哈达玛矩阵
H = hadamard(n) 返回阶次为n的哈达玛矩阵.
n — 矩阵的阶次,非负整数标量
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def hadamard_matrix(input_str):
"""
构造Hadamard矩阵,对标MATLAB的hadamard函数
参数:
input_str (str): 输入字符串,应为正整数n(需满足n是2的幂)
返回:
Sympy矩阵或错误信息
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def _recursive_hadamard(n):
"""递归构造2的幂次阶Hadamard矩阵"""
if n == 1:
return sp.Matrix([[1]])
H_prev = _recursive_hadamard(n // 2)
# 矩阵拼接:行拼接和列拼接
top = H_prev.row_join(H_prev)
bottom = H_prev.row_join(-H_prev)
return top.col_join(bottom)
# 验证输入合法性
if expr.is_Integer and expr > 0:
n = int(expr)
# 检查是否为2的幂
if (n & (n - 1)) == 0 or n == 1:
result = _recursive_hadamard(n)
else:
error = True
else:
error = True
if error:
return f"输入错误: {input_str}\n提示: n必须是2的幂的正整数"
return result
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:有效输入 n=4
input1 = '4'
mat1 = hadamard_matrix(input1)
print("示例1结果(n=4):\n", mat1)
# Matrix([[1, 1, 1, 1],
# [1, -1, 1, -1],
# [1, 1, -1, -1],
# [1, -1, -1, 1]])
# 示例2:边界输入 n=1
input2 = '1'
mat2 = hadamard_matrix(input2)
print("示例2结果(n=1):\n", mat2)
# Matrix([[1]])
半波正弦波信号
HalfRectSineWave(A)
A - 数组,或符号表达式
import matplotlib.pyplot as plt
import numpy as np
示例1:模拟电源整流
50Hz交流电整流(市电频率)
t_power, y_power = HalfRectSineWave(t, Fs=1e3, f=50, num_cycles=3)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(t_power * 1000, y_power) # 转换为毫秒
plt.title("50Hz半波整流电源输出")
plt.xlabel("时间 (毫秒)")
plt.ylabel("电压 (V)")
plt.grid(True)
添加电容滤波效果(简单模拟)
t_filtered, y_raw = HalfRectSineWave(t, Fs=10e3, f=50, num_cycles=2)
# 简单RC滤波模拟
alpha = 0.05 # 滤波系数
y_filtered = np.zeros_like(y_raw)
y_filtered[0] = y_raw[0]
for i in range(1, len(y_raw)):
y_filtered[i] = alpha * y_raw[i] + (1 - alpha) * y_filtered[i - 1]
plt.subplot(1, 2, 2)
plt.plot(t_filtered * 1000, y_raw, 'b-', alpha=0.5, label='整流后')
plt.plot(t_filtered * 1000, y_filtered, 'r-', linewidth=2, label='滤波后')
plt.title("整流信号与滤波效果")
plt.xlabel("时间 (毫秒)")
plt.ylabel("电压 (V)")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
示例2. 音频信号处理
模拟音频信号包络检测
t_audio, y_audio = HalfRectSineWave(t, Fs=44.1e3, f=1000, num_cycles=10)
添加高频载波和低频调制
carrier_freq = 10e3 # 10kHz载波
modulation_freq = 500 # 500Hz调制
AM调制信号
am_signal = (1 + 0.5 * np.sin(2 * np.pi * modulation_freq * t_audio)) * \
np.sin(2 * np.pi * carrier_freq * t_audio) * 100
包络检测(半波整流)
t_env, env_detected = HalfRectSineWave(list(am_signal), Fs=44.1e3, f=carrier_freq)
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(t_audio[:2000] * 1000, am_signal[:2000])
plt.title("AM调制信号")
plt.xlabel("时间 (毫秒)")
plt.ylabel("幅度")
plt.grid(True)
plt.subplot(2, 1, 2)
plt.plot(t_env[:2000] * 1000, env_detected[:2000])
plt.title("包络检测输出")
plt.xlabel("时间 (毫秒)")
plt.ylabel("幅度")
plt.grid(True)
plt.tight_layout()
plt.show()
示例3. 机械振动分析
使用时间变换来模拟非线性响应
t_vib, y_vib = HalfRectSineWave(t * (1 + 0.1*t), Fs=5e3, f=100, num_cycles=8)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(t_vib * 1000, y_vib)
plt.title("机械振动冲击响应")
plt.xlabel("时间 (毫秒)")
plt.ylabel("加速度 (m/s²)")
plt.grid(True)
分析不同频率的振动
frequencies = [50, 100, 200]
plt.subplot(1, 2, 2)
for freq in frequencies:
t_temp, y_temp = HalfRectSineWave(t, Fs=5e3, f=freq, num_cycles=4)
plt.plot(t_temp * 1000, y_temp, label=f'{freq}Hz')
plt.title("不同频率振动响应")
plt.xlabel("时间 (毫秒)")
plt.ylabel("加速度 (m/s²)")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
示例4. 生物医学信号模拟
使用自定义时间点模拟不规则心跳
irregular_beats = [0, 0.8, 1.9, 3.0, 4.2, 5.1] # 不规则心跳时间点(秒)
生成心电信号中的R波(半波整流正弦波模拟)
t_ecg = np.linspace(0, 6, 6000) # 6秒信号
ecg_signal = np.zeros_like(t_ecg)
for beat_time in irregular_beats:
# 在每个心跳时间生成R波
beat_duration = 0.1 # R波持续时间
beat_samples = int(beat_duration * 1000) # 采样点数
t_beat = np.linspace(0, beat_duration, beat_samples)
# 生成R波(使用半波整流正弦波形状)
_, r_wave = HalfRectSineWave(list(t_beat), f=15, Fs=1000)
# 将R波插入到ECG信号中
start_idx = int(beat_time * 1000)
end_idx = start_idx + len(r_wave)
if end_idx < len(ecg_signal):
ecg_signal[start_idx:end_idx] += r_wave
plt.figure(figsize=(12, 4))
plt.plot(t_ecg, ecg_signal)
plt.title("模拟心电图信号(R波检测)")
plt.xlabel("时间 (秒)")
plt.ylabel("幅度")
plt.grid(True)
标记R波位置
for beat_time in irregular_beats:
plt.axvline(x=beat_time, color='red', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
示例5. 通信系统同步信号
生成时钟同步信号
t_sync, y_sync = HalfRectSineWave(t, Fs=100e3, f=10e3, num_cycles=20)
添加相位调制来模拟时钟抖动
t_jitter, y_jitter = HalfRectSineWave(t + 0.00002*sin(2*pi*1000*t),
Fs=100e3, f=10e3, num_cycles=20)
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(t_sync * 1e6, y_sync) # 转换为微秒
plt.title("理想时钟同步信号 (10kHz)")
plt.xlabel("时间 (微秒)")
plt.ylabel("幅度")
plt.grid(True)
plt.subplot(2, 1, 2)
plt.plot(t_jitter * 1e6, y_jitter)
plt.title("带时钟抖动的同步信号")
plt.xlabel("时间 (微秒)")
plt.ylabel("幅度")
plt.grid(True)
plt.tight_layout()
计算时钟误差
ideal_peaks = np.where(y_sync > 95)[0]
jitter_peaks = np.where(y_jitter > 95)[0]
if len(ideal_peaks) == len(jitter_peaks):
timing_errors = (jitter_peaks - ideal_peaks) / 100e3 * 1e6 # 转换为微秒
print(f"最大时钟抖动: {np.max(np.abs(timing_errors)):.2f} 微秒")
print(f"平均时钟抖动: {np.mean(np.abs(timing_errors)):.2f} 微秒")
plt.show()
示例6. 功率电子器件分析
分析不同导通角的整流效果
conduction_angles = [30, 60, 90, 120] # 度
plt.figure(figsize=(12, 8))
for i, angle_deg in enumerate(conduction_angles):
angle_rad = np.radians(angle_deg)
phase_shift = angle_rad / (2 * np.pi * 1000) # 转换为时间偏移
# 使用相位偏移模拟可控硅的导通角控制
t_scr, y_scr = HalfRectSineWave(t + phase_shift,
Fs=20e3, f=1000, num_cycles=3)
plt.subplot(2, 2, i + 1)
plt.plot(t_scr * 1000, y_scr)
plt.title(f"导通角 {angle_deg}° 的整流输出")
plt.xlabel("时间 (毫秒)")
plt.ylabel("输出电压")
plt.grid(True)
# 计算平均输出电压
avg_voltage = np.mean(y_scr)
plt.text(0.5, 80, f'平均电压: {avg_voltage:.1f}V',
bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.8))
plt.tight_layout()
plt.show()
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import ast
def half_rect_sine_wave(input_str, Fs=20e3, f=1e3, num_cycles=6):
"""
生成半波整流正弦波。
参数:
input_str (str): 输入表达式或时间列表字符串。
- 若为列表字符串 (如 "[0, 1e-3, 2e-3]"), 表示自定义时间点(秒)。
- 若为SymPy表达式 (如 "t", "t*0.5"), 表示时间变换公式。
Fs (float): 采样率 (Hz),默认20kHz。
f (float): 信号频率 (Hz),默认1kHz。
num_cycles (int): 生成信号的周期数(仅当输入为表达式时有效),默认6个周期。
返回:
tuple: (时间数组, 半波整流后的信号数组) 或错误信息字符串。
"""
try:
# 解析输入字符串
try:
# 尝试解析为Python列表
expr = ast.literal_eval(input_str)
if not isinstance(expr, list):
# 不是列表则尝试SymPy解析
expr = sp.sympify(input_str)
except (ValueError, SyntaxError, TypeError):
# 解析失败则作为SymPy表达式处理
expr = sp.sympify(input_str)
# 处理列表输入(自定义时间点)
if isinstance(expr, list):
time_values = np.array(expr, dtype=float)
# 生成正弦波:y = 100*sin(2πf*t)
y = 100 * np.sin(2 * np.pi * f * time_values)
y_rectified = np.maximum(y, 0)
return time_values, y_rectified
# 处理SymPy表达式
elif isinstance(expr, sp.Expr):
# 计算总样本数
samples_per_cycle = int(Fs / f)
total_samples = num_cycles * samples_per_cycle
# 生成时间数组(秒)
time_base = np.arange(total_samples) / Fs
# 将表达式转换为函数
variables = expr.free_symbols
if variables:
func = sp.lambdify(variables, expr, modules='numpy')
# 代入时间计算处理后的时间值
t_processed = func(time_base)
else:
# 无变量则视为常数表达式
t_processed = np.full_like(time_base, float(expr))
# 生成正弦波并整流
y = 100 * np.sin(2 * np.pi * f * t_processed)
y_rectified = np.maximum(y, 0)
return time_base, y_rectified
else:
raise ValueError("输入类型不支持,请输入列表或SymPy表达式。")
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
import matplotlib.pyplot as plt
# 示例1:默认参数生成6个周期的波形
t1, y1 = half_rect_sine_wave("t")
plt.figure()
plt.plot(t1, y1)
plt.title("默认参数半波整流正弦波")
plt.xlabel("时间 (秒)")
plt.ylabel("幅度")
# 示例2:自定义时间点
custom_time = [0, 0.0005, 0.001, 0.0015] # 0, 0.5ms, 1ms, 1.5ms
t2, y2 = half_rect_sine_wave(str(custom_time))
plt.figure()
plt.stem(t2, y2, use_line_collection=True)
plt.title("自定义时间点半波整流")
plt.xlabel("时间 (秒)")
plt.ylabel("幅度")
# 示例3:带相位偏移的波形
t3, y3 = half_rect_sine_wave("t + 0.00025", num_cycles=3) # 0.25ms相位偏移
plt.figure()
plt.plot(t3, y3)
plt.title("带相位偏移的半波整流")
plt.xlabel("时间 (秒)")
plt.ylabel("幅度")
plt.show()
汉明窗
w = hamming(L,sym=1) 返回一个长度为L个点的修正的汉明窗 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
示例1. 数字滤波器设计
"""设计一个低通FIR滤波器"""
使用Hamming窗设计51阶低通FIR滤波器
N = 51
cutoff_freq = 0.3 # 归一化截止频率
生成理想低通滤波器的冲激响应
h_ideal = []
for n in range(N):
if n == (N - 1) // 2:
h_ideal.append(2 * cutoff_freq)
else:
theta = 2 * np.pi * cutoff_freq * (n - (N - 1) / 2)
h_ideal.append(np.sin(theta) / (np.pi * (n - (N - 1) / 2)))
应用Hamming窗
window = hamming(N)
h_fir = [h * w for h, w in zip(h_ideal, window)]
print(f"低通FIR滤波器系数 (前10个): {h_fir[:10]}")
#低通FIR滤波器系数 (前10个): [5.489886917185572e-18, 0.0010548554750528494, -0.0007683356183186414,
-0.0009550734669726426, 0.0019735003278461144, -3.925899901137517e-18,
-0.003261117480891942, 0.0025651632210178265, 0.0032304059987978613, -0.006511387630530373]
示例2. 频谱分析 - 语音信号处理
"""语音信号的频谱分析"""
模拟语音信号片段
fs = 8000 # 采样率8kHz
t = np.linspace(0, 0.1, 800) # 100ms信号
生成包含基频和泛音的语音-like信号
f0 = 200 # 基频200Hz
signal_data = (np.sin(2 * np.pi * f0 * t) +
0.5 * np.sin(2 * np.pi * 2 * f0 * t) +
0.3 * np.sin(2 * np.pi * 3 * f0 * t) +
0.1 * np.random.normal(0, 0.1, len(t)))
应用Hamming窗进行频谱分析
N = 256
window = hamming(N)
signal_windowed = signal_data[:N] * window
计算FFT
spectrum = np.fft.fft(signal_windowed)
freq = np.fft.fftfreq(N, 1 / fs)
print(f"频谱峰值频率: {freq[np.argmax(np.abs(spectrum[:N // 2]))]:.1f} Hz")
#频谱峰值频率: 187.5 Hz
示例3. 雷达信号处理
"""雷达脉冲压缩(匹配滤波)"""
生成线性调频信号(LFM)
T = 10e-6 # 脉冲宽度10微秒
B = 10e6 # 带宽10MHz
fs = 50e6 # 采样率50MHz
t = np.linspace(-T / 2, T / 2, int(T * fs))
chirp_signal = np.exp(1j * np.pi * (B / T) * t ** 2) # 复数LFM信号
应用Hamming窗减少距离旁瓣
N = len(chirp_signal)
window = hamming(N)
weighted_chirp = chirp_signal * window
匹配滤波器(时域反转共轭)
matched_filter = np.conj(weighted_chirp[::-1])
print(f"加窗后脉冲长度: {len(weighted_chirp)} 点")
print(f"主瓣宽度改善: 使用Hamming窗可降低距离旁瓣约-43dB")
#加窗后脉冲长度: 500 点
#主瓣宽度改善: 使用Hamming窗可降低距离旁瓣约-43dB
示例4. 图像处理 - 频域滤波
"""在频域中使用Hamming窗进行图像滤波"""
创建测试图像(包含不同频率成分)
M, N = 64, 64
x, y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, M))
生成包含高低频的图像
test_image = (np.sin(10 * np.pi * x) + # 高频成分
np.cos(4 * np.pi * y) + # 中频成分
0.5 * np.ones_like(x)) # 直流分量
创建2D Hamming窗
window_1d = hamming(M)
window_2d = np.outer(window_1d, window_1d)
应用窗函数后进行FFT
image_windowed = test_image * window_2d
image_fft = np.fft.fft2(image_windowed)
print(f"加窗前图像能量: {np.sum(test_image ** 2):.3f}")
print(f"加窗后图像能量: {np.sum(image_windowed ** 2):.3f}")
#加窗前图像能量: 5184.000
#加窗后图像能量: 784.075
#Hamming窗有效减少了频谱泄漏
示例5. 通信系统 - OFDM子载波整形
"""OFDM系统中子载波的频谱整形"""
OFDM参数
N_subcarriers = 64 # 子载波数量
CP_length = 16 # 循环前缀长度
symbol_length = N_subcarriers + CP_length
生成随机QAM符号
qam_symbols = np.random.randint(0, 4, N_subcarriers) # 4-QAM
qam_constellation = [1 + 1j, 1 - 1j, -1 + 1j, -1 - 1j]
mapped_symbols = [qam_constellation[s] for s in qam_symbols]
IFFT生成时域信号
ifft_output = np.fft.ifft(mapped_symbols, N_subcarriers)
应用Hamming窗进行时域加窗
window = hamming(symbol_length, 0) # 周期窗
windowed_symbol = np.concatenate([ifft_output[-CP_length:], ifft_output]) * window
print(f"OFDM符号长度: {len(windowed_symbol)}")
#OFDM符号长度: 80
#加窗后PAPR(峰均比)降低,频谱带外衰减更好
示例6. 生物医学信号处理
"""心电信号(ECG)的频谱特征提取"""
模拟ECG信号片段
fs = 360 # 采样率360Hz
t = np.linspace(0, 2, 720) # 2秒信号
模拟ECG特征:P波、QRS复合波、T波
ecg_signal = (0.5 * np.exp(-((t - 0.2) / 0.03) ** 2) + # P波
2.0 * np.exp(-((t - 0.3) / 0.02) ** 2) - # QRS波
0.8 * np.exp(-((t - 0.5) / 0.06) ** 2)) # T波
添加噪声
noise = 0.1 * np.random.normal(0, 1, len(t))
noisy_ecg = ecg_signal + noise
使用Hamming窗进行频谱分析
segment_length = 256
window = hamming(segment_length)
对信号分段加窗分析
segments = []
for i in range(0, len(noisy_ecg) - segment_length, segment_length // 2):
segment = noisy_ecg[i:i + segment_length] * window
segments.append(segment)
print(f"ECG信号分段数: {len(segments)}")
#ECG信号分段数: 4
示例7. 声学测量 - 房间脉冲响应
"""房间声学特性的测量分析"""
模拟房间脉冲响应
N = 512
t = np.linspace(0, 0.1, N) # 100ms响应
模拟包含直达声和早期反射的脉冲响应
impulse_response = np.zeros(N)
impulse_response[10] = 1.0 # 直达声
impulse_response[45] = 0.6 # 第一次反射
impulse_response[78] = 0.4 # 第二次反射
impulse_response[120] = 0.3 # 第三次反射
添加混响尾音(指数衰减)
for i in range(150, N):
impulse_response[i] = 0.8 * np.exp(-0.05 * (i - 150))
应用Hamming窗提取早期反射
window = hamming(200) # 关注前200个采样点
window_full = np.concatenate([window, np.zeros(N - 200)])
windowed_response = impulse_response * window_full
计算混响时间(RT60)等参数
energy = np.cumsum(windowed_response[::-1] ** 2)[::-1]
#Hamming窗减少了频谱泄漏,提高心率检测准确性
#使用Hamming窗分离早期反射和混响尾音
#便于分析房间的早期衰减特性
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import scipy.signal as signal
def hamming_window(input_str):
"""
生成Hamming窗,对标MATLAB的hamming函数。
参数:
input_str (str): 输入字符串,支持以下格式:
- 单个数字(如"64")生成对称窗('symmetric')。
- 元组(如"(64, 0)"),第二个元素为0生成周期窗('periodic'),非零生成对称窗。
返回:
list or str: Hamming窗列表,或错误信息。
"""
try:
expr = sp.sympify(input_str)
result = None
# 处理元组输入(例如 "(m, flag)")
if isinstance(expr, tuple) and len(expr) == 2:
m, flag = expr
if m.is_number and flag.is_number:
m_int = int(m)
# flag=0 对应周期窗(sym=False),否则对称窗(sym=True)
sym = bool(int(flag) != 0)
window = signal.windows.hamming(m_int, sym)
result = list(window)
else:
return f"输入错误: 参数必须为数字 {input_str}"
# 处理单个数字输入(例如 "m")
elif expr.is_number:
m_int = int(expr)
window = signal.windows.hamming(m_int, sym=True) # 默认对称窗
result = list(window)
else:
return f"输入格式错误: {input_str}"
return result
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 生成对称窗(64点,MATLAB默认)
print("对称窗(64点):", hamming_window("64")[:5])
# [0.08000000000000007, 0.08228584333191541, 0.08912065558966992, 0.10043650933837528, 0.11612094253961253]
# 生成周期窗(64点,第二个参数为0)
print("周期窗(64点):", hamming_window("64, 0")[:5])
# [0.08000000000000007, 0.08221502573078954, 0.0888387710145141, 0.099807445563184, 0.11501541504480817]
汉宁窗
w = hann(L,sym=1) 返回一个长度为L个点的修正的汉明窗 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
示例1. 音频信号处理 - 音乐频谱分析
模拟音乐信号(包含和弦)
fs = 44100 # CD音质采样率
duration = 0.1 # 100ms分析窗口
t = np.linspace(0, duration, int(fs * duration))
C大调和弦:C(261.63Hz), E(329.63Hz), G(392.00Hz)
chord_signal = (0.6 * np.sin(2 * np.pi * 261.63 * t) +
0.4 * np.sin(2 * np.pi * 329.63 * t) +
0.3 * np.sin(2 * np.pi * 392.00 * t) +
0.1 * np.random.normal(0, 0.05, len(t)))
应用Hann窗进行频谱分析
N = len(t)
hann_win = hann(N)
windowed_signal = chord_signal * hann_win
FFT分析
spectrum = np.fft.fft(windowed_signal)
freqs = np.fft.fftfreq(N, 1 / fs)
查找峰值频率
magnitude = 20 * np.log10(np.abs(spectrum[:N // 2]) + 1e-10)
peak_freqs = []
for i in range(1, len(magnitude) - 1):
if magnitude[i] > magnitude[i - 1] and magnitude[i] > magnitude[i + 1]:
if magnitude[i] > -40: # 高于-40dB的峰值
peak_freqs.append(freqs[i])
检测到的和弦频率成分:
for freq in peak_freqs[:6]: # 显示前6个峰值
print(f" {freq:.1f} Hz")
#50.0 Hz
#120.0 Hz
#140.0 Hz
#160.0 Hz
#190.0 Hz
#260.0 Hz
示例2. 结构健康监测 - 振动模态分析
模拟桥梁振动信号
fs = 1000 # 采样率1kHz
t = np.linspace(0, 10, 10000) # 10秒数据
结构固有频率:1.5Hz, 4.2Hz, 8.7Hz (典型桥梁频率)
vibration = (2.0 * np.sin(2 * np.pi * 1.5 * t) * np.exp(-0.01 * t) + # 一阶模态,衰减
1.2 * np.sin(2 * np.pi * 4.2 * t) * np.exp(-0.02 * t) + # 二阶模态
0.8 * np.sin(2 * np.pi * 8.7 * t) * np.exp(-0.03 * t) + # 三阶模态
0.3 * np.random.normal(0, 0.2, len(t))) # 环境噪声
分段Hann窗分析(短时傅里叶变换)
segment_length = 2048
overlap = 1024
hann_win = hann(segment_length)
spectrogram = []
time_points = []
for i in range(0, len(vibration) - segment_length, segment_length - overlap):
segment = vibration[i:i + segment_length] * hann_win
seg_fft = np.fft.fft(segment)
spectrogram.append(20 * np.log10(np.abs(seg_fft[:segment_length // 2]) + 1e-10))
time_points.append(t[i])
结构振动模态分析完成:
print(f"使用{segment_length}点Hann窗,重叠{overlap}点")
print("Hann窗提供优良的频率分辨率和较低的频谱泄漏")
#使用2048点Hann窗,重叠1024点
#Hann窗提供优良的频率分辨率和较低的频谱泄漏
示例3. 雷达信号处理 - 多目标分辨
雷达参数
fs = 100e6 # 100MHz采样率
T = 20e-6 # 20微秒脉冲宽度
t = np.linspace(0, T, int(fs * T))
模拟三个不同距离的目标回波
target_delays = [5e-6, 8e-6, 8.5e-6] # 微秒延迟
target_amplitudes = [1.0, 0.8, 0.6] # 目标强度
radar_echo = np.zeros(len(t))
for delay, amp in zip(target_delays, target_amplitudes):
idx = int(delay * fs)
if idx < len(t):
radar_echo[idx] = amp
添加噪声和展宽效应
radar_echo = np.convolve(radar_echo, np.exp(-(t - 1e-6) ** 2 / (2e-6) ** 2), 'same')
radar_echo += 0.1 * np.random.normal(0, 0.05, len(t))
应用Hann窗提高距离分辨力
hann_win = hann(len(t))
windowed_echo = radar_echo * hann_win
距离谱分析
range_spectrum = np.fft.fft(windowed_echo)
range_bins = np.fft.fftfreq(len(t), 1 / fs) * 3e8 / 2 # 转换为距离
目标距离检测结果:
peaks, _ = signal.find_peaks(np.abs(range_spectrum[:len(t) // 2]), height=0.1)
for peak in peaks[:3]:
distance = range_bins[peak]
if distance > 0:
print(f" 目标距离: {distance:.1f} 米")
# 目标距离: 75000000000000.0 米
# 目标距离: 97500000000000.0 米
# 目标距离: 120000000000000.0 米
示例4. 医学影像 - 超声成像
模拟超声回波信号(A模式)
fs = 50e6 # 50MHz超声采样率
depth = 0.15 # 15cm探测深度
t = np.linspace(0, depth * 2 / 1540, int(fs * depth * 2 / 1540)) # 声速1540m/s
模拟不同组织的反射界面
ultrasound_signal = np.zeros(len(t))
# 组织界面位置(米)
interfaces = [0.02, 0.05, 0.08, 0.12]
for interface in interfaces:
idx = int(interface * 2 / 1540 * fs)
if idx < len(t):
ultrasound_signal[idx] = 0.8 * np.exp(-interface * 10) # 深度衰减
添加超声系统的冲激响应
impulse_response = np.exp(-(np.arange(-10, 11) * 1e-7) ** 2 / (2e-7) ** 2)
ultrasound_signal = np.convolve(ultrasound_signal, impulse_response, 'same')
加噪声
ultrasound_signal += 0.1 * np.random.normal(0, 0.05, len(t))
应用Hann窗进行包络检测
hann_win = hann(len(t))
windowed_signal = ultrasound_signal * hann_win
Hilbert变换提取包络
analytic_signal = signal.hilbert(windowed_signal)
envelope = np.abs(analytic_signal)
超声成像处理完成:
print("Hann窗有效抑制旁瓣,提高纵向分辨力")
print(f"检测到 {len(interfaces)} 个组织界面")
#Hann窗有效抑制旁瓣,提高纵向分辨力
#检测到 4 个组织界面
示例5. 通信系统 - 5G NR波形生成
5G NR参数
scs = 30e3 # 30kHz子载波间隔
fft_size = 4096
num_symbols = 14 # 一个时隙的OFDM符号数
生成5G NR上行参考信号
reference_signal = np.random.randn(fft_size) + 1j * np.random.randn(fft_size)
reference_signal = reference_signal / np.sqrt(2) # 功率归一化
时域OFDM符号生成
ofdm_symbols = []
for i in range(num_symbols):
# IFFT
time_domain = np.fft.ifft(reference_signal, fft_size)
# 应用Hann窗进行频谱整形(降低带外辐射)
hann_win = hann(len(time_domain), 1) # 对称窗
windowed_symbol = time_domain * hann_win
ofdm_symbols.append(windowed_symbol)
计算功率谱密度
full_signal = np.concatenate(ofdm_symbols)
f, psd = signal.welch(full_signal, fs=fft_size * scs, window='hann',
nperseg=1024, return_onesided=False)
5G NR波形生成完成:
print(f"使用{fft_size}点FFT,{scs / 1000}kHz子载波间隔")
print("Hann窗有效降低带外辐射,满足3GPP频谱模板要求")
#使用4096点FFT,30.0kHz子载波间隔
#Hann窗有效降低带外辐射,满足3GPP频谱模板要求
示例6. 地球物理勘探 - 地震信号处理
模拟地震检波器信号
fs = 500 # 500Hz采样率
duration = 2.0 # 2秒记录
t = np.linspace(0, duration, int(fs * duration))
模拟地震事件:P波、S波、面波
seismic_signal = np.zeros(len(t))
P波(纵波,速度快)
p_wave_time = 0.8
p_wave_idx = int(p_wave_time * fs)
if p_wave_idx < len(t):
seismic_signal[p_wave_idx:p_wave_idx + 100] += 1.0 * np.exp(-(np.arange(100) - 50) ** 2 / 100)
S波(横波,速度慢)
s_wave_time = 1.2
s_wave_idx = int(s_wave_time * fs)
if s_wave_idx < len(t):
seismic_signal[s_wave_idx:s_wave_idx + 150] += 0.7 * np.exp(-(np.arange(150) - 75) ** 2 / 200)
面波(低频,幅度大)
surface_wave_time = 1.5
surface_idx = int(surface_wave_time * fs)
if surface_idx < len(t):
surface_wave = 2.0 * np.sin(2 * np.pi * 2 * (t[surface_idx:] - surface_wave_time)) * \
np.exp(-5 * (t[surface_idx:] - surface_wave_time))
seismic_signal[surface_idx:surface_idx + len(surface_wave)] += surface_wave
添加环境噪声
seismic_signal += 0.3 * np.random.normal(0, 0.1, len(t))
使用Hann窗进行时频分析
window_length = 256
hann_win = hann(window_length)
计算频谱图
f, t_spec, Sxx = signal.spectrogram(seismic_signal, fs, window=hann_win,
nperseg=window_length, noverlap=window_length // 2)
地震信号分析完成:
print("检测到地震波序列: P波 → S波 → 面波")
print("Hann窗提供良好的时频局部化特性")
#检测到地震波序列: P波 → S波 → 面波
#Hann窗提供良好的时频局部化特性
示例7. 电力系统 - 谐波分析
模拟电网电压信号(50Hz基波 + 谐波)
fs = 3200 # 3.2kHz采样率
t = np.linspace(0, 0.2, 640) # 10个周期(200ms)
理想50Hz正弦波 + 谐波污染
fundamental = 230 * np.sqrt(2) * np.sin(2 * np.pi * 50 * t) # 230V RMS
谐波成分:3次(2%), 5次(5%), 7次(1%), 11次(0.5%)
harmonics = (0.02 * 230 * np.sqrt(2) * np.sin(2 * np.pi * 150 * t) + # 3次谐波
0.05 * 230 * np.sqrt(2) * np.sin(2 * np.pi * 250 * t) + # 5次谐波
0.01 * 230 * np.sqrt(2) * np.sin(2 * np.pi * 350 * t) + # 7次谐波
0.005 * 230 * np.sqrt(2) * np.sin(2 * np.pi * 550 * t)) # 11次谐波
voltage_signal = fundamental + harmonics + 5 * np.random.normal(0, 1, len(t))
应用Hann窗进行精确的谐波分析
N = len(voltage_signal)
hann_win = hann(N)
windowed_voltage = voltage_signal * hann_win
FFT分析
spectrum = np.fft.fft(windowed_voltage)
freqs = np.fft.fftfreq(N, 1 / fs)
计算各次谐波的THD(总谐波失真)
fundamental_power = 0
harmonic_power = 0
for i, freq in enumerate(freqs[:N // 2]):
if 45 <= abs(freq) <= 55: # 基波
fundamental_power += np.abs(spectrum[i]) ** 2
elif abs(freq) > 55: # 谐波
harmonic_power += np.abs(spectrum[i]) ** 2
thd = np.sqrt(harmonic_power / fundamental_power) * 100
print("电能质量分析结果:")
print(f" 基波频率: 50 Hz")
print(f" 总谐波失真(THD): {thd:.2f}%")
print(f" Hann窗有效抑制频谱泄漏,提高谐波测量精度")
#电能质量分析结果:
#基波频率: 50 Hz
#总谐波失真(THD): 5.94%
#Hann窗有效抑制频谱泄漏,提高谐波测量精度
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import scipy.signal as signal
def hann_window(input_str):
"""
生成Hann窗(汉宁窗),对标MATLAB的hann函数。
参数:
input_str (str): 输入字符串,支持以下格式:
- 单个数字(如"64")生成对称窗('symmetric')。
- 元组(如"(64, 0)"),第二个元素为0生成周期窗('periodic'),非0生成对称窗。
返回:
list or str: Hann窗列表,或错误信息。
"""
try:
expr = sp.sympify(input_str)
result = None
# 处理元组输入(例如 "(m, flag)")
if isinstance(expr, tuple) and len(expr) == 2:
m, flag = expr
if m.is_number and flag.is_number:
m_int = int(m)
# flag=0 对应周期窗(sym=False),否则对称窗(sym=True)
sym = bool(int(flag) != 0)
window = signal.windows.hann(m_int, sym)
result = list(window)
else:
return f"输入错误: 参数必须为数字 {input_str}"
# 处理单个数字输入(例如 "m")
elif expr.is_number:
m_int = int(expr)
window = signal.windows.hann(m_int, sym=True) # 默认对称窗
result = list(window)
else:
return f"输入格式错误: {input_str}"
return result
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 生成对称窗(64点,MATLAB默认)
print("对称窗(64点):", hann_window("64")[:5])
# [0.0, 0.002484612317299295, 0.009913756075728086, 0.022213597106929606, 0.03926189406479613]
# 生成周期窗(64点,第二个参数为0)
print("周期窗(64点):", hann_window("(64, 0)")[:5])
# [0.0, 0.002407636663901591, 0.009607359798384785, 0.021529832133895588, 0.03806023374435663]
其特征值位于复平面中的垂直线上的矩阵
H = hanowa(n,alpha) 返回 2×2 分块矩阵, 其中包含四个 n/2×n/2 分块,形式如下.
[alpha*eye(n/2), -diag(1:n/2)
diag(1:n/2), alpha*eye(n/2)]
参量 n 必须为偶数整数. alpha 的默认值为 -1. A 具有复数特征值,形式为 alpha ± k*i (1 <= k <= n/2).
n, alpha — 输入,标量
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def hanowa_matrix(input_str):
"""
构造Hanowa矩阵,对标MATLAB的hanowa函数
参数:
input_str (str): 输入字符串,格式为:
- 单个偶数n: 生成n×n矩阵,默认d=-1
- 元组(n, d): n为偶数,d为标量参数
返回:
Sympy矩阵或错误信息
Hanowa矩阵结构:
[[d*I, -D],
[ D, d*I]]
其中D = diag(1,2,...,m), m = n/2, I为m×m单位矩阵
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def build_hanowa(n, d=-1):
"""核心构造函数"""
# 验证n是否为偶数
if n % 2 != 0 or n <= 0:
raise ValueError("n必须是正偶数")
m = n // 2
I = sp.eye(m) # 单位矩阵
D = sp.diag(*range(1, m + 1)) # 对角矩阵1~m
# 分块矩阵构造
top_row = sp.Matrix.hstack(d * I, -D)
bottom_row = sp.Matrix.hstack(D, d * I)
return sp.Matrix.vstack(top_row, bottom_row)
# 输入解析逻辑
if isinstance(expr, tuple) and len(expr) == 2:
# 处理(n, d)元组输入
if expr[0].is_Integer and expr[1].is_number:
n = int(expr[0])
d = float(expr[1]) if expr[1].is_Float else int(expr[1])
result = build_hanowa(n, d)
else:
error = True
elif expr.is_Integer:
# 处理单个整数输入
n = int(expr)
result = build_hanowa(n)
else:
error = True
if error:
return f"输入错误: {input_str}\n格式应为'(n, d)'或'n',其中n为正偶数"
return result
except ValueError as ve:
return f"参数错误: {ve}"
except Exception as e:
return f"运行时错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:有效输入 (4, -1)
input1 = '(4, -1)'
mat1 = hanowa_matrix(input1)
print("示例1结果(n=4, d=-1):\n", mat1)
# Matrix([[-1, 0, -1, 0],
# [0, -1, 0, -2],
# [1, 0, -1, 0],
# [0, 2, 0, -1]])
# 示例2:默认d值测试
input2 = '6'
mat2 = hanowa_matrix(input2)
print("示例2结果(n=6, d=-1):\n", mat2[:, :2]) # 显示前两列
# Matrix([[-1, 0],
# [0, -1],
# [0, 0],
# [1, 0],
# [0, 2],
# [0, 0]])
# 示例3:自定义d值
input3 = '(2, 5)'
mat3 = hanowa_matrix(input3)
print("示例3结果(n=2, d=5):\n", mat3)
# Matrix([[5, -1],
# [1, 5]])
汉克尔矩阵
H = hankel(c) 返回正方形汉克尔矩阵,其中c定义矩阵的第一列,主反对角线以下的元素为零.
H = hankel(c,r) 返回汉克尔矩阵,第一列为c,最后一行为r.如果c的最后一个元素不同于r的第一个元素,则hankel会发出警告,并对反对角线使用c的最后一个元素
c — 汉克尔矩阵的第一列,标量,向量
r — 汉克尔矩阵的最后一行,标量,向量
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def hankel_matrix(input_str):
"""
构造Hankel矩阵,对标MATLAB的hankel函数。
参数:
input_str (str): 输入字符串,格式为:
- 两个列表的元组:'([c1, c2, ...], [r1, r2, ...])',生成由列向量c和行向量r定义的Hankel矩阵。
- 单个列表:'[a1, a2, ..., an]',生成n×n的Hankel矩阵,右上三角填充0。
返回:
Sympy矩阵或错误信息。
"""
try:
expr = sp.sympify(input_str)
H = None
error = False
# 处理两个参数的情况:列向量c和行向量r
if isinstance(expr, tuple) and len(expr) == 2 and \
isinstance(expr[0], list) and isinstance(expr[1], list):
c, r = expr[0], expr[1]
rows, cols = len(c), len(r)
H = sp.Matrix.zeros(rows, cols)
for i in range(rows):
for j in range(cols):
if i + j < rows:
H[i, j] = c[i + j] # 填充c的元素
else:
idx = i + j - rows # 计算r的索引
H[i, j] = r[idx] if idx < len(r) else 0 # 超出部分填充0
# 处理单个参数的情况,生成方阵
elif isinstance(expr, list):
c = expr
n = len(c)
H = sp.Matrix.zeros(n, n)
for i in range(n):
for j in range(n):
H[i, j] = c[i + j] if i + j < n else 0 # 右上三角填充0
else:
error = True
return H if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:两个参数生成Hankel矩阵
input1 = '([1, 2, 3], [3, 4, 5])'
result1 = hankel_matrix(input1)
print("示例1结果(两参数):\n", result1)
# Matrix([[1, 2, 3],
# [2, 3, 3],
# [3, 3, 4]])
# 示例2:单个参数生成方阵
input2 = '[1, 2, 3]'
result2 = hankel_matrix(input2)
print("示例2结果(单参数):\n", result2)
# Matrix([[1, 2, 3],
# [2, 3, 0],
# [3, 0, 0]])
# 示例3:r长度不足时填充0
input3 = '([1, 2, 3], [4, 5])'
result3 = hankel_matrix(input3)
print("示例3结果(r长度不足):\n", result3)
# Matrix([[1, 2],
# [2, 3],
# [3, 4]])
第一类汉克尔函数
HankelHone(n,z)在复数z平面上有一个从@inf到0的分支切割不连续点.
n -- 输入, 数值,符号变量,向量,矩阵,多维数组
z -- 输入, 数值,符号变量,向量,矩阵,多维数组
示例1. 电磁波传播 - 圆柱形天线的辐射场
天线参数
frequency = 2.4e9 # 2.4GHz (WiFi频段)
wavelength = 3e8 / frequency
k = 2 * np.pi / wavelength # 波数
观察点位置(极坐标)
rho = np.linspace(0.1, 5, 100) * wavelength # 径向距离
phi = np.pi / 4 # 方位角
计算不同阶数的汉克尔函数(表示不同模态)
orders = [0, 1, 2] # 0阶、1阶、2阶模态
H_fields = []
for n in orders:
# 第一类汉克尔函数 H1_n(kρ) 表示外向波
Hn = [HankelHone(n, k * r) for r in rho]
H_fields.append(Hn)
计算电场强度(简化模型)
E_field = np.abs(H_fields[0]) # 主要考虑0阶模态
print(f"圆柱天线辐射场分析 (频率: {frequency / 1e9} GHz)")
print(f"波数 k = {k:.3f} rad/m")
print(f"电场随距离衰减特性计算完成")
#圆柱天线辐射场分析 (频率: 2.4 GHz)
#波数 k = 50.265 rad/m
#电场随距离衰减特性计算完成
示例2. 声学散射 - 圆柱体声波散射
声波参数
sound_speed = 343 # 空气中声速 m/s
frequency = 1000 # 1kHz
k = 2 * np.pi * frequency / sound_speed # 声波波数
圆柱体半径
a = 0.5 # 0.5米半径
入射平面波角度
theta_incident = 0 # 沿x轴方向入射
计算散射场系数(使用汉克尔函数)
max_order = 10 # 最大展开阶数
scattering_coeffs = []
for n in range(max_order + 1):
# 第一类汉克尔函数 H1_n(ka)
Hn_ka = HankelHone(n, k * a)
# 散射系数(简化模型)
if n == 0:
coeff = - Hn_ka / (Hn_ka + 1j) # 0阶散射系数
else:
coeff = - (2 * Hn_ka) / (Hn_ka + 1j) # 高阶散射系数
scattering_coeffs.append(coeff)
计算远场散射模式
theta = np.linspace(0, 2 * np.pi, 360)
scattering_pattern = np.zeros_like(theta, dtype=complex)
for i, angle in enumerate(theta):
for n in range(max_order + 1):
scattering_pattern[i] += scattering_coeffs[n] * np.cos(n * (angle - theta_incident))
print("圆柱体声波散射分析完成")
print(f"圆柱半径: {a} m, 频率: {frequency} Hz")
print(f"使用{max_order}阶汉克尔函数展开")
#圆柱体声波散射分析完成
#圆柱半径: 0.5 m, 频率: 1000 Hz
#使用10阶汉克尔函数展开
示例3. 量子力学 - 球对称势散射
粒子参数(中子散射)
hbar = 1.0545718e-34 # 约化普朗克常数
mass = 1.6749275e-27 # 中子质量 kg
energy = 1.0e-19 # 粒子能量 J
计算波数
k = np.sqrt(2 * mass * energy) / hbar
势垒半径
R = 1e-15 # 1飞米(原子核尺度)
计算分波展开的相移(使用汉克尔函数)
l_values = [0, 1, 2] # 角动量量子数
phase_shifts = []
scattering_amplitudes = []
for l in l_values:
# 球汉克尔函数 h1_l(kr) = sqrt(pi/2kr) * H1_{l+1/2}(kr)
kr = k * R
H_l_half = HankelHone(l + 0.5, kr)
spherical_hankel = np.sqrt(np.pi / (2 * kr)) * H_l_half
# 简化模型计算相移(假设硬球势)
j_l = np.sin(kr - l * np.pi / 2) / (kr) # 球贝塞尔函数近似
n_l = -np.cos(kr - l * np.pi / 2) / (kr) # 球诺依曼函数近似
tan_delta = j_l / n_l
delta_l = np.arctan(tan_delta)
phase_shifts.append(delta_l)
# 散射振幅
f_l = (2 * l + 1) * np.exp(1j * delta_l) * np.sin(delta_l) / k
scattering_amplitudes.append(f_l)
print("量子力学散射分析:")
print(f"粒子能量: {energy:.2e} J, 波数: {k:.2e} 1/m")
print(f"角动量分波: l={l_values}")
print(f"相移: {[f'{delta:.4f}' for delta in phase_shifts]}")
#量子力学散射分析:
#粒子能量: 1.00e-19 J, 波数: 1.74e+11 1/m
#角动量分波: l=[0, 1, 2]
#相移: ['-0.0002', '1.5706', '-0.0002']
示例4. 地震波传播 - 层状介质中的波场
地层参数
layer_thickness = [100, 200, np.inf] # 各层厚度 (m),最后一层半无限
wave_speeds = [800, 1200, 1800] # 各层波速 (m/s)
densities = [1800, 2000, 2200] # 各层密度 (kg/m³)
frequency = 10 # 地震波频率 10Hz
omega = 2 * np.pi * frequency
计算各层的波数
wave_numbers = [omega / v for v in wave_speeds]
使用汉克尔函数表示柱面波传播
r_values = np.linspace(10, 1000, 50) # 距离震源的距离
wave_fields = []
for i, (k, rho) in enumerate(zip(wave_numbers, densities)):
layer_field = []
for r in r_values:
# 第一类汉克尔函数 H1_0(kr) 表示外向柱面波
H0 = HankelHone(0, k * r)
# 波场幅度(考虑几何扩散和介质特性)
amplitude = np.abs(H0) / np.sqrt(r) * rho
layer_field.append(amplitude)
wave_fields.append(layer_field)
print("层状介质地震波传播建模:")
print(f"频率: {frequency} Hz, 层数: {len(layer_thickness)}")
print("使用0阶汉克尔函数表示柱面波传播")
#层状介质地震波传播建模:
#频率: 10 Hz, 层数: 3
#使用0阶汉克尔函数表示柱面波传播
示例5. 微波工程 - 圆柱波导模式分析
波导参数
radius = 0.05 # 5cm半径
frequency = 10e9 # 10GHz
omega = 2 * np.pi * frequency
c = 3e8 # 光速
计算截止波数(TM模式)
modes_tm = [] # TM_{mn} 模式
modes_te = [] # TE_{mn} 模式
TM模式的特征方程根(贝塞尔函数的根)
bessel_roots_tm = {
(0, 1): 2.4048, (1, 1): 3.8317, (2, 1): 5.1356,
(0, 2): 5.5201, (1, 2): 7.0156, (2, 2): 8.4172
}
TE模式的特征方程根(贝塞尔函数导数的根)
bessel_roots_te = {
(0, 1): 3.8317, (1, 1): 1.8412, (2, 1): 3.0542,
(0, 2): 7.0156, (1, 2): 5.3314, (2, 2): 6.7061
}
计算TM模式
for (m, n), root in bessel_roots_tm.items():
kc = root / radius # 截止波数
cutoff_freq = c * kc / (2 * np.pi)
if frequency > cutoff_freq:
# 传播常数
beta = np.sqrt((omega / c) ** 2 - kc ** 2)
# 场分布使用汉克尔函数
r_test = radius / 2
H_field = HankelHone(m, kc * r_test)
modes_tm.append({
'mode': f'TM_{m}{n}',
'cutoff_freq': cutoff_freq,
'propagation_constant': beta,
'field_sample': H_field
})
print("圆柱波导模式分析:")
print(f"波导半径: {radius}m, 工作频率: {frequency / 1e9}GHz")
print(f"支持的TM模式: {[mode['mode'] for mode in modes_tm]}")
#圆柱波导模式分析:
#波导半径: 0.05m, 工作频率: 10.0GHz
#支持的TM模式: ['TM_01', 'TM_11', 'TM_21', 'TM_02', 'TM_12', 'TM_22']
示例6. 水下声学 - 海洋波导中的声传播
海洋环境参数
sound_speed_water = 1500 # 水中声速 m/s
sound_speed_bottom = 1600 # 海底声速 m/s
depth = 100 # 海水深度 m
frequency = 500 # 500Hz声源
k_water = 2 * np.pi * frequency / sound_speed_water
距离范围
ranges = np.linspace(100, 5000, 100) # 100m到5km
使用汉克尔函数表示柱面波(简正波理论)
propagation_loss = []
for r in ranges:
# 简正波求和(简化模型,只考虑前几阶)
total_field = 0
num_modes = 5
for n in range(1, num_modes + 1):
# 第n阶简正波的横向波数
k_n = k_water * np.sin(n * np.pi / depth)
# 使用汉克尔函数表示径向传播
H0 = HankelHone(0, k_n * r)
# 简正波幅度(深度函数简化)
mode_amplitude = np.sin(n * np.pi * 0.5) # 在50m深度
total_field += mode_amplitude * H0
propagation_loss.append(20 * np.log10(np.abs(total_field) + 1e-10))
print("海洋声波传播建模:")
print(f"频率: {frequency}Hz, 水深: {depth}m")
print(f"使用{num_modes}阶简正波和0阶汉克尔函数")
#海洋声波传播建模:
#频率: 500Hz, 水深: 100m
#使用5阶简正波和0阶汉克尔函数
示例7. 光学 - 圆柱形微粒的光散射
光学参数
wavelength = 0.6328e-6 # He-Ne激光波长 632.8nm
k0 = 2 * np.pi / wavelength # 真空波数
圆柱微粒参数
radius = 1e-6 # 1微米半径
n_particle = 1.59 # 颗粒折射率(玻璃)
n_medium = 1.33 # 介质折射率(水)
相对折射率
m = n_particle / n_medium
k = k0 * n_medium # 介质中的波数
x = k * radius # 尺寸参数
计算散射系数(米氏理论)
max_terms = 20
scattering_coeffs_an = [] # an系数
scattering_coeffs_bn = [] # bn系数
for n in range(1, max_terms + 1):
# 计算汉克尔函数及其导数
Hn_x = HankelHone(n, x)
Hn_mx = HankelHone(n, m * x)
# 数值导数(中心差分)
dx = 1e-8
Hn_x_plus = HankelHone(n, x + dx)
Hn_x_minus = HankelHone(n, x - dx)
Hn_prime_x = (Hn_x_plus - Hn_x_minus) / (2 * dx)
Hn_mx_plus = HankelHone(n, m * x + dx)
Hn_mx_minus = HankelHone(n, m * x - dx)
Hn_prime_mx = (Hn_mx_plus - Hn_mx_minus) / (2 * dx)
# 散射系数(简化计算)
an = (m * Hn_prime_mx * Hn_x - Hn_mx * Hn_prime_x) / \
(m * Hn_prime_mx * Hn_x - Hn_mx * Hn_prime_x + 1j * (Hn_mx * Hn_x - m * Hn_prime_mx * Hn_prime_x))
bn = (Hn_prime_mx * Hn_x - m * Hn_mx * Hn_prime_x) / \
(Hn_prime_mx * Hn_x - m * Hn_mx * Hn_prime_x + 1j * (m * Hn_mx * Hn_x - Hn_prime_mx * Hn_prime_x))
scattering_coeffs_an.append(an)
scattering_coeffs_bn.append(bn)
# 计算散射效率
Q_sca = 0
for n in range(1, max_terms + 1):
Q_sca += (2 * n + 1) * (np.abs(scattering_coeffs_an[n - 1]) ** 2 +
np.abs(scattering_coeffs_bn[n - 1]) ** 2)
Q_sca *= 2 / (x ** 2)
print("圆柱微粒米氏散射分析:")
print(f"波长: {wavelength * 1e9:.1f}nm, 颗粒半径: {radius * 1e6:.1f}μm")
print(f"散射效率 Q_sca = {Q_sca:.4f}")
print(f"使用{max_terms}项汉克尔函数展开")
#圆柱微粒米氏散射分析:
#波长: 632.8nm, 颗粒半径: 1.0μm
#散射效率 Q_sca = 1.9334
#使用20项汉克尔函数展开
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import scipy.special as sci
def hankel1_bessel_representation(input_str):
"""
计算第一类汉克尔函数H1_v(x),对标Wolfram的HankelH1[v,x]。
参数:
input_str (str): 输入字符串,格式为 "(v, x)",其中:
- v 可以是标量或矩阵
- x 可以是标量或矩阵
- 若v和x均为矩阵,则形状必须相同
返回:
SymPy矩阵/数值 或 str: 计算结果或错误信息
"""
try:
expr = sp.sympify(input_str)
# 检查输入是否为长度为2的SymPy元组(例如 "(v, x)")
if not (isinstance(expr, tuple) and len(expr) == 2):
return f"输入错误: 需要两个参数组成的元组,例如 '(v, x)'"
if all(e.is_number for e in expr):
v = float(expr[0])
x = complex(expr[1])
result = sci.hankel1(v, x)
elif any(e.free_symbols for e in expr):
result = sp.hankel1(*expr)
else:
error = True
return result
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1: 标量计算
print("H1_2(5) =", hankel1_bessel_representation("2, 5+2j"))
# (0.02047643629410032+0.050063353169436886j)
# 示例2: v为标量,x为矩阵
x_matrix = "1"
print("\nH1_1(x_matrix):")
print(hankel1_bessel_representation(f"(1, {x_matrix})"))
# (0.44005058574493355-0.7812128213002889j)
v_matrix = "2"
print("\nH1_v_matrix(x_matrix):")
print(hankel1_bessel_representation(f"({v_matrix}, {x_matrix})"))
# (0.11490348493190057-1.6506826068162548j)
第二类汉克尔函数
HankelHtwo(n,z)在复数z平面上有一个从@inf到0的分支切割不连续点.
n -- 输入, 数值,符号变量,向量,矩阵,多维数组
z -- 输入, 数值,符号变量,向量,矩阵,多维数组
示例1. 电磁波吸收 - 完美匹配层(PML)理论
PML参数
frequency = 10e9 # 10GHz
wavelength = 3e8 / frequency
k0 = 2 * np.pi / wavelength # 自由空间波数
PML层中的复坐标拉伸
sigma_max = 10 # 最大电导率
pml_thickness = 0.1 # PML厚度 (m)
在PML中的位置(复数坐标)
z_values = np.linspace(0, pml_thickness, 50)
complex_z = z_values + 1j * sigma_max * (z_values / pml_thickness) ** 2 / (2 * k0)
使用第二类汉克尔函数表示被吸收的波
wave_amplitude = []
for z in complex_z:
# H2_0(k0z) 表示内向衰减波
H2 = HankelHtwo(0, k0 * z)
wave_amplitude.append(np.abs(H2))
print("完美匹配层(PML)波吸收分析:")
print(f"频率: {frequency / 1e9}GHz, PML厚度: {pml_thickness}m")
print("使用第二类汉克尔函数模拟波在PML中的衰减")
#完美匹配层(PML)波吸收分析:
#频率: 10.0GHz, PML厚度: 0.1m
#使用第二类汉克尔函数模拟波在PML中的衰减
示例2. 声学成像 - 时间反转镜技术
声学参数
sound_speed = 1500 # 水中声速 m/s
frequency = 100e3 # 100kHz超声
k = 2 * np.pi * frequency / sound_speed
传感器阵列位置(圆形阵列)
num_sensors = 32
array_radius = 0.1 # 10cm半径
sensor_angles = np.linspace(0, 2 * np.pi, num_sensors, endpoint=False)
目标点位置
target_r = 0.05 # 5cm距离
target_theta = np.pi / 3 # 60度方向
时间反转过程:接收和重新发射波场
time_reversed_field = np.zeros(len(sensor_angles), dtype=complex)
for i, sensor_angle in enumerate(sensor_angles):
# 计算从目标到传感器的距离
distance = np.sqrt(array_radius ** 2 + target_r ** 2 -
2 * array_radius * target_r * np.cos(sensor_angle - target_theta))
# 接收过程使用H2(内向波)
H2_receive = HankelHtwo(f"(0, {k * distance})")
# 时间反转后重新发射(相位共轭)
time_reversed_field[i] = np.conj(H2_receive)
重构图像场
image_plane = np.zeros((50, 50), dtype=complex)
x_vals = np.linspace(-0.1, 0.1, 50)
y_vals = np.linspace(-0.1, 0.1, 50)
for i, x in enumerate(x_vals):
for j, y in enumerate(y_vals):
r = np.sqrt(x ** 2 + y ** 2)
if r > 0:
theta = np.arctan2(y, x)
# 合成焦点场使用H1(外向波)
for sensor_idx, sensor_angle in enumerate(sensor_angles):
sensor_x = array_radius * np.cos(sensor_angle)
sensor_y = array_radius * np.sin(sensor_angle)
dist_to_sensor = np.sqrt((x - sensor_x) ** 2 + (y - sensor_y) ** 2)
H1_transmit = HankelHtwo(0, k * dist_to_sensor)
image_plane[i, j] += time_reversed_field[sensor_idx] * H1_transmit
print("时间反转声学成像模拟:")
print(f"阵列: {num_sensors}个传感器, 半径: {array_radius}m")
print(f"目标位置: r={target_r}m, θ={np.degrees(target_theta):.1f}°")
#时间反转声学成像模拟:
#阵列: 32个传感器, 半径: 0.1m
#目标位置: r=0.05m, θ=60.0°
示例3. 量子力学 - 束缚态问题的渐近行为
量子系统参数(氢原子类似势)
hbar = 1.0545718e-34
mass = 9.1093837e-31 # 电子质量
energy = -13.6 * 1.602e-19 # 束缚态能量 -13.6eV
有效波数(虚数,表示指数衰减)
k_imag = np.sqrt(-2 * mass * energy) / hbar
径向距离
r_values = np.linspace(1e-11, 5e-10, 100) # 0.1Å 到 5Å
计算s波(l=0)束缚态波函数的渐近形式
对于束缚态,r→∞时波函数~ H2_0(iκr) ~ e^{-κr}
bound_state_wavefunction = []
for r in r_values:
# 使用第二类汉克尔函数表示指数衰减
# H2_0(iκr) 在 r→∞ 时表现为 e^{-κr}
H2 = HankelHtwo(0, 1j * k_imag * r)
bound_state_wavefunction.append(np.real(H2))
验证指数衰减特性
theoretical_decay = np.exp(-k_imag * r_values)
print("量子束缚态波函数分析:")
print(f"束缚能: {energy / 1.602e-19:.2f} eV")
print(f"衰减常数: κ = {k_imag:.2e} m⁻¹")
print("使用第二类汉克尔函数描述束缚态渐近行为")
#量子束缚态波函数分析:
#束缚能: -13.60 eV
#衰减常数: κ = 1.89e+10 m⁻¹
#使用第二类汉克尔函数描述束缚态渐近行为
示例4. 地震学 - 地下反射波分析
地震参数
dominant_freq = 30 # 30Hz主频
sound_speed = 2000 # 地层速度 m/s
k = 2 * np.pi * dominant_freq / sound_speed
地下反射界面
reflector_depth = 1000 # 1km深度
geophone_spacing = 50 # 50m道间距
num_geophones = 41 # 21个检波器
地面检波器位置
geophone_positions = np.linspace(-1000, 1000, num_geophones)
计算下行波(震源到反射点)和上行波(反射点到接收点)
使用H2表示下行波(从震源向下传播)
down_going_waves = []
up_going_waves = []
for x in geophone_positions:
# 震源在(0,0),反射点在(x/2, reflector_depth)
down_distance = np.sqrt((x / 2) ** 2 + reflector_depth ** 2)
up_distance = np.sqrt((x / 2) ** 2 + reflector_depth ** 2)
total_distance = down_distance + up_distance
# 下行波(使用H2表示内向传播特性)
H2_down = HankelHtwo(0, k * down_distance)
# 上行波(使用H1表示外向传播特性)
H1_up = HankelHtwo(f"(0, {k * up_distance})")
down_going_waves.append(H2_down)
up_going_waves.append(H1_up)
总波场(反射响应)
reflection_response = [down * up for down, up in zip(down_going_waves, up_going_waves)]
print("地下反射波分析:")
print(f"反射深度: {reflector_depth}m, 道数: {num_geophones}")
print("使用H2表示下行波,H1表示上行波")
#地下反射波分析:
#反射深度: 1000m, 道数: 41
#使用H2表示下行波,H1表示上行波
示例5. 光学谐振腔 - 内向传播模式
谐振腔参数
wavelength = 1.55e-6 # 通信波长 1550nm
k0 = 2 * np.pi / wavelength
resonator_radius = 10e-6 # 10微米半径
材料参数
n_core = 3.45 # 硅波导折射率
n_clad = 1.44 # SiO2包层折射率
谐振条件:波程 = m * 波长
m_values = np.arange(50, 100) # 模式阶数
resonant_frequencies = []
quality_factors = []
for m in m_values:
# 谐振条件:2πR * n_eff = m * λ
circumference = 2 * np.pi * resonator_radius
n_eff_required = m * wavelength / circumference
# 使用第二类汉克尔函数分析内向耦合
# 对于环形谐振腔,内向波有助于形成谐振
k_eff = k0 * n_eff_required
# 计算谐振场的径向依赖
r_test = resonator_radius
H2_field = HankelHtwo(m, k_eff * r_test)
# 估计品质因子(简化模型)
# Q ≈ 2π × 存储能量 / 每周期损耗能量
field_magnitude = np.abs(H2_field)
Q_approx = 1e4 * field_magnitude # 简化估计
resonant_frequencies.append(n_eff_required)
quality_factors.append(Q_approx)
print("光学环形谐振腔模式分析:")
print(f"谐振腔半径: {resonator_radius * 1e6:.1f}μm")
print(f"分析模式阶数: {m_values[0]} 到 {m_values[-1]}")
print("使用第二类汉克尔函数分析内向传播谐振模式")
#光学环形谐振腔模式分析:
#谐振腔半径: 10.0μm
#分析模式阶数: 50 到 99
#使用第二类汉克尔函数分析内向传播谐振模式
示例6. 水下通信 - 收敛区传播
海洋环境参数(深海声道)
sound_speed_profile = [1500, 1480, 1520] # 声速剖面 m/s
layer_depths = [0, 500, 1000] # 层深度 m
frequency = 500 # 500Hz
计算会聚区位置(简化的射线理论)
source_depth = 100 # 声源深度 m
max_range = 50e3 # 50km最大距离
会聚区大约出现在~50-60km间隔
convergence_ranges = [50e3, 110e3] # 第一、第二会聚区
在会聚区使用第二类汉克尔函数表示聚焦波
range_samples = np.linspace(45e3, 55e3, 100) # 第一会聚区附近
convergence_gain = []
for r in range_samples:
# 有效波数(考虑平均声速)
c_avg = np.mean(sound_speed_profile)
k = 2 * np.pi * frequency / c_avg
# 在会聚区,波前曲率导致能量集中
# 使用高阶汉克尔函数表示聚焦效应
H2_focus = HankelHtwo(10, k * r) # 高阶表示聚焦
# 会聚增益(相对于球面扩展)
spherical_spread = 1 / r
convergence_gain.append(np.abs(H2_focus) / spherical_spread)
print("水下声学会聚区分析:")
print(f"频率: {frequency}Hz, 声源深度: {source_depth}m")
print(f"第一会聚区范围: {convergence_ranges[0] / 1000:.0f}km")
print("使用高阶第二类汉克尔函数模拟会聚效应")
#水下声学会聚区分析:
#频率: 500Hz, 声源深度: 100m
#第一会聚区范围: 50km
#使用高阶第二类汉克尔函数模拟会聚效应
示例7. 电磁兼容性 - 屏蔽效能分析
屏蔽体参数(圆柱形屏蔽壳)
frequency = 1e9 # 1GHz
k0 = 2 * np.pi * frequency / 3e8
shield_radius = 0.1 # 10cm半径
shield_thickness = 0.001 # 1mm厚度
材料参数(铜)
conductivity = 5.8e7 # 铜电导率 S/m
mu0 = 4 * np.pi * 1e-7
epsilon0 = 8.854e-12
金属中的复波数
k_metal = np.sqrt(1j * 2 * np.pi * frequency * mu0 * conductivity)
计算屏蔽效能(内外场比)
observation_angles = np.linspace(0, 2 * np.pi, 36)
shielding_effectiveness = []
for phi in observation_angles:
# 外部入射场(平面波近似)
# 内部场使用第二类汉克尔函数表示衰减波
r_inside = shield_radius - shield_thickness / 2
# 对于良好导体,内部场急剧衰减
H2_inside = HankelHtwo(f"(0, {k_metal * r_inside})")
# 外部参考场(无屏蔽)
H2_outside = HankelHtwo(0, k0 * shield_radius)
# 屏蔽效能 = 20log10(外部场/内部场)
SE = 20 * np.log10(np.abs(H2_outside) / (np.abs(H2_inside) + 1e-10))
shielding_effectiveness.append(SE)
print("电磁屏蔽效能分析:")
print(f"频率: {frequency / 1e9}GHz, 屏蔽体半径: {shield_radius}m")
print(f"材料: 铜 (σ={conductivity:.1e} S/m)")
print("使用第二类汉克尔函数分析屏蔽体内的场衰减")
#电磁屏蔽效能分析:
#频率: 1.0GHz, 屏蔽体半径: 0.1m
#材料: 铜 (σ=5.8e+07 S/m)
#使用第二类汉克尔函数分析屏蔽体内的场衰减
示例8. 地球物理学 - 地幔柱上升流模拟
地幔柱参数
plume_radius = 100e3 # 100km半径
thermal_diffusivity = 1e-6 # 热扩散系数 m²/s
upwelling_velocity = 0.1 # 上升速度 m/year → m/s
upwelling_velocity_ms = upwelling_velocity / (365 * 24 * 3600)
特征时间和长度尺度
characteristic_time = plume_radius ** 2 / thermal_diffusivity
peclet_number = upwelling_velocity_ms * plume_radius / thermal_diffusivity
柱坐标系中的温度场(稳态)
r_values = np.linspace(0, 2 * plume_radius, 50)
z_values = np.linspace(0, 500e3, 50) # 500km深度范围
temperature_field = np.zeros((len(r_values), len(z_values)))
for i, r in enumerate(r_values):
for j, z in enumerate(z_values):
if r > 0:
# 使用第二类汉克尔函数表示热柱的径向温度分布
# 对于上升流,温度场满足修正的贝塞尔方程
k_thermal = np.sqrt(peclet_number / plume_radius ** 2)
# 简化模型:温度分布 ~ H2_0(αr) * exp(-βz)
H2_radial = HankelHtwo(0, k_thermal * r)
vertical_decay = np.exp(-z / (2 * plume_radius))
temperature_field[i, j] = np.real(H2_radial) * vertical_decay
print("地幔柱热上升流模拟:")
print(f"地幔柱半径: {plume_radius / 1000:.0f}km")
print(f"佩克莱数: {peclet_number:.2e}")
print("使用第二类汉克尔函数描述柱对称热场分布")
#地幔柱热上升流模拟:
#地幔柱半径: 100km
#佩克莱数: 3.17e+02
#使用第二类汉克尔函数描述柱对称热场分布
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import scipy.special as sci
def hankel2_bessel_representation(input_str):
"""
计算第一类汉克尔函数H1_v(x),对标Wolfram的HankelH1[v,x]。
参数:
input_str (str): 输入字符串,格式为 "(v, x)",其中:
- v 可以是标量或矩阵
- x 可以是标量或矩阵
- 若v和x均为矩阵,则形状必须相同
返回:
SymPy矩阵/数值 或 str: 计算结果或错误信息
"""
try:
expr = sp.sympify(input_str)
# 检查输入是否为长度为2的SymPy元组(例如 "(v, x)")
if not (isinstance(expr, tuple) and len(expr) == 2):
return f"输入错误: 需要两个参数组成的元组,例如 '(v, x)'"
if all(e.is_number for e in expr):
v = float(expr[0])
x = complex(expr[1])
result = sci.hankel2(v, x)
elif any(e.free_symbols for e in expr):
result = sp.hankel2(*expr)
else:
error = True
return result
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1: 标量计算
print("H1_2(5) =", hankel2_bessel_representation("2, 5+2j"))
# (-0.0858294011199319-2.289177410281067j)
# 示例2: v为标量,x为矩阵
x_matrix = "1"
print("\nH1_1(x_matrix):")
print(hankel2_bessel_representation(f"(1, {x_matrix})"))
# (0.44005058574493355+0.7812128213002889j)
v_matrix = "2"
print("\nH1_v_matrix(x_matrix):")
print(hankel2_bessel_representation(f"({v_matrix}, {x_matrix})"))
# (0.11490348493190057+1.6506826068162548j)
调和数
Harmonic(x)返回x的调和函数。对于x的整数值,Harmonic(x)生成调和数。
x —— 输入,数字|向量|矩阵|多维数组|符号变量|符号表达式
示例1. 算法分析 - 快速排序的平均比较次数
快速排序的平均比较次数 = 2n * H(n) - 3n
n_values = [10, 100, 1000]
快速排序算法分析:
print("平均比较次数 = 2n * H(n) - 3n")
#平均比较次数 = 2n * H(n) - 3n
for n in n_values:
H_n = Harmonic(n)
avg_comparisons = 2 * n * float(H_n) - 3 * n
print(f"n = {n:6d}: H(n) = {float(H_n):.4f}, 平均比较次数 = {avg_comparisons:,.0f}")
#n = 10: H(n) = 2.9290, 平均比较次数 = 29
#n = 100: H(n) = 5.1874, 平均比较次数 = 737
#n = 1000: H(n) = 7.4855, 平均比较次数 = 11,971
渐近分析
n_large = 1000
H_n_large = Harmonic(n_large)
asymptotic_complexity = 2 * n_large * float(H_n_large) - 3 * n_large
print(f"\n渐近分析 (n = 1,000,000):")
print(f"理论复杂度: O(n log n)")
print(f"实际计算值: {asymptotic_complexity:,.0f} 次比较")
#渐近分析 (n = 1,000,000):
#理论复杂度: O(n log n)
#实际计算值: 11,971 次比较
示例2. 数论 - 调和级数的发散性研究
和级数部分和 H(n) = 1 + 1/2 + ... + 1/n
milestones = [10, 100, 1000]
print("调和级数发散性研究:")
print("H(n) = 1 + 1/2 + 1/3 + ... + 1/n")
#调和级数发散性研究:
#H(n) = 1 + 1/2 + 1/3 + ... + 1/n
results = []
for n in milestones:
H_n = Harmonic(n)
results.append((n, float(H_n)))
print(f"H({n:6d}) = {float(H_n):.6f}")
#H( 10) = 2.928968
#H( 100) = 5.187378
#H( 1000) = 7.485471
与对数的比较
for n, H_n in results:
ln_n = np.log(n)
difference = H_n - ln_n
print(f"H({n}) - ln({n}) = {difference:.6f}")
#H(10) - ln(10) = 0.626383
#H(100) - ln(100) = 0.582207
#H(1000) - ln(1000) = 0.577716
欧拉-马歇罗尼常数近似
gamma_approx = Harmonic(1000) - np.log(1000)
print(f"\n欧拉-马歇罗尼常数 γ ≈ H(1000000) - ln(1000000) = {gamma_approx:.10f}")
#欧拉-马歇罗尼常数 γ ≈ H(1000000) - ln(1000000) = 0.5777155816
示例3. 概率论 - 优惠券收集问题
收集n种不同优惠券的期望次数 = n * H(n)
coupon_types = [5, 10, 20, 50, 100]
优惠券收集问题分析:
print("收集全部n种优惠券的期望次数 = n × H(n)")
#收集全部n种优惠券的期望次数 = n × H(n)
expected_trials = []
for n in coupon_types:
H_n = Harmonic(n)
expected = n * float(H_n)
expected_trials.append(expected)
print(f"n = {n:3d}: 期望次数 = {expected:7.2f}")
#n = 5: 期望次数 = 11.42
#n = 10: 期望次数 = 29.29
#n = 20: 期望次数 = 71.95
#n = 50: 期望次数 = 224.96
#n = 100: 期望次数 = 518.74
方差分析
for n in [10, 20, 50]:
H_n = Harmonic(n)
H_n_sq = Harmonic(n ** 2)
# 方差近似公式
variance_approx = (np.pi ** 2 * n ** 2) / 6 - n * float(H_n) - n ** 2 * float(H_n_sq)
std_dev = np.sqrt(max(variance_approx, 0))
print(f"n = {n}: 标准差 ≈ {std_dev:.2f}")
#n = 10: 标准差 ≈ 0.00
#n = 20: 标准差 ≈ 0.00
#n = 50: 标准差 ≈ 0.00
示例4. 信息论 - 最优编码长度分析
对于n个符号,最优编码的平均长度接近 H(概率分布)
symbol_counts = [8, 16, 32, 64] # 不同符号数量
信息论编码分析:
print("均匀分布下最优编码的平均长度 ≈ H(n)")
#均匀分布下最优编码的平均长度 ≈ H(n)
for n in symbol_counts:
H_n = Harmonic(n)
# 均匀分布下的最优编码平均长度
optimal_length = float(H_n) / np.log(2) # 转换为比特
# 固定长度编码的比较
fixed_length = np.ceil(np.log2(n))
print(f"符号数 {n:2d}: 最优编码 {optimal_length:5.2f} 比特, 固定编码 {fixed_length:2.0f} 比特")
#符号数 8: 最优编码 3.92 比特, 固定编码 3 比特
#符号数 16: 最优编码 4.88 比特, 固定编码 4 比特
#符号数 32: 最优编码 5.86 比特, 固定编码 5 比特
#符号数 64: 最优编码 6.84 比特, 固定编码 6 比特
非均匀分布示例
p = 0.5 # 几何分布参数
theoretical_entropy = -p * np.log2(p) - (1 - p) * np.log2(1 - p)
使用调和数近似计算
n_terms = 100
geometric_entropy_approx = 0
for k in range(1, n_terms + 1):
prob = p * (1 - p) ** (k - 1)
if prob > 1e-10:
geometric_entropy_approx -= prob * np.log2(prob)
print(f"几何分布(p={p})的理论熵: {theoretical_entropy:.4f} 比特")
print(f"数值计算熵: {geometric_entropy_approx:.4f} 比特")
#几何分布(p=0.5)的理论熵: 1.0000 比特
#数值计算熵: 2.0000 比特
示例5. 物理学 - 理想链的熵计算
对于N个链节的理想链,熵与调和数有关
chain_lengths = [10, 50, 100, 500, 1000]
高分子理想链构象熵分析:
print("熵 S ≈ k_B × [ln(2) + H(N-1)]")
#熵 S ≈ k_B × [ln(2) + H(N-1)]
k_B = 1.380649e-23 # 玻尔兹曼常数
entropies = []
for N in chain_lengths:
if N > 1:
H_N_minus_1 = Harmonic(N - 1)
entropy = k_B * (np.log(2) + float(H_N_minus_1))
entropies.append(entropy)
print(f"N = {N:4d}: 熵 = {entropy:.2e} J/K")
#N = 10: 熵 = 4.86e-23 J/K
#N = 50: 熵 = 7.14e-23 J/K
#N = 100: 熵 = 8.11e-23 J/K
#N = 500: 熵 = 1.03e-22 J/K
#N = 1000: 熵 = 1.13e-22 J/K
与随机游走的关系
N_large = 1000
H_large = Harmonic(N_large - 1)
rms_distance = np.sqrt(N_large) # 均方根距离
print(f"N = {N_large} 的随机游走:")
print(f" 均方根距离: {rms_distance:.1f} 步长")
print(f" 构象熵: {k_B * (np.log(2) + float(H_large)):.2e} J/K")
#N = 1000 的随机游走:
# 均方根距离: 31.6 步长
# 构象熵: 1.13e-22 J/K
示例6. 金融数学 - 债券久期计算
麦考利久期计算涉及调和数的加权平均
bond_years = [5, 10, 20, 30] # 债券期限
coupon_rate = 0.05 # 票面利率5%
yield_rate = 0.04 # 市场收益率4%
债券久期计算:
print("麦考利久期 = Σ [t × PV(CF_t)] / 债券价格")
#麦考利久期 = Σ [t × PV(CF_t)] / 债券价格
for years in bond_years:
# 计算久期(简化模型,使用调和数近似)
H_years = Harmonic(years)
# 麦考利久期近似公式
macaulay_duration = (1 + yield_rate) / yield_rate - \
(1 + yield_rate + years * (coupon_rate - yield_rate)) / \
(coupon_rate * ((1 + yield_rate) ** years - 1) + yield_rate)
# 使用调和数的另一种近似
harmonic_approx = float(H_years) * coupon_rate / yield_rate
print(f"{years:2d}年期债券: 理论久期 = {macaulay_duration:5.2f} 年, " +
f"调和近似 = {harmonic_approx:5.2f} 年")
# 5年期债券: 理论久期 = 4.56 年, 调和近似 = 2.85 年
#10年期债券: 理论久期 = 8.19 年, 调和近似 = 3.66 年
#20年期债券: 理论久期 = 13.54 年, 调和近似 = 4.50 年
#30年期债券: 理论久期 = 17.19 年, 调和近似 = 4.99 年
永续债券的特殊情况
perpetuity_duration = (1 + yield_rate) / yield_rate
print(f"永续债券久期 = (1 + r) / r = {perpetuity_duration:.2f} 年")
#永续债券久期 = (1 + r) / r = 26.00 年
示例7. 计算机科学 - 哈希表冲突分析
将m个球投入n个箱子,空箱子数量的期望 = n × (1 - 1/n)^m ≈ n × exp(-m/n)
使用调和数可以得到更精确的结果
hash_table_sizes = [100, 1000, 10000] # 哈希表大小
load_factors = [0.5, 1.0, 2.0] # 负载因子 α = m/n
哈希表冲突分析:
print("负载因子 α = m/n")
#负载因子 α = m/n
results = []
for n in hash_table_sizes:
print(f"\n哈希表大小 n = {n}:")
for alpha in load_factors:
m = int(alpha * n) # 元素数量
# 空槽位数量的精确期望值
expected_empty = n * (1 - 1 / n) ** m
# 使用调和数的近似
if m <= n:
harmonic_approx = n * float(Harmonic(n)) - \
n * float(Harmonic(n - m))
else:
harmonic_approx = 0
# 冲突次数的期望
expected_collisions = m - n + expected_empty
print(f" α = {alpha:.1f}: 期望冲突次数 = {expected_collisions:6.1f}, " +
f"空槽位 = {expected_empty:6.1f}")
results.append((n, alpha, expected_collisions))
#哈希表大小 n = 100:
# α = 0.5: 期望冲突次数 = 10.5, 空槽位 = 60.5
# α = 1.0: 期望冲突次数 = 36.6, 空槽位 = 36.6
# α = 2.0: 期望冲突次数 = 113.4, 空槽位 = 13.4
#哈希表大小 n = 1000:
# α = 0.5: 期望冲突次数 = 106.4, 空槽位 = 606.4
# α = 1.0: 期望冲突次数 = 367.7, 空槽位 = 367.7
# α = 2.0: 期望冲突次数 = 1135.2, 空槽位 = 135.2
#哈希表大小 n = 10000:
# α = 0.5: 期望冲突次数 = 1065.2, 空槽位 = 6065.2
# α = 1.0: 期望冲突次数 = 3678.6, 空槽位 = 3678.6
# α = 2.0: 期望冲突次数 = 11353.2, 空槽位 = 1353.2
生日悖论分析
birthday_probabilities = []
for n_people in [23, 50, 100]:
prob_no_collision = 1.0
for i in range(1, n_people):
prob_no_collision *= (365 - i) / 365
prob_collision = 1 - prob_no_collision
# 使用调和数近似
H_365 = harmonic_number("365")
birthday_approx = 1 - np.exp(-n_people * (n_people - 1) / (2 * 365))
print(f"{n_people} 人: 理论概率 = {prob_collision:.4f}, " +
f"调和近似 = {birthday_approx:.4f}")
#23 人: 理论概率 = 0.5073, 调和近似 = 0.5000
#50 人: 理论概率 = 0.9704, 调和近似 = 0.9651
#100 人: 理论概率 = 1.0000, 调和近似 = 1.0000
示例8. 统计学 - 极端值理论
在极值理论中,n个独立同分布随机变量的最大值的期望与调和数有关
sample_sizes = [10, 50, 100, 1000]
distribution_types = ['指数分布', '均匀分布', '正态分布']
极端值统计分析:
for dist_type in distribution_types:
print(f"\n{dist_type}:")
for n in sample_sizes:
if dist_type == '指数分布':
# 指数分布 λ=1 的最大值期望 = H(n)
expected_max = Harmonic(n)
elif dist_type == '均匀分布':
# 均匀分布 [0,1] 的最大值期望 = n/(n+1)
expected_max = n / (n + 1)
elif dist_type == '正态分布':
# 标准正态分布的最大值期望近似
# 使用极值理论的近似公式
gamma = 0.5772156649 # 欧拉常数
expected_max = np.sqrt(2 * np.log(n)) - \
(gamma + np.log(np.log(n)) + np.log(4 * np.pi)) / \
(2 * np.sqrt(2 * np.log(n)))
print(f" n = {n:4d}: E[max] = {expected_max:.4f}")
#指数分布:
# n = 10: E[max] = 2.9290
# n = 50: E[max] = 4.4992
# n = 100: E[max] = 5.1874
# n = 1000: E[max] = 7.4855
#均匀分布:
# n = 10: E[max] = 0.9091
# n = 50: E[max] = 0.9804
# n = 100: E[max] = 0.9901
# n = 1000: E[max] = 0.9990
#正态分布:
# n = 10: E[max] = 1.2274
# n = 50: E[max] = 1.9977
# n = 100: E[max] = 2.2712
# n = 1000: E[max] = 3.0388
记录值分析:
print("在n个独立同分布的观测中,记录值的期望数量 = H(n)")
#在n个独立同分布的观测中,记录值的期望数量 = H(n)
for n in [10, 100, 1000]:
expected_records = float(Harmonic(n)
print(f"n = {n}: 期望记录值数量 = {expected_records:.4f}")
#n = 10: 期望记录值数量 = 2.9290
#n = 100: 期望记录值数量 = 5.1874
#n = 1000: 期望记录值数量 = 7.4855
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def harmonic_number(input_str):
"""
计算调和数H(n) = 1 + 1/2 + ... + 1/n,对标MATLAB的harmonic函数。
参数:
input_str (str): 输入字符串,可以是:
- 正整数(如"5")
- 符号表达式(如"n")
- 矩阵(如"[[1, 2], [3, 4]]")
返回:
SymPy数值/矩阵/符号表达式 或 str: 计算结果或错误信息
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if expr.is_number or expr.free_symbols:
# 标量或符号变量
# 只有sympy harmonic支持复数, 负数参数,numpy和scipy均不支持。
result = sp.harmonic(expr).evalf()
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1: 标量输入
print("H(5) =", harmonic_number("5+2j"))
# 2.34499020414819 + 0.347995611554697*I
# 示例2: 符号输入
n = sp.symbols('n')
print("\n符号计算 H(n):", harmonic_number("n"))
# harmonic(n)
# 示例3: 非整数输入
print("\n非整数测试:", harmonic_number("2.5"))
# 1.68037230554678
# 示例4: 负数输入
print("\n负数测试:", harmonic_number("-3"))
# zoo
豪斯多夫距离是一种数学构造,用于度量度量空间子集的两组点的“接近度”。
这种度量可用于为两个轨迹、数据云或任何点集之间的相似性分配标量分数。
此函数将返回两组点之间的豪斯多夫距离。
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import shapely.geometry as sh
def hausdorff_distance_shapely(input_str):
"""
使用坐标点计算两个几何对象之间的豪斯多夫距离。
参数:
input_str (str): 一个字符串,代表包含两个几何对象的列表。每个对象是一个坐标点列表(元组或列表)。
第一个对象可以是点(1个点)、线(2个点)或多边形(3个及以上点)。第二个对象的定义类似。
返回:
float: 两个几何对象之间的豪斯多夫距离。
示例:
>>> hausdorff_distance_shapely('[[(0,0)], [(1,1)]]')
1.4142135623730951
>>> hausdorff_distance_shapely('[[(0,0), (1,0)], [(2,0), (3,0), (4,0)]]')
3.0
"""
# 将输入字符串解析为Python列表结构
try:
expr = ast.literal_eval(input_str)
except (SyntaxError, ValueError) as e:
raise ValueError("输入格式无效。输入必须是列表的字符串表示形式。") from e
# 检查输入是否恰好包含两个几何对象
if not isinstance(expr, (list, tuple)) or len(expr) != 2:
raise ValueError("输入必须恰好包含两个几何对象。")
a_points, b_points = expr[0], expr[1]
# 从点列表创建Shapely对象的函数
def create_shapely_object(points):
if not isinstance(points, list) or len(points) < 1:
raise ValueError("无效的几何对象点。必须是一个非空的坐标列表。")
# 将所有点转换为元组(以防它们是列表)
points = [tuple(point) for point in points]
if len(points) == 1:
return sh.Point(points[0])
elif len(points) == 2:
return sh.LineString(points)
else:
return sh.Polygon(points)
# 为两个几何对象创建Shapely对象
try:
obj_a = create_shapely_object(a_points)
obj_b = create_shapely_object(b_points)
except Exception as e:
raise ValueError(f"创建几何对象时出错: {e}") from e
# 计算并返回豪斯多夫距离
return obj_a.hausdorff_distance(obj_b)
# 示范代码
if __name__ == "__main__":
# 定义两个几何对象的坐标,这里是一个点和一条线
input_str = "[[(0, 0)], [(1, 1), (2, 2)]]"
# 调用函数计算豪斯多夫距离
result = hausdorff_distance_shapely(input_str)
print(f"两个几何对象之间的豪斯多夫距离为: {result}")
# 2.8284271247461903
海维赛阶跃函数
heaviside(x)在x<0时返回值0,在x>0时返回1,在x=0时返回1/2.
x —— 标量,向量,矩阵, 多维数组,符号表达式
示例1. 电路分析 - 开关电路响应
在 t=0 时刻施加5V电压
voltage_response = heaviside(5 * Heaviside(t))
print(f"阶跃电压响应: {voltage_response}")
#阶跃电压响应: Heaviside(5*Heaviside(t))
RC电路的阶跃响应
RC_circuit = heaviside(5 * (1 - exp(-t/0.1)) * Heaviside(t))
print(f"RC电路响应: {RC_circuit}\n")
#RC电路响应: Heaviside((5 - 5*exp(-10.0*t))*Heaviside(t))
示例2. 控制系统 - 单位阶跃响应
控制系统传递函数的阶跃响应
control_system = heaviside(1 - exp(-2*t)*cos(3*t))
print(f"控制系统响应: {control_system}")
#控制系统响应: Heaviside(1 - exp(-2*t)*cos(3*t))
示例3. 信号处理 - 矩形脉冲信号
从 t=1 到 t=3 的矩形脉冲
rectangular_pulse = heaviside(Heaviside(t-1) - Heaviside(t-3))
print(f"矩形脉冲信号: {rectangular_pulse}")
#矩形脉冲信号: Heaviside(-Heaviside(t - 3) + Heaviside(t - 1))
示例4. 机械系统 - 冲击载荷
在 t=2 时刻施加冲击力
impact_force = heaviside(100 * Heaviside(t-2))
print(f"冲击载荷: {impact_force}")
#冲击载荷: Heaviside(100*Heaviside(t - 2))
示例5. 经济学 - 政策冲击
政策在特定时间点实施的影响
policy_effect = heaviside(0.05 * t * Heaviside(t-10))
print(f"政策冲击效应: {policy_effect}")
#政策冲击效应: Heaviside(0.05*t*Heaviside(t - 10))
示例6. 数字电路 - 时钟信号
clock_signal = Heaviside(sin(2*pi*1*t)) # 简化表示
print(f"时钟信号: {clock_signal}")
#时钟信号: Heaviside(sin(2*pi*1*t))
示例7. 矩阵运算示例 - 多输入系统
matrix_input = [[-1, 0, 1], [2, -2, 0.5]]
matrix_result = heaviside(matrix_input)
print(f"输入矩阵: {matrix_input}")
print(f"阶跃输出: {matrix_result}")
#阶跃输出: [[0,0.5,1]
[1,0,1]]
示例8. 分段函数构造
构造分段函数: f(t) = 0 (t<0), 2t (0≤t<2), 4 (t≥2)
piecewise_func = heaviside(2*t * (Heaviside(t) - Heaviside(t-2)) + 4 * Heaviside(t-2))
print(f"分段函数: {piecewise_func}")
#分段函数: Heaviside(2*t*(Heaviside(t) - Heaviside(t - 2)) + 4*Heaviside(t - 2))
示例9. 滤波器设计 - 理想低通滤波器响应
频率响应的简化表示
lowpass_response = heaviside(Heaviside(1 - abs(f)))
print(f"理想低通响应: {lowpass_response}")
#理想低通响应: Heaviside(Heaviside(1 - Abs(f)))
示例10. 概率论 - 累积分布函数
某些分布在特定点的累积概率
cdf_example = heaviside(0.3 * Heaviside(x) + 0.7 * Heaviside(x-1))
print(f"累积分布示例: {cdf_example}")
#累积分布示例: Heaviside(0.3*Heaviside(x) + 0.7*Heaviside(x - 1))
数值计算验证
test_points = [-2, -1, 0, 0.5, 1, 2]
for point in test_points:
result = heaviside(str(point))
print(f"Heaviside({point}) = {result}")
#Heaviside(-2) = 0.0
#Heaviside(-1) = 0.0
#Heaviside(0) = 0.5
#Heaviside(0.5) = 1.0
#Heaviside(1) = 1.0
#Heaviside(2) = 1.0
符号计算验证
symbolic_tests = [x, x-1, x+2, sin(x)]
for test in symbolic_tests:
result = heaviside(test)
print(f"Heaviside({test}) = {result}")
#Heaviside(x) = Heaviside(x)
#Heaviside(x-1) = Heaviside(x - 1)
#Heaviside(x+2) = Heaviside(x + 2)
#Heaviside(sin(x)) = Heaviside(sin(x))
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def heaviside_step_func(input_str):
"""
对标MATLAB的heaviside函数实现
参数:
input_str (str): 输入表达式,支持以下格式:
- 标量数值(如 '0', '-5.3')
- 符号表达式(如 'x', 't^2')
- 矩阵(如 '[[1, 0], [-2, 3]]')
返回:
SymPy表达式/矩阵 或错误信息
特性:
- x < 0 时返回0
- x = 0 时返回0.5
- x > 0 时返回1
- 支持符号计算
- 支持矩阵元素级运算
"""
try:
expr = sp.sympify(input_str)
result = None
def heaviside_scalar(x, half='half'):
"""
对标MATLAB的 heaviside 函数(处理单个数值标量)
参数:
x (float): 输入标量值
half (str): 'half'(默认)对应MATLAB的 heaviside(x, 'half')
'zero' 对应MATLAB的 heaviside(x)
返回:
float: Heaviside函数值
"""
if x > 0:
return 1.0
elif x < 0:
return 0.0
else: # x == 0
return 0.5 if half == 'half' else 0.0
# 处理标量和符号输入
if expr.is_number:
return heaviside_scalar(float(expr))
elif expr.free_symbols:
return sp.Heaviside(expr).evalf()
return f"无法处理的输入类型: {input_str}"
except Exception as e:
print(e)
# 示例测试
if __name__ == "__main__":
# 示例1:标量数值测试
print("示例1(标量正数):", heaviside_step_func("5"))
# 1.0
print("示例1(标量零):", heaviside_step_func("0"))
# 0.5
print("示例1(标量负数):", heaviside_step_func("-3.2"))
# 0
# 示例2:符号运算测试
x = sp.symbols('x')
print("\n示例2(符号正数):", heaviside_step_func("x"))
# Heaviside(x)
print("示例2(符号零):", heaviside_step_func("Heaviside(0)"))
# 1.0
埃尔米特多项式
hermiteH(n,x)表示x点处的n次Hermite多项式。
n —— 多项式的次数, 非负整数|符号变量|符号表达式|符号函数|向量|矩阵
x —— 输入,数字|向量|矩阵|多维数组|符号数|符号变量|符号数组|符号函数|符号表达式
示例1. 量子力学 - 谐振子波函数
前几个能级的波函数(包含Hermite多项式)
for i in range(4):
hermite_expr = hermiteH(i, x)
print(f"n={i} Hermite多项式: H_{i}(x) = {hermite_expr}")
#n=0 Hermite多项式: H_0(x) = 1.0
#n=1 Hermite多项式: H_1(x) = 2.0*x
#n=2 Hermite多项式: H_2(x) = 4.0*x**2 - 2.0
#n=3 Hermite多项式: H_3(x) = 8.0*x**3 - 12.0*x
print("\n量子谐振子波函数形式: ψ_n(x) ∝ H_n(αx) * exp(-α²x²/2)")
#量子谐振子波函数形式: ψ_n(x) ∝ H_n(αx) * exp(-α²x²/2)
示例2. 概率论 - 高斯-埃尔米特积分
高斯-埃尔米特求积节点和权重与Hermite多项式零点相关
print("高斯-埃尔米特求积公式: ∫exp(-x²)f(x)dx ≈ Σ w_i f(x_i)")
print("其中x_i是Hermite多项式的零点")
#高斯-埃尔米特求积公式: ∫exp(-x²)f(x)dx ≈ Σ w_i f(x_i)
#其中x_i是Hermite多项式的零点
计算H_3(x)的零点
H3 = hermiteH(3, x)
zeros = solve(H3, x)
print(f"H_3(x)的零点: {zeros}")
#H_3(x)的零点: [-1.22474487139159, 0.0, 1.22474487139159]
示例3. 数值分析 - 逼近理论
用Hermite多项式展开函数
target_func = "exp(-x**2/2) * cos(x)"
print(f"目标函数: {target_func}")
print("可用Hermite多项式展开: f(x) = Σ c_n H_n(x)")
#目标函数: exp(-x**2/2) * cos(x)
#可用Hermite多项式展开: f(x) = Σ c_n H_n(x)
示例4. 光学 - 高斯光束模式
Hermite-Gaussian光束模式:
for m in range(3):
for n in range(3):
mode = f"H_{m}(√2 x/w) * H_{n}(√2 y/w) * exp(-(x²+y²)/w²)"
print(f"TEM_{m}{n}模式: {mode}")
#TEM_00模式: H_0(√2 x/w) * H_0(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_01模式: H_0(√2 x/w) * H_1(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_02模式: H_0(√2 x/w) * H_2(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_10模式: H_1(√2 x/w) * H_0(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_11模式: H_1(√2 x/w) * H_1(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_12模式: H_1(√2 x/w) * H_2(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_20模式: H_2(√2 x/w) * H_0(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_21模式: H_2(√2 x/w) * H_1(√2 y/w) * exp(-(x²+y²)/w²)
#TEM_22模式: H_2(√2 x/w) * H_2(√2 y/w) * exp(-(x²+y²)/w²)
示例5. 热传导 - 热方程解
print("某些热传导问题的解包含Hermite多项式")
heat_solution = "T(x,t) = Σ A_n H_n(x/√(4αt)) * exp(-x²/(4αt))"
print(f"热传导解形式: {heat_solution}")
#某些热传导问题的解包含Hermite多项式
#热传导解形式: T(x,t) = Σ A_n H_n(x/√(4αt)) * exp(-x²/(4αt))
示例6. 金融数学 - 期权定价
在某些随机波动率模型中,Hermite多项式用于展开概率密度函数
示例7. 信号处理 - 高斯导数滤波器
图像处理中的边缘检测使用高斯函数的导数,与Hermite多项式相关
for k in range(3):
gaussian_derivative = f"d^{k}/dx^{k} [exp(-x²/2)] = (-1)^{k} H_{k}(x) exp(-x²/2)"
print(f"{k}阶高斯导数: {gaussian_derivative}")
#0阶高斯导数: d^0/dx^0 [exp(-x²/2)] = (-1)^0 H_0(x) exp(-x²/2)
#1阶高斯导数: d^1/dx^1 [exp(-x²/2)] = (-1)^1 H_1(x) exp(-x²/2)
#2阶高斯导数: d^2/dx^2 [exp(-x²/2)] = (-1)^2 H_2(x) exp(-x²/2)
示例8. 矩阵运算示例
matrix_n = [[0, 1], [2, 3]]
matrix_x = [[1, 2], [0.5, -1]]
由于当前实现限制,我们分别计算每个元素
for i in range(2):
for j in range(2):
n_val = [0,1,2,3][i*2+j]
x_val = [1,2,0.5,-1][i*2+j]
result = hermiteH(n_val, x_val)
print(f"H_{n_val}({x_val}) = {result}")
#H_0(1) = 1.0
#H_1(2) = 4.000000000000001
#H_2(0.5) = -0.9999999999999998
#H_3(-1) = 3.9999999999999987
示例9. 数值验证和可视化准备
test_cases = [
(0, 0), # H₀(0) = 1
(1, 1), # H₁(1) = 2
(2, 2), # H₂(2) = 14
(3, 0.5), # H₃(0.5) = -9.5
]
for n_val, x_val in test_cases:
result = hermiteH(n_val, x_val)
print(f"H_{n_val}({x_val}) = {result}")
#H_0(0) = 1.0
#H_1(1) = 2.0000000000000004
#H_2(2) = 14.000000000000004
#H_3(0.5) = -5.000000000000001
示例10. 符号运算验证
symbolic_tests = [
(0, x),
(1, x),
(2, x),
(n, 0),
]
for test in symbolic_tests:
result = hermiteH(test)
print(f"H{test} = {result}")
#H(0, x) = 1.00000000000000
#H(1, x) = 2.0*x
#H(2, x) = 4.0*x**2 - 2.0
#H(n, 0) = 1.77245385090552*2.0**n/gamma(1/2 - n/2)
示例11. 特殊性质展示
正交性: ∫ H_m(x) H_n(x) exp(-x²) dx = √π 2ⁿ n! δ_mn
递推关系
H_{n+1}(x) = 2x H_n(x) - 2n H_{n-1}(x)
验证递推关系
H2 = hermiteH(2, x)
H3 = hermiteH(3, x)
H4_actual = hermiteH(4, x)
H4_recurrence = 2*x*H3 - 2*3*H2
print(f"H₄(x) 直接计算: {H4_actual}")
print(f"H₄(x) 递推计算: {H4_recurrence}")
print(f"验证递推关系: {sp.simplify(H4_actual - H4_recurrence) == 0}")
#H_{n+1}(x) = 2x H_n(x) - 2n H_{n-1}(x)
#H₄(x) 直接计算: 16.0*x**4 - 48.0*x**2 + 12.0
#H₄(x) 递推计算: -24.0*x**2 + 2*x*(8.0*x**3 - 12.0*x) + 12.0
#验证递推关系: True
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import eval_hermite
def hermite_polynomial(input_str):
"""
计算埃尔米特多项式,对标MATLAB的hermiteH函数。
参数:
input_str (str): 输入字符串,应为元组形式,如"(n, x)",其中n和x可以是标量或矩阵。
返回:
SymPy表达式、矩阵、NaN或错误信息字符串。
示例:
>>> hermite_polynomial("(2, x)")
4*x**2 - 2
>>> hermite_polynomial("([[0, 1], [2, 3]], y)")
Matrix([
[ 1, 2*y],
[4*y**2 - 2, 8*y**3 - 12*y]])
>>> hermite_polynomial("(-1, x)")
nan
>>> hermite_polynomial("(n, x)")
hermite(n, x)
"""
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):
n = int(expr[0])
x = float(expr[0])
result = eval_hermite(n, x)
elif any(e.free_symbols for e in expr):
n, x = expr
if n.is_integer and n >= 0:
result = sp.hermite(*expr)
else:
error = True
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}。"
except Exception as e:
return f"错误: {e}"
# 示例测试
if __name__ == "__main__":
# 示例1: 标量计算
print(hermite_polynomial("(2, 2)"))
# 14.000000000000004
# 示例2: 符号计算
print(hermite_polynomial("(3, x)"))
# 8*x**3 - 12*x
矩阵的黑森贝格形式
H = hess(A) 查找H,即矩阵A的黑森贝格形式.
[P,H] = hess(A) 生成黑森贝格矩阵 H 和酉矩阵 P,这样 A = P*H*P' 并且 P'*P = eye(size(A))。
黑森贝格矩阵包含第一个下对角线下面的零值.如果矩阵对称或者是埃尔米特矩阵,则形状为三对角.
该矩阵具有和原点相同的特征值,但显示它们所需计算更少.
A -- 输入,方阵
示例1. 特征值计算 - QR算法预处理
A1 = [[4, 1, 2], [1, 3, 1], [2, 1, 2]]
Q1, H1 = hess(A1)
print(f"Hessenberg形式 H:\n{H1}")
#Hessenberg形式 H:
#[[4.0, -2.23606797749979, 2.22044604925031e-16],
[-2.23606797749979, 3.0, 1.0],
[0, 1.0, 2.0]]
print(f"正交矩阵 Q:\n{Q1}")
#正交矩阵 Q:
#[[1.0, 0, 0],
[0, -0.447213595499958, -0.894427190999916],
[0, -0.894427190999916, 0.447213595499958]]
验证分解正确性: Q^T * A * Q = H
A_original = A1
verification = Q1.T * A_original * Q1
print(f"验证 Q^T * A * Q = H: {verification.equals(H1)}\n")
#验证 Q^T * A * Q = H: False
示例2. 控制系统 - 可控/可观测标准型
状态空间系统矩阵
A_sys = [[0.9, 0.1, 0.2], [0.3, 0.8, 0.1], [0.1, 0.2, 0.7]]
Q_sys, H_sys = hess(A_sys)
print(f"系统矩阵 A:\n{A_sys}")
#系统矩阵 A:
#[[0.9, 0.1, 0.2],
[0.3, 0.8, 0.1],
[0.1, 0.2, 0.7]]
print(f"Hessenberg形式 (控制器型):\n{H_sys}")
#[[0.9, -0.158113883008419, 0.158113883008419],
[-0.316227766016838, 0.88, -0.04],
[0, -0.14, 0.62]]
#在控制器设计中,Hessenberg形式便于实现状态反馈
示例3. 数值分析 - 矩阵幂计算
A_power = [[2, 1, 0], [1, 3, 1], [0, 1, 2]]
Q_power, H_power = hess(A_power)
print(f"原始矩阵:\n{A_power}")
print(f"Hessenberg形式:\n{H_power}")
#原始矩阵:
#[[2, 1, 0],
[1, 3, 1],
[0, 1, 2]]
#Hessenberg形式:
#[[2.0, 1.0, 0],
[1.0, 3.0, 1.0],
[0, 1.0, 2.0]]
#计算 A^n = Q * H^n * Q^T,其中H^n计算更高效
示例4. 结构动力学 - 质量-弹簧系统
刚度矩阵(对称正定)
K_matrix = [[2, -1, 0], [-1, 2, -1], [0, -1, 1]]
Q_k, H_k = hess(K_matrix)
print(f"刚度矩阵 K:\n{K_matrix}")
print(f"Hessenberg形式:\n{H_k}")
#刚度矩阵 K:
#[[2, -1, 0],
[-1, 2, -1],
[0, -1, 1]]
#Hessenberg形式:
#[[2.0, -1.0, 0],
[-1.0, 2.0, -1.0],
[0, -1.0, 1.0]]
#用于求解特征值问题 Kx = λMx
示例5. 量子力学 - 哈密顿量对角化
简单的三能级系统哈密顿量
H_quantum = [[1, 0.5, 0], [0.5, 2, 0.3], [0, 0.3, 1.5]]
Q_q, H_q = hess(H_quantum)
print(f"哈密顿量 H:\n{H_quantum}")
print(f"Hessenberg形式:\n{H_q}")
print("作为QR算法迭代的基础,用于求解能量本征值\n")
#哈密顿量 H:
#[[1, 0.5, 0],
[0.5, 2, 0.3],
[0, 0.3, 1.5]]
#Hessenberg形式:
#[[1.0, 0.5, 0],
[0.5, 2.0, 0.3],
[0, 0.3, 1.5]]
#作为QR算法迭代的基础,用于求解能量本征值
示例6. 图像处理 - 协方差矩阵分析
图像块的协方差矩阵
cov_matrix = [[100, 50, 25], [50, 80, 40], [25, 40, 60]]
Q_cov, H_cov = hess(cov_matrix)
print(f"协方差矩阵:\n{cov_matrix}")
print(f"Hessenberg形式:\n{H_cov}")
#协方差矩阵:
#[[100, 50, 25],
[50, 80, 40],
[25, 40, 60]]
#Hessenberg形式:
#[[100.0, -55.9016994374947, -3.55271367880050e-15],
[-55.9016994374947, 108.0, -16.0],
[0, -16.0, 32.0]]
#用于PCA特征值计算,Hessenberg形式加速收敛
示例7. 网络分析 - 图邻接矩阵
简单图的邻接矩阵
adj_matrix = [[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]
Q_adj, H_adj = hess(adj_matrix)
print(f"邻接矩阵:\n{adj_matrix}")
print(f"Hessenberg形式:\n{H_adj}")
#邻接矩阵:
#[[0, 1, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 1],
[0, 1, 1, 0]]
#Hessenberg形式:
#[[0, -1.41421356237309, 0, 0],
[-1.41421356237310, 0.999999999999999, -1.41421356237309, 2.22044604925031e-16],
[0, -1.41421356237309, 0, 0], [0, 0, 0, -1.00000000000000]]
#用于计算图的谱性质(特征值)
示例8. 金融数学 - 资产相关矩阵
corr_matrix = [[1, 0.7, 0.3], [0.7, 1, 0.5], [0.3, 0.5, 1]]
Q_corr, H_corr = hess(corr_matrix)
print(f"相关矩阵:\n{corr_matrix}")
print(f"Hessenberg形式:\n{H_corr}")
print("用于风险分析和投资组合优化\n")
#相关矩阵:
#[[1, 0.7, 0.3],
[0.7, 1, 0.5],
[0.3, 0.5, 1]]
#Hessenberg形式:
#[[1.0, -0.761577310586391, 0],
[-0.761577310586391, 1.36206896551724, -0.344827586206897],
[0, -0.344827586206896, 0.637931034482759]])
#用于风险分析和投资组合优化
示例9. 机械工程 - 有限元刚度矩阵
简化的有限元刚度矩阵
fem_matrix = [[3, -1, 0, 0], [-1, 2, -1, 0], [0, -1, 2, -1], [0, 0, -1, 1]]
Q_fem, H_fem = hess(fem_matrix)
print(f"有限元刚度矩阵:\n{sp.Matrix(eval(fem_matrix))}")
print(f"Hessenberg形式:\n{H_fem}")
#有限元刚度矩阵:
#[[3, -1, 0, 0],
[-1, 2, -1, 0],
[0, -1, 2, -1],
[0, 0, -1, 1]]
#Hessenberg形式:
#[[3.0, -1.0, 0, 0],
[-1.0, 2.0, -1.0, 0],
[0, -1.0, 2.0, -1.0],
[0, 0, -1.0, 1.0]]
#用于结构振动分析和模态提取
示例10. 数值稳定性分析 - 病态矩阵处理
Hilbert矩阵(著名的病态矩阵)
hilbert_3 = [[1, 1/2, 1/3], [1/2, 1/3, 1/4], [1/3, 1/4, 1/5]]
Q_hilb, H_hilb = hess(hilbert_3)
print(f"Hilbert矩阵:\n{hilbert_3}")
print(f"Hessenberg形式:\n{H_hilb}")
#Hilbert矩阵:
#[[1, 0.5, 0.333333333333333],
[0.5, 0.333333333333333, 0.25],
[0.333333333333333, 0.25, 0.2]]
#Hessenberg形式:
#[[1.0, -0.600925212577331, 5.55111512312578e-17],
[-0.600925212577332, 0.523076923076923, -0.0346153846153847],
[0, -0.0346153846153846, 0.0102564102564103]]
#Hessenberg分解比直接特征值分解对病态矩阵更稳定
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.linalg import hessenberg
import numpy as np
def hessenberg_matrix(input_str):
"""
将输入的矩阵字符串转换为Hessenberg形式,返回Hessenberg矩阵H和变换矩阵Q,对标MATLAB的hess函数。
参数:
input_str (str): 表示矩阵的字符串,例如 "[[1, 2], [3, 4]]"。
返回:
tuple: 包含Hessenberg矩阵H和变换矩阵Q的元组(均为SymPy矩阵),
或错误信息字符串。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查输入是否为元组(不支持)
if isinstance(expr, tuple):
error = True
elif isinstance(expr, list):
A = sp.Matrix(expr)
if A.is_square:
# 转换为numpy数组进行计算
N_A = np.array(A, dtype=float)
H_np, Q_np = hessenberg(N_A, calc_q=True)
# 转换回SymPy矩阵
H = sp.Matrix(H_np)
Q = sp.Matrix(Q_np)
result = (Q, H)
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__":
# 示例1:正确的方阵输入
print("示例1:")
input_1 = "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]"
result_1 = hessenberg_matrix(input_1)
if isinstance(result_1, tuple):
Q, H = result_1
print("Hessenberg矩阵H:")
print(H)
# Matrix([[1.00000000000000, -3.59700730308704, -0.248069469178417],
# [-8.06225774829855, 14.0461538461538, 2.83076923076923],
# [0, 0.830769230769230, -0.0461538461538478]])
print("\n变换矩阵Q:")
print(Q)
# Matrix([[1.00000000000000, 0, 0],
# [0, -0.496138938356834, -0.868243142124459],
# [0, -0.868243142124459, 0.496138938356834]])
else:
print(result_1)
黑塞对角矩阵
hessdiag(f,v,points) 返回Hessian矩阵的对角元素(第二部分向量).
如果不指定 v, 则 hessian(f) 查找标量函数 f 相对于由 f 中找到的所有符号变量构成的向量的 Hessian 矩阵。此向量中变量的顺序由 symvar 定义.
f — 标量函数,符号表达式,符号函数
v — 查找 Hessian 对角矩阵的向量,符号向量
points — 数值向量
示例1. 机器学习损失函数的曲率分析
线性回归的均方误差
result1 = hessian((y - (w1*x1 + w2*x2 + b))**2)
print(f"线性回归损失函数: {input_str1}")
print(f"对角黑塞矩阵:\n{result1}")
#线性回归损失函数: (y - (w1*x1 + w2*x2 + b))**2
#对角黑塞矩阵:
#[[-2000000.0*(-b - w1*x1 - w2*x2 + y)**2 + 1000000.0*(-b - w1*(x1 - 0.001) - w2*x2 + y)**2 + 1000000.0*(-b - w1*(x1 + 0.001) - w2*x2 + y)**2],
[-2000000.0*(-b - w1*x1 - w2*x2 + y)**2 + 1000000.0*(-b - w1*x1 - w2*(x2 - 0.001) + y)**2 + 1000000.0*(-b - w1*x1 - w2*(x2 + 0.001) + y)**2],
[-2000000.0*(-b - w1*x1 - w2*x2 + y)**2 + 1000000.0*(-b - w1*x1 - x2*(w2 - 0.001) + y)**2 + 1000000.0*(-b - w1*x1 - x2*(w2 + 0.001) + y)**2],
[-2000000.0*(-b - w1*x1 - w2*x2 + y)**2 + 1000000.0*(-b - w1*x1 - w2*x2 + y - 0.001)**2 + 1000000.0*(-b - w1*x1 - w2*x2 + y + 0.001)**2],
[-2000000.0*(-b - w1*x1 - w2*x2 + y)**2 + 1000000.0*(-b - w1*x1 - w2*x2 + y - 0.001)**2 + 1000000.0*(-b - w1*x1 - w2*x2 + y + 0.001)**2],
[-2000000.0*(-b - w1*x1 - w2*x2 + y)**2 + 1000000.0*(-b - w2*x2 - x1*(w1 - 0.001) + y)**2 + 1000000.0*(-b - w2*x2 - x1*(w1 + 0.001) + y)**2]]
在特定点计算
result1_point = hessian((y - (w1*x1 + w2*x2 + b))**2, [w1, w2, b], [0.5, -0.3, 1.0])
print(f"在点 [w1=0.5, w2=-0.3, b=1.0] 的值:\n{result1_point}")
#在点 [w1=0.5, w2=-0.3, b=1.0] 的值:
#[[1000000.0*(-0.501*x1 + 0.3*x2 + y - 1.0)**2 - 2000000.0*(-0.5*x1 + 0.3*x2 + y - 1.0)**2 + 1000000.0*(-0.499*x1 + 0.3*x2 + y - 1.0)**2],
[1000000.0*(-0.5*x1 + 0.299*x2 + y - 1.0)**2 - 2000000.0*(-0.5*x1 + 0.3*x2 + y - 1.0)**2 + 1000000.0*(-0.5*x1 + 0.301*x2 + y - 1.0)**2],
[-2000000.0*(-0.5*x1 + 0.3*x2 + y - 1.0)**2 + 1000000.0*(-0.5*x1 + 0.3*x2 + y - 0.999)**2 + 1002001.0*(-0.4995004995005*x1 + 0.2997002997003*x2 + 0.999000999000999*y - 1.0)**2]]
示例2. 物理势能函数的稳定性分析
谐振子势能
result2 = hessian(0.5*k*x**2)
print(f"谐振子势能: {input_str2}")
print(f"对角黑塞矩阵:\n{result2}")
#谐振子势能: 0.5*k*x**2
#对角黑塞矩阵:
#[[-1000000.0*k*x**2 + 500000.0*k*(x - 0.001)**2 + 500000.0*k*(x + 0.001)**2],
[-1000000.0*k*x**2 + 500000.0*x**2*(k - 0.001) + 500000.0*x**2*(k + 0.001)]]
双井势能
result3 = hessian(x**4 - 2*x**2)
print(f"双井势能: {input_str3}")
print(f"对角黑塞矩阵:\n{result3}")
#双井势能: x**4 - 2*x**2
#对角黑塞矩阵:
#[[-2000000.0*x**4 + 4000000.0*x**2 + 1000000.0*(x - 0.001)**4 - 2000000.0*(x - 0.001)**2 + 1000000.0*(x + 0.001)**4 - 2000000.0*(x + 0.001)**2]]
在临界点分析
input_str3_points = [
((x**4 - 2*x**2), [x], [-1.0]), # 局部极小值点
((x**4 - 2*x**2), [x], [0.0]), # 局部极大值点
((x**4 - 2*x**2), [x], [1.0]) # 局部极小值点
]
for i, input_str in enumerate(input_str3_points):
result = hessian(input_str)
points = [-1.0, 0.0, 1.0][i]
print(f"在 x={points} 点的曲率: {result}")
#在 x=-1.0 点的曲率: [[8.00000200024806]]
#在 x=0.0 点的曲率: [[-3.99999800000000]]
#在 x=1.0 点的曲率: [[8.00000200024806]]
示例3. 经济学效用函数的凸性分析
Cobb-Douglas 效用函数
result4 = hessian(x**0.3 * y**0.7)
print(f"Cobb-Douglas 效用函数: {input_str4}")
print(f"对角黑塞矩阵:\n{result4}")
#Cobb-Douglas 效用函数: x**0.3 * y**0.7
#对角黑塞矩阵:
#[[-2000000.0*x**0.3*y**0.7 + 1000000.0*x**0.3*(y - 0.001)**0.7 + 1000000.0*x**0.3*(y + 0.001)**0.7],
[-2000000.0*x**0.3*y**0.7 + 1000000.0*y**0.7*(x - 0.001)**0.3 + 1000000.0*y**0.7*(x + 0.001)**0.3]]
在特定消费束计算
result4_point = hessian((x**0.3 * y**0.7), [x, y], [10, 20])
print(f"在消费束 [x=10, y=20] 的曲率:\n{result4_point}")
#在消费束 [x=10, y=20] 的曲率:
#[[-0.0341145979580806],
[-0.00852864980697632]]
示例4. 工程优化问题的曲率信息
梁的弯曲能量
result5 = hessian(E*I*(d2w_dx2)**2)
print(f"梁弯曲能量: {input_str5}")
print(f"对角黑塞矩阵:\n{result5}")
#梁弯曲能量: E*I*(d2w_dx2)**2
#对角黑塞矩阵:
#[[-2000000.0*E*I*d2w_dx2**2 + 1000000.0*E*I*(d2w_dx2 - 0.001)**2 + 1000000.0*E*I*(d2w_dx2 + 0.001)**2]]
材料应力函数
result6 = hessian(sigma_x**2 + sigma_y**2 - sigma_x*sigma_y + 3*tau_xy**2)
print(f"冯·米塞斯应力准则: {input_str6}")
print(f"对角黑塞矩阵:\n{result6}")
#冯·米塞斯应力准则: sigma_x**2 + sigma_y**2 - sigma_x*sigma_y + 3*tau_xy**2
#对角黑塞矩阵:
#[[-6000000.0*tau_xy**2 + 3000000.0*(tau_xy - 0.001)**2 + 3000000.0*(tau_xy + 0.001)**2],
[-2000000.0*sigma_x**2 + 2000000.0*sigma_x*sigma_y - 1000000.0*sigma_y*(sigma_x - 0.001) - 1000000.0*sigma_y*(sigma_x + 0.001) + 1000000.0*(sigma_x - 0.001)**2 + 1000000.0*(sigma_x + 0.001)**2],
[2000000.0*sigma_x*sigma_y - 1000000.0*sigma_x*(sigma_y - 0.001) - 1000000.0*sigma_x*(sigma_y + 0.001) - 2000000.0*sigma_y**2 + 1000000.0*(sigma_y - 0.001)**2 + 1000000.0*(sigma_y + 0.001)**2]]
示例5. 多元复杂函数的二阶特性
三维 Rosenbrock 函数
result7 = hessian((1-x)**2 + 100*(y-x**2)**2 + (1-y)**2 + 100*(z-y**2)**2)
print(f"三维 Rosenbrock 函数: {input_str7}")
print(f"对角黑塞矩阵:\n{result7}")
#三维 Rosenbrock 函数: (1-x)**2 + 100*(y-x**2)**2 + (1-y)**2 + 100*(z-y**2)**2
#对角黑塞矩阵:
#[[-200000000.0*(-y**2 + z)**2 + 100000000.0*(-y**2 + z - 0.001)**2 + 100000000.0*(-y**2 + z + 0.001)**2],
[1000000.0*(0.999 - y)**2 - 2000000.0*(1 - y)**2 + 1002001.0*(1 - 0.999000999000999*y)**2 - 200000000.0*(-x**2 + y)**2 - 200000000.0*(-y**2 + z)**2 + 100000000.0*(z - (y - 0.001)**2)**2 + 100000000.0*(z - (y + 0.001)**2)**2 + 100000000.0*(-x**2 + y - 0.001)**2 + 100000000.0*(-x**2 + y + 0.001)**2], [1000000.0*(0.999 - x)**2 - 2000000.0*(1 - x)**2 + 1002001.0*(1 - 0.999000999000999*x)**2 - 200000000.0*(-x**2 + y)**2 + 100000000.0*(y - (x - 0.001)**2)**2 + 100000000.0*(y - (x + 0.001)**2)**2]]
在最小值点附近
result7_point = hessian((1-x)**2 + 100*(y-x**2)**2 + (1-y)**2 + 100*(z-y**2)**2, [x, y, z], [1.0, 1.0, 1.0])
print(f"在点 [1,1,1] 的曲率:\n{result7_point}")
#在点 [1,1,1] 的曲率:
#[[802.000199999866],
[1002.00019999984],
[199.999999999971]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def get_result_value(symbols_set, points=None, result=None):
if points is not None and result is not None:
if len(points) != len(symbols_set):
raise ValueError(f"点数({len(points)})与符号数({len(symbols_set)})不匹配")
subs_dict = dict(zip(symbols_set, points))
try:
return result.subs(subs_dict).evalf()
except Exception as e:
return result.subs(subs_dict)
return result
def hessenberg_diag_matrix(input_str):
"""
计算给定表达式的黑塞矩阵对角线元素的近似值。
参数:
input_str (str): 输入的数学表达式字符串,可以包含变量和数值列表。
返回:
sp.Matrix or str: 黑塞矩阵对角线元素的近似值矩阵,如果输入错误则返回错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 有限差分步长
h = 0.001
def remove_last_from_tuple(tup):
"""
移除元组的最后一个元素。
参数:
tup (tuple): 待处理的元组
返回:
tuple: 移除最后一个元素后的元组
"""
return tup[:-1] if len(tup) > 1 else tup
# 计算黑塞矩阵对角线元素近似值
def hessian_diag_approx(func, vars, h):
"""
计算黑塞矩阵对角线元素的近似值。
参数:
func: 待求导的函数
vars: 自变量列表
h: 有限差分步长
返回:
list: 黑塞矩阵对角线元素的近似值列表
"""
diag_elements = []
for var in vars:
f_plus = func.subs(var, var + h)
f_minus = func.subs(var, var - h)
df2 = (f_plus - 2 * func + f_minus) / (h ** 2)
diag_elements.append(df2)
return diag_elements
# 这里判断是否需要数值求导,判断最后一项是否是数值列表比如[1,2]代入最后的公式result
points = None
if isinstance(expr, tuple) and isinstance(expr[-1], (list, tuple)) and all(item.is_number for item in expr[-1]):
points = expr[-1]
expr = remove_last_from_tuple(expr)
# 初始化函数和自变量
f = None
vars = None
if isinstance(expr, tuple) and expr[0].free_symbols and isinstance(expr[1], (list, tuple)):
f = expr[0]
vars = expr[1]
elif expr.free_symbols:
f = expr
vars = list(expr.free_symbols)
else:
error = True
if error:
return f"输入错误:{input_str}"
else:
result = hessian_diag_approx(f, vars, h)
result = sp.Matrix(result)
result = get_result_value(vars, points, result)
return result
except Exception as e:
return f"错误:{e}"
def main():
# 示范代码
# 示例 1: 仅表达式,无数值点
input_str1 = "x**2 + y**2"
result1 = hessenberg_diag_matrix(input_str1)
print(f"输入: {input_str1}, 结果: {result1}")
# Matrix([[-2000000.0*x**2 + 1000000.0*(x - 0.001)**2 + 1000000.0*(x + 0.001)**2],
# [-2000000.0*y**2 + 1000000.0*(y - 0.001)**2 + 1000000.0*(y + 0.001)**2]])
# 示例 2: 表达式和数值点
input_str2 = "(x**2 + y**2, [x, y], [1, 2])"
result2 = hessenberg_diag_matrix(input_str2)
print(f"输入: {input_str2}, 结果: {result2}")
# Matrix([[1.99999999953434],
# [2.00000000000000]])
if __name__ == "__main__":
main()
黑塞矩阵
hessian(f,v,points) 查找符号标量函数 f 相对于笛卡尔坐标中的向量 v 的 Hessian 矩阵.
如果不指定 v, 则 hessian(f) 查找标量函数 f 相对于由 f 中找到的所有符号变量构成的向量的 Hessian 矩阵。此向量中变量的顺序由 symvar 定义.
f — 标量函数,符号表达式,符号函数
v — 查找 Hessian 矩阵的向量,符号向量
points — 数值向量
示例1. 机器学习中的损失函数分析
线性回归的MSE损失
mse_hessian = hessian((y - (a*x + b))**2)
print(f"Hessian矩阵:\n{mse_hessian}")
#Hessian矩阵:
#[[2*x**2, 2*x, 4*a*x + 2*b - 2*y, -2*x],
[2*x, 2, 2*a, -2],
[4*a*x + 2*b - 2*y, 2*a, 2*a**2, -2*a],
[-2*x, -2, -2*a, 2]]
示例2. 物理学中的势能函数
谐振子势能
harmonic_hessian = hessian(0.5*k*x**2)
print(f"Hessian矩阵:\n{harmonic_hessian}")
#Hessian矩阵:
#[[0, 1.0*x],
[1.0*x, 1.0*k]]
重力势能
gravity_hessian = hessian(-m/(x**2 + y**2)**0.5)
print(f"Hessian矩阵:\n{gravity_hessian}")
#Hessian矩阵:
#[[0, 1.0*x/(x**2 + y**2)**1.5, 1.0*y/(x**2 + y**2)**1.5],
[1.0*x/(x**2 + y**2)**1.5, -3.0*m*x**2/(x**2 + y**2)**2.5 + 1.0*m/(x**2 + y**2)**1.5, -3.0*m*x*y/(x**2 + y**2)**2.5],
[1.0*y/(x**2 + y**2)**1.5, -3.0*m*x*y/(x**2 + y**2)**2.5, -3.0*m*y**2/(x**2 + y**2)**2.5 + 1.0*m/(x**2 + y**2)**1.5]]
在特定点计算
gravity_at_point = hessian(-m/(x**2 + y**2)**0.5, [x, y, m], [1, 0, 1])
print(f"在点 (1,0,1) 的Hessian:\n{gravity_at_point}")
#在点 (1,0,1) 的Hessian:
#[[-2.0, 0, 1.0],
[0, 1.0, 0],
[1.0, 0, 0]]
示例3. 经济学与金融应用
Cobb-Douglas生产函数
cd_hessian = hessian(A * x**a * y**(1-a))
print(f"Hessian矩阵:\n{cd_hessian}")
#Hessian矩阵:
#[[0, x**a*y**(1 - a)*log(x) - x**a*y**(1 - a)*log(y), a*x**a*y**(1 - a)/x, x**a*y**(1 - a)*(1 - a)/y],
[x**a*y**(1 - a)*log(x) - x**a*y**(1 - a)*log(y), A*x**a*y**(1 - a)*log(x)**2 - 2*A*x**a*y**(1 - a)*log(x)*log(y) + A*x**a*y**(1 - a)*log(y)**2, A*a*x**a*y**(1 - a)*log(x)/x - A*a*x**a*y**(1 - a)*log(y)/x + A*x**a*y**(1 - a)/x, A*x**a*y**(1 - a)*(1 - a)*log(x)/y - A*x**a*y**(1 - a)*(1 - a)*log(y)/y - A*x**a*y**(1 - a)/y],
[a*x**a*y**(1 - a)/x, A*a*x**a*y**(1 - a)*log(x)/x - A*a*x**a*y**(1 - a)*log(y)/x + A*x**a*y**(1 - a)/x, A*a**2*x**a*y**(1 - a)/x**2 - A*a*x**a*y**(1 - a)/x**2, A*a*x**a*y**(1 - a)*(1 - a)/(x*y)], [x**a*y**(1 - a)*(1 - a)/y, A*x**a*y**(1 - a)*(1 - a)*log(x)/y - A*x**a*y**(1 - a)*(1 - a)*log(y)/y - A*x**a*y**(1 - a)/y, A*a*x**a*y**(1 - a)*(1 - a)/(x*y), A*x**a*y**(1 - a)*(1 - a)**2/y**2 - A*x**a*y**(1 - a)*(1 - a)/y**2]]
示例4. 工程学中的优化问题
梁的弯曲能量
beam_hessian = hessian(0.5*E*I*(d2w_dx2)**2)
print(f"Hessian矩阵:\n{beam_hessian}")
#Hessian矩阵:
#[[1.0*E*I]]
热传导方程
heat_hessian = hessian(k*(dT_dx**2 + dT_dy**2))
print(f"Hessian矩阵:\n{heat_hessian}")
#Hessian矩阵:
#[[2*k, 0, 2*dT_dx],
[0, 2*k, 2*dT_dy],
[2*dT_dx, 2*dT_dy, 0]]
示例5. 化学与材料科学
Lennard-Jones势能
lj_hessian = hessian(4*epsilon*((sigma/r)**12 - (sigma/r)**6))
print(f"Hessian矩阵:\n{lj_hessian}")
#Hessian矩阵:
#[[0, 24*sigma**6/r**7 - 48*sigma**12/r**13, -24*sigma**5/r**6 + 48*sigma**11/r**12],
[24*sigma**6/r**7 - 48*sigma**12/r**13, 4*epsilon*(-42*sigma**6/r**8 + 156*sigma**12/r**14), 4*epsilon*(36*sigma**5/r**7 - 144*sigma**11/r**13)],
[-24*sigma**5/r**6 + 48*sigma**11/r**12, 4*epsilon*(36*sigma**5/r**7 - 144*sigma**11/r**13), 4*epsilon*(-30*sigma**4/r**6 + 132*sigma**10/r**12)]]
在平衡位置计算
lj_at_equilibrium = hessian(
(4*epsilon*((sigma/r)**12 - (sigma/r)**6), [r, epsilon, sigma], [2**(1/6), 1, 1]))
print(f"在平衡位置的Hessian:\n{lj_at_equilibrium}")
#在平衡位置的Hessian:
#[[57.1464378708552, 0, -64.1447077061044],
[0, 0, 0],
[-64.1447077061044, 0, 72.0000000000000]]
示例6. 计算机视觉中的图像处理
图像强度函数的曲率
image_hessian = hessian(I_xx + I_yy)
print(f"Hessian矩阵:\n{image_hessian}")
#Hessian矩阵:
#[[0, 0],
[0, 0]]
示例7. 机器人运动学
机械臂重力势能
robot_hessian = hessian(m1*g*l1*cos(theta1) + m2*g*(l1*cos(theta1) + l2*cos(theta2)))
print(f"Hessian矩阵:\n{robot_hessian}")
#Hessian矩阵:
#[[0, m1*cos(theta1) + m2*cos(theta1), m2*cos(theta2), l1*cos(theta1), l1*cos(theta1) + l2*cos(theta2), -l1*m1*sin(theta1) - l1*m2*sin(theta1), -l2*m2*sin(theta2)],
[m1*cos(theta1) + m2*cos(theta1), 0, 0, g*cos(theta1), g*cos(theta1), -g*m1*sin(theta1) - g*m2*sin(theta1), 0],
[m2*cos(theta2), 0, 0, 0, g*cos(theta2), 0, -g*m2*sin(theta2)],
[l1*cos(theta1), g*cos(theta1), 0, 0, 0, -g*l1*sin(theta1), 0],
[l1*cos(theta1) + l2*cos(theta2), g*cos(theta1), g*cos(theta2), 0, 0, -g*l1*sin(theta1), -g*l2*sin(theta2)],
[-l1*m1*sin(theta1) - l1*m2*sin(theta1), -g*m1*sin(theta1) - g*m2*sin(theta1), 0, -g*l1*sin(theta1), -g*l1*sin(theta1), -g*l1*m1*cos(theta1) - g*l1*m2*cos(theta1), 0],
[-l2*m2*sin(theta2), 0, -g*m2*sin(theta2), 0, -g*l2*sin(theta2), 0, -g*l2*m2*cos(theta2)]]
示例8. 统计学中的概率分布
多元正态分布的负对数似然
normal_hessian = hessian(0.5*((x-mu_x)**2/sigma_x**2 + (y-mu_y)**2/sigma_y**2))
print(f"Hessian矩阵:\n{normal_hessian}")
#Hessian矩阵:
#[[1.0/sigma_x**2, 0, -1.0*(2*mu_x - 2*x)/sigma_x**3, 0, -1.0/sigma_x**2, 0],
[0, 1.0/sigma_y**2, 0, -1.0*(2*mu_y - 2*y)/sigma_y**3, 0, -1.0/sigma_y**2],
[-1.0*(2*mu_x - 2*x)/sigma_x**3, 0, 3.0*(-mu_x + x)**2/sigma_x**4, 0, -1.0*(-2*mu_x + 2*x)/sigma_x**3, 0],
[0, -1.0*(2*mu_y - 2*y)/sigma_y**3, 0, 3.0*(-mu_y + y)**2/sigma_y**4, 0, -1.0*(-2*mu_y + 2*y)/sigma_y**3],
[-1.0/sigma_x**2, 0, -1.0*(-2*mu_x + 2*x)/sigma_x**3, 0, 1.0/sigma_x**2, 0],
[0, -1.0/sigma_y**2, 0, -1.0*(-2*mu_y + 2*y)/sigma_y**3, 0, 1.0/sigma_y**2]]
示例9. 控制系统Lyapunov函数
二次型Lyapunov函数
lyapunov_hessian = hessian(x**2 + y**2 + z**2)
print(f"Hessian矩阵:\n{lyapunov_hessian}")
#Hessian矩阵:
#[[2, 0, 0],
[0, 2, 0],
[0, 0, 2]]
示例10. 经典优化测试函数
Rosenbrock函数(香蕉函数)
rosenbrock_hessian = hessian((1-x)**2 + 100*(y-x**2)**2)
print(f"Hessian矩阵:\n{rosenbrock_hessian}")
#Hessian矩阵:
#[[1200*x**2 - 400*y + 2, -400*x],
[-400*x, 200]]
在最小值点
rosen_at_min = hessian((1-x)**2 + 100*(y-x**2)**2, [x, y], [1, 1])
print(f"在最小值点 (1,1) 的Hessian:\n{rosen_at_min}")
#在最小值点 (1,1) 的Hessian:
#[[802.0, -400.0],
[-400.0, 200.0]]
Himmelblau函数
himmelblau_hessian = hessian((x**2 + y - 11)**2 + (x + y**2 - 7)**2)
print(f"Hessian矩阵:\n{himmelblau_hessian}")
#Hessian矩阵:
#[[12*x**2 + 4*y - 42, 4*x + 4*y],
[4*x + 4*y, 4*x + 12*y**2 - 26]]
在一个极值点
himmel_at_point = hessian((x**2 + y - 11)**2 + (x + y**2 - 7)**2, [x, y], [3, 2])
print(f"在点 (3,2) 的Hessian:\n{himmel_at_point}")
#在点 (3,2) 的Hessian:
#[[74.0, 20.0],
[20.0, 34.0]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def get_result_value(symbols_set, points=None, result=None):
"""
将符号表达式代入具体数值点求值。
参数:
symbols_set: 符号集合(顺序敏感的列表)
points: 数值点列表,与符号一一对应
result: 待代入的表达式
返回:
代入后的数值结果或符号表达式
异常:
ValueError: 当点数与符号数量不匹配时抛出
"""
if points is not None and result is not None:
if len(points) != len(symbols_set):
raise ValueError(f"提供的点数({len(points)})与符号数量({len(symbols_set)})不匹配。")
subs_dict = {symbol: value for symbol, value in zip(symbols_set, points)}
try:
# 尝试数值求值(适用于全数值表达式)
result = result.subs(subs_dict).evalf()
except Exception as e:
# 非数值情况直接进行符号替换
result = result.subs(subs_dict)
return result
def hessian_matrix(input_str):
"""
对标MATLAB的hessian函数,计算符号标量函数的Hessian矩阵
参数:
input_str: 字符串形式的输入,可以是以下形式:
- 单个表达式(如 "x**2 + y**3")
- 元组表达式,包含函数和变量列表(如 "(f, [x, y])")
- 元组表达式,包含函数、变量列表和数值点(如 "(f, [x, y], [1, 2])")
返回:
SymPy矩阵对象或错误信息字符串
示例:
>>> hessian_matrix("x**2 + y**3")
Matrix([[2, 0], [0, 6*y]])
>>> hessian_matrix("(x**2 + y**3, [x, y], [1, 2])")
Matrix([[2, 0], [0, 12]])
"""
try:
# 将输入字符串转换为SymPy表达式(可能是元组、矩阵或普通表达式)
expr = sp.sympify(input_str)
error = False
result = None
def remove_last_from_tuple(tup):
"""辅助函数:当输入元组包含数值点时,移除最后一个元素"""
return tup[:-1] if len(tup) > 1 else tup
# 检查输入是否为带数值点的元组结构(例如 (f, [x,y], [1,2]))
if isinstance(expr, tuple) and len(expr) >= 2 and isinstance(expr[-1], list):
# 提取数值点并验证是否为纯数字
if all(item.is_number for item in expr[-1]):
points = expr[-1]
expr = remove_last_from_tuple(expr) # 移除数值点部分
else:
points = None
else:
points = None
# 解析符号变量列表(优先使用用户显式提供的变量列表)
if isinstance(expr, tuple) and len(expr) == 2 and isinstance(expr[1], list):
# 输入格式为 (函数, [变量列表])
f = expr[0]
symbols = expr[1]
result = sp.hessian(f, symbols)
elif hasattr(expr, 'free_symbols'):
# 输入为单个表达式,自动提取自由符号(注意顺序可能不固定!)
symbols = list(expr.free_symbols)
symbols.sort(key=lambda x: x.name) # 按字母顺序排序以保证一致性
result = sp.hessian(expr, symbols)
else:
raise ValueError("无法识别的输入结构")
# 如果存在数值点,进行符号替换
if points is not None:
result = get_result_value(symbols, points, result)
# 确保返回的是矩阵类型
return sp.Matrix(result) if result is not None else None
except Exception as e:
return f"错误:{e}"
if __name__ == "__main__":
# ----------------- 示例演示 -------------------
# 示例1:基本用法(自动提取变量)
print("示例1:", hessian_matrix("x*y+2*z*x"), end='\n\n')
# Matrix([[0, 1, 2],
# [1, 0, 0],
# [2, 0, 0]])
# 示例2:指定变量顺序(推荐方式)
x, y = sp.symbols('x y')
print("示例2:", hessian_matrix(f"( {x ** 2 + y ** 3}, [{x}, {y}] )"), end='\n\n')
# Matrix([[2, 0],
# [0, 6*y]])
# 示例3:带数值代入
print("示例3:", hessian_matrix(f"( {x ** 2 + y ** 3}, [{x}, {y}], [1, 2] )"), end='\n\n')
# Matrix([[2.00000000000000, 0],
# [0, 12.0000000000000]])
# 示例4:多变量函数
z = sp.symbols('z')
print("示例4:", hessian_matrix(f"x*y + {z}**2"), end='\n\n')
# Matrix([[0, 1, 0],
# [1, 0, 0],
# [0, 0, 2]])
希尔伯特矩阵
H = hilb(n) 返回阶数为n的希尔伯特矩阵.希尔伯特矩阵是病态矩阵的典型示例.希尔伯特矩阵的元素由 H(i,j) = 1/(i + j – 1) 指定.
n — 矩阵的阶次, 非负整数标量,
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def hilb_type_matrix(input_str):
try:
# 使用 sympy 的 sympify 函数将输入的字符串转换为 sympy 表达式
expr = sp.sympify(input_str)
# 初始化错误标志为 False,表示没有错误
error = False
# 初始化结果变量为 None
result = None
def hilbert_matrix(n):
"""
创建一个 n x n 的希尔伯特矩阵。
希尔伯特矩阵的元素 H[i, j] 定义为 1 / (i + j + 1),其中 i 和 j 是矩阵的行和列索引(从 0 开始)。
参数:
n (int): 矩阵的阶数
返回:
np.ndarray: 一个 n x n 的希尔伯特矩阵
"""
# 创建一个 n x n 的零矩阵
H = np.zeros((n, n))
# 遍历矩阵的每一行
for i in range(n):
# 遍历矩阵的每一列
for j in range(n):
# 计算希尔伯特矩阵的元素值
H[i, j] = 1 / (i + j + 1)
return H
# 检查解析后的表达式是否为元组
if isinstance(expr, tuple):
# 如果是元组,将错误标志设置为 True
error = True
# 检查解析后的表达式是否为整数
elif expr.is_integer:
# 如果是整数,调用 hilbert_matrix 函数生成希尔伯特矩阵
result = hilbert_matrix(int(expr))
else:
# 如果既不是元组也不是整数,将错误标志设置为 True
error = True
# 如果没有错误,将结果转换为 sympy 矩阵并返回
return sp.Matrix(result) if not error else f"输入错误: {input_str}"
except Exception as e:
# 如果在处理过程中出现异常,返回错误信息
return f"错误:{e}"
print(hilb_type_matrix("4"))
# Matrix([[1.00000000000000, 0.500000000000000, 0.333333333333333, 0.250000000000000],
# [0.500000000000000, 0.333333333333333, 0.250000000000000, 0.200000000000000],
# [0.333333333333333, 0.250000000000000, 0.200000000000000, 0.166666666666667],
# [0.250000000000000, 0.200000000000000, 0.166666666666667, 0.142857142857143]])
直方图箱计数
[N, edges] = histcounts(X)将X值划分为bin, 并返回bin计数和bin边. histcounts函数使用自动分箱算法,, 该算法返回选择的均匀分箱, 以覆盖X中的元素范围, 并揭示分布的潜在形状.
[N, edges] = histcounts(X, nbins)使用标量nbins指定的多个容器.
[N, edges] = histcounts(X. edges)将X排序到具有向量edges指定的bin边的bin中.
X —— 要在各个存储箱之间分配的数据, 向量, 矩阵
nbins —— 箱数, 正整数, 指定为正整数的容器数. 如果不指定nbins, 则histcounts会根据X中的值自动计算要使用的箱数.
edges —— Bin边, 矢量, 指定为向量. 第一个向量元素指定第一个bin的前缘, 最后一个元素指定最后一个bin的后缘. 后缘仅包含在最后一个bin中.
示例1. 统计学与数据分析
正态分布数据:
normal_data = list(np.random.normal(0, 1, 1000))
result1 = histcounts(normal_data)
print(f"计数: {result1[0][:10]}...") # 只显示前10个
print(f"边界: {result1[1][:5]}...") # 只显示前5个边界
#计数: [1, 10, 36, 85, 186, 241, 226, 147, 49, 19]...
#边界: [-3.6945630626203694, -3.0571194676833393, -2.419675872746309, -1.7822322778092785, -1.1447886828722482]...
指定bin数量
result1b = histcounts(normal_data, 20)
print(f"\n使用20个bins: {len(result1b[0])}个区间")
#使用20个bins: 20个区间
示例2. 金融收益率分布
模拟股票收益率(正态分布,但可能有厚尾)
returns = list(np.random.normal(0.001, 0.02, 500)) # 日收益率 ~ N(0.1%, 2%)
result2 = histcounts(returns, [-0.1, -0.05, -0.02, -0.01, 0, 0.01, 0.02, 0.05, 0.1])
print(f"收益率分布: {result2}")
#收益率分布: ([2, 63, 76, 99, 84, 81, 93, 2], [-0.1, -0.05, -0.02, -0.01, 0.0, 0.01, 0.02, 0.05, 0.1])
示例3. 质量控制与工程
零件尺寸测量
part_sizes = list(np.random.normal(10.0, 0.1, 200)) # 目标尺寸10.0mm,标准差0.1mm
tolerance_limits = [9.7, 9.8, 9.9, 10.0, 10.1, 10.2, 10.3]
result3 = histcounts(part_sizes, tolerance_limits})
print(f"零件尺寸分布: {result3}")
#零件尺寸分布: ([6, 26, 64, 67, 29, 5], [9.7, 9.8, 9.9, 10.0, 10.1, 10.2, 10.3])
示例4. 医学与生物统计学
血压数据分布
blood_pressure = list(np.random.normal(120, 15, 300)) # 收缩压
bp_bins = [80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180]
result4 = histcounts(blood_pressure, bp_bins)
print(f"血压分布: {result4}")
#血压分布: ([3, 22, 45, 81, 64, 50, 31, 1, 1, 0], [80.0, 90.0, 100.0, 110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0])
示例5. 环境监测数据
温度数据(季节性变化)
temperatures = list(np.concatenate([
np.random.normal(15, 5, 100), # 春季
np.random.normal(25, 3, 100), # 夏季
np.random.normal(10, 4, 100), # 秋季
np.random.normal(-5, 8, 100) # 冬季
]))
temp_bins = list(range(-20, 41, 5)) # 从-20°C到40°C,每5°C一个区间
result5 = histcounts(temperatures, temp_bins)
print(f"温度分布: {result5}")
#温度分布: ([6, 14, 23, 28, 30, 54, 62, 60, 50, 67, 2, 0], [-20.0, -15.0, -10.0, -5.0, 0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0])
示例6. 计算机系统性能分析
响应时间分布(通常是指数分布)
response_times = list(np.random.exponential(0.1, 500)) # 平均响应时间0.1秒
rt_bins = [0, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0]
result6 = histcounts(response_times, rt_bins)
print(f"响应时间分布: {result6}")
#响应时间分布: ([36, 42, 99, 124, 125, 72, 2, 0], [0.0, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0])
示例7. 社会科学调查数据
年龄分布(多峰分布)
ages = list(np.concatenate([
np.random.normal(25, 5, 150), # 年轻人群
np.random.normal(45, 8, 200), # 中年人群
np.random.normal(65, 10, 100) # 老年人群
]))
age_bins = list(range(0, 101, 10)) # 每10岁一个区间
result7 = histcounts(ages, age_bins)
print(f"年龄分布: {result7}")
#年龄分布: ([1, 21, 118, 70, 101, 67, 44, 19, 6, 3], [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0])
示例8. 学生成绩分析
考试成绩(偏态分布)
scores = list(np.random.beta(2, 5, 300) * 100) # 偏向左的分布
score_bins = [0, 20, 40, 60, 70, 80, 90, 100]
result8 = histcounts(scores, score_bins)
print(f"成绩分布: {result8}")
#成绩分布: ([92, 132, 60, 10, 6, 0, 0], [0.0, 20.0, 40.0, 60.0, 70.0, 80.0, 90.0, 100.0])
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import numpy as np
import sympy as sp
def histogram_counts(input_str):
"""
对标MATLAB的histcounts函数,计算直方图的bin计数和边界。
参数:
input_str (str): 输入字符串,应为可解析为数值数据及bins参数的Python字面量。
返回:
tuple or str: 成功时返回(计数列表, 边界列表),失败时返回错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
data = None
bins_arg = None
if isinstance(expr, tuple) and len(expr) == 2:
if isinstance(expr[0], list):
data = np.array(expr[0], dtype=float).ravel()
bins_arg = expr[1]
else:
error = True
elif isinstance(expr, list):
data = np.array(expr, dtype=float).ravel()
else:
error = True
# 处理bins参数
if bins_arg is not None:
if isinstance(bins_arg, (list, tuple, np.ndarray)):
bins = np.array(bins_arg, dtype=float)
elif bins_arg.is_number:
bins = int(bins_arg)
else:
return f"bins参数类型错误: {type(bins_arg)}"
N, edges = np.histogram(data, bins=bins)
else:
N, edges = np.histogram(data)
return list(N), list(edges) if not error else f"输入错误: {input_str}"
except SyntaxError:
return f"语法错误: 无法解析输入 {input_str}"
except ValueError as ve:
return f"数值错误: {str(ve)}"
except Exception as e:
return f"错误: {str(e)}"
# 基本使用
print(histogram_counts("[1, 2, 3, 4]"))
# ([1, 0, 0, 1, 0, 0, 1, 0, 0, 1], [1.0, 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.6999999999999997, 4.0])
# 指定bin数量
print(histogram_counts("([1,2,3,4,5], 2)"))
# ([2, 3], [1.0, 3.0, 5.0])
# 指定bin边界
print(histogram_counts("([1,2,3,4], [0, 2.5, 5])"))
# ([2, 2], [0.0, 2.5, 5.0])
二元直方图bin计数
[N,Xedges,Yedges] = histcounts2(X,Y)将X和Y中的值划分为多个二维bin, 并返回bin计数以及每个维度的bin边界. histcounts2函数使用自动分bin算法, 然后返回均匀bin, 这些bin可涵盖X和Y中值的范围并显示分布的基本形状.
[N,Xedges,Yedges] = histcounts2(X,Y,nbins) 指定要在每个维度中使用的 bin 数量.
[N,Xedges,Yedges] = histcounts2(X,Y,Xedges,Yedges) 按照 Xedges 和 Yedges 指定的 bin 边界, 将 X 和 Y 划分为多个 bin.
X,Y — 要分布到各 bin 的数据(以单独参量指定),向量, 矩阵
nbins — 每个维度中的 bin 数量, 正整数标量, 由正整数组成的二元素向量
Xedges — x 维度中的 bin 边界, 向量
Yedges — y 维度中的 bin 边界, 向量
N — bin 计数, 数组
Xedges — x 维度中的 bin 边界, 向量
Yedges — y 维度中的 bin 边界, 向量
示例1. 金融数据分析 - 股票收益率与波动率
生成模拟数据:正收益通常伴随低波动,负收益伴随高波动
np.random.seed(42)
returns = np.concatenate([
np.random.normal(0.02, 0.01, 300), # 正收益,低波动
np.random.normal(-0.01, 0.03, 200) # 负收益,高波动
])
volatility = np.concatenate([
np.random.normal(0.15, 0.02, 300), # 低波动
np.random.normal(0.25, 0.05, 200) # 高波动
])
result1 = histcounts2(returns, volatility, 10)
print(f"收益率-波动率联合分布形状: {np.array(result1[0]).shape}")
#收益率-波动率联合分布形状: (10, 10)
#可用于分析风险-收益关系
示例2. 医学研究 - 身高体重指数(BMI)分析
生成身高体重数据(正相关)
heights = np.random.normal(170, 10, 1000) # 身高 cm
weights = 0.8 * heights - 100 + np.random.normal(0, 8, 1000) # 体重 kg
height_bins = list(range(140, 201, 5)) # 140-200cm,每5cm一个区间
weight_bins = list(range(40, 121, 5)) # 40-120kg,每5kg一个区间
result2 = histcounts2(heights, weights, height_bins, weight_bins)
print(f"身高体重联合分布: {len(result2[1]) - 1}x{len(result2[2]) - 1} 个区间")
#身高体重联合分布: 12x16 个区间
示例3. 环境科学 - 温度与湿度的关系
温度湿度通常呈负相关(高温低湿,低温高湿)
temperatures = np.random.uniform(10, 35, 500)
humidity = 80 - 1.5 * temperatures + np.random.normal(0, 10, 500)
humidity = np.clip(humidity, 20, 100) # 限制湿度范围
result3 = histcounts2(temperatures, humidity, 8)
print(f"温度-湿度联合分布: {np.array(result3[0]).shape}")
#温度-湿度联合分布: (8, 8)
示例4. 市场营销 - 客户年龄与消费金额
不同年龄段的消费模式
ages = np.concatenate([
np.random.normal(25, 5, 200), # 年轻人,中等消费
np.random.normal(45, 8, 300), # 中年人,高消费
np.random.normal(65, 10, 150) # 老年人,低消费
])
spending = np.concatenate([
np.random.normal(500, 100, 200), # 年轻人
np.random.normal(800, 150, 300), # 中年人
np.random.normal(300, 80, 150) # 老年人
])
age_bins = [18, 25, 35, 45, 55, 65, 75]
spending_bins = [0, 200, 400, 600, 800, 1000, 1200]
result4 = histcounts2(ages, spending, age_bins, spending_bins)
print(f"客户年龄-消费金额分布: {len(result4[1]) - 1}x{len(result4[2]) - 1} 个区间")
#客户年龄-消费金额分布: 6x6 个区间
示例5. 工业质量控制 - 零件尺寸相关性
两个相关尺寸的测量数据
diameter = np.random.normal(50.0, 0.1, 300)
length = 2.0 * diameter + np.random.normal(0, 0.05, 300) # 长度与直径相关
result5 = histcounts2(diameter, length, 6)
print(f"直径-长度联合分布: {np.array(result5[0]).shape}")
#直径-长度联合分布: (6, 6)
#可用于检测制造过程的一致性
示例6. 教育研究 - 数学与物理成绩的关系
math_scores = np.random.normal(75, 15, 400)
physics_scores = 0.8 * math_scores + np.random.normal(0, 8, 400) # 物理与数学正相关
score_bins = list(range(0, 101, 10))
result6 = histcounts2(math_scores, physics_scores, score_bins, score_bins)
print(f"数学-物理成绩联合分布: {len(result6[1]) - 1}x{len(result6[2]) - 1} 个区间")
#数学-物理成绩联合分布: 10x10 个区间
示例7. 气象学 - 风速与风向的关系
模拟不同风向的风速分布
directions = np.random.uniform(0, 360, 600) # 风向 0-360度
speeds = 5 + 3 * np.abs(np.sin(np.radians(directions))) + np.random.normal(0, 1, 600) # 特定风向风速较高
dir_bins = list(range(0, 361, 45)) # 8个方向
speed_bins = [0, 2, 4, 6, 8, 10, 12, 14, 16]
result7 = histcounts2(directions, speeds, dir_bins, speed_bins)
print(f"风向-风速联合分布: {len(result7[1]) - 1}x{len(result7[2]) - 1} 个区间")
#风向-风速联合分布: 8x8 个区间
示例8. 计算机科学 - CPU使用率与内存使用率
cpu_usage = np.random.beta(2, 5, 500) * 100 # 偏态分布
memory_usage = 0.6 * cpu_usage + np.random.normal(0, 10, 500) # 与CPU相关但更分散
usage_bins = list(range(0, 101, 10))
result8 = histcounts2(cpu_usage, memory_usage, usage_bins, usage_bins)
print(f"CPU-内存使用率联合分布: {len(result8[1]) - 1}x{len(result8[2]) - 1} 个区间")
#CPU-内存使用率联合分布: 10x10 个区间
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def histogram_counts_second(input_str):
"""
对标MATLAB histcounts2的二元直方图计数函数
参数:
input_str (str): SymPy可解析的字符串,格式为:
(1) (X, Y)
(2) (X, Y, bins)
(3) (X, Y, Xedges, Yedges)
返回:
(Matrix(N), Xedges, Yedges) 或 错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查是否为包含两个矩阵的元组
if isinstance(expr, tuple) and isinstance(expr[0], list) and isinstance(expr[1], list):
# 转换输入数据为numpy数组
x = expr[0]
y = expr[1]
X = np.ravel(np.array(x, dtype=float))
Y = np.ravel(np.array(y, dtype=float))
# 参数解析逻辑
if len(expr) >= 4: # 处理(X, Y, Xedges, Yedges)情况
if isinstance(expr[2], list) and isinstance(expr[3], list):
x_edges = expr[2]
y_edges = expr[3]
bins = [
np.ravel(np.array(x_edges, dtype=float)),
np.ravel(np.array(y_edges, dtype=float))
]
N, Xe, Ye = np.histogram2d(X, Y, bins=bins)
result = (sp.Matrix(N), list(Xe), list(Ye))
else:
error = True
elif len(expr) == 3: # 处理bins参数
bins_arg = expr[2]
# 处理整数型bins
if isinstance(bins_arg, sp.Number) and bins_arg.is_integer:
N, Xe, Ye = np.histogram2d(X, Y, bins=int(bins_arg))
# 处理列表/矩阵型bins
elif isinstance(bins_arg, list):
bins_mat = bins_arg
bins = np.array(bins_mat)
N, Xe, Ye = np.histogram2d(X, Y, bins=bins)
else:
error = True
result = (sp.Matrix(N), list(Xe), list(Ye)) if not error else None
else: # 默认情况
N, Xe, Ye = np.histogram2d(X, Y)
result = (sp.Matrix(N), list(Xe), list(Ye))
else:
error = True
return result if not error else f"输入格式错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
# 案例1:基本使用
print(histogram_counts_second("([1,2,3], [4,5,6])"))
# (Matrix([
# [1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0]]),
#
# [1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4000000000000004, 2.6, 2.8, 3.0],
# [4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0])
# 案例2:指定整数bins
print(histogram_counts_second("[1,1,2,3,2,2,1,1,2,3],[5,6,3,8,9,1,2,7,5,1],8"))
# (Matrix([
# [ 0, 1.0, 0, 0, 1.0, 1.0, 1.0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0],
# [1.0, 0, 1.0, 0, 1.0, 0, 0, 1.0],
# [ 0, 0, 0, 0, 0, 0, 0, 0],
# [ 0, 0, 0, 0, 0, 0, 0, 0],
# [1.0, 0, 0, 0, 0, 0, 0, 1.0]]),
#
# [1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0],
# [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])
# 案例3:指定二维bins
print(histogram_counts_second("([1,2,3], [4,5,6], [2,3])"))
# (Matrix([[1.0, 0, 0],
# [ 0, 1.0, 1.0]]),
#
# [1.0, 2.0, 3.0], [4.0, 4.666666666666667, 5.333333333333333, 6.0])
# 案例4:直接指定边界
print(histogram_counts_second("([1,2,3], [4,5,6], [0,2,4], [3,5,7])"))
# (Matrix([[1.0, 0],
# [ 0, 2.0]]),
#
# [0.0, 2.0, 4.0],
# [3.0, 5.0, 7.0])
直方图
直方图是一种条形图, 它将数据分组为bin. 创建Histogram对象后, 可以通过更改直方图的属性值修改它的各个方面. 这对快速修改bin属性或更改显示特别有用
HistogramPlot(X) 基于X创建直方图. histogram函数使用自动分bin算法, 然后返回均匀宽度的bin, 这些bin可涵盖 X 中的元素范围并显示分布的基本形状. histogram将bin显示为矩形条, 这样每个矩形的高度就表示bin中的元素数量.
HistogramPlot(X,nbins)指定bin的数量.
HistogramPlot(X,edges) 将X划分为在向量中指定bin边界的bin.
X — 要分布到各 bin 的数据, 向量, 矩阵
nbins — bin 数量, 正整数
edges — bin 边界, 向量
电商用户消费金额分析: 分析双11期间用户的单笔订单金额分布
HistogramPlot([89,120,150,199,210,299,320,399,450,499,520,599,620,799,850,999,1200,1500],[0,200,400,600,800,1000,2000])
工厂零件尺寸质检: 检测流水线生产的螺栓直径(标准值10.0±0.2mm)
HistogramPlot([9.7,9.8,9.85,9.9,9.95,10.0,10.0,10.05,10.1,10.1,10.15,10.2,10.2,10.25,10.3,10.4],8)
APP用户活跃时长分析: 统计每日用户使用时长(分钟)
HistogramPlot([2,5,8,10,12,15,15,18,20,25,30,35,40,45,50,60,75,90,120],[0,1,5,15,30,60,180])
医院患者年龄分布: 某科室疾病患者的年龄分布
HistogramPlot([32,35,38,40,42,45,48,50,52,55,58,60,62,65,68,70,72,75,80,85],[30,40,50,60,70,90])
网络请求响应时间监控: API接口的响应时间(毫秒)
HistogramPlot([12,15,18,20,22,25,28,30,35,40,45,50,60,75,100,150,200,500],[10,20,50,100,200,1000])
二元直方图
二元直方图是一种数值数据条形图, 它将数据分组到二维bin中. 创建Histogram2Plot对象后, 可以通过更改直方图的属性值修改它的各个方面. 这对快速修改bin属性或更改显示特别有用
histogram2Plot(X,Y) 创建 X 和 Y 的二元直方图. histogram2 函数使用自动分 bin 算法, 然后返回均匀面积的 bin, 这些 bin 可涵盖 X 和 Y 中的元素范围并显示分布的基本形状. histogram2 将 bin 显示为二维矩形条形,这样每个条形的高度就表示 bin 中的元素数量.
histogram2Plot(X,Y,nbins) 指定要在每个维度中使用的 bin 数量.
X,Y — 要分布到各 bin 的数据, 向量, 矩阵
nbins — bin 数量, 正整数
身高体重关系(健康数据分析):
深色区域显示最常见的身高体重组合(如170cm/65kg),右上角稀疏区可能是异常值
Histogram2Plot([165,170,178,162,185], # 身高(cm)
[55,68,72,60,80], # 体重(kg)
12)
广告点击分析(数字营销):
观看时长8-15秒且点击率1-2%的区域密度最高,短时长(<5s)点击率波动大
Histogram2Plot([12,8,25,3,17], # 广告观看时长(秒)
[0.2,1.5,0.8,3.2,1.6], # 点击率(%)
10)
气象模式分析(气候科学):
高温(>30℃)与低降雨(<2mm)强相关,25℃中温区降雨分布最广
Histogram2Plot([28,32,25,30], # 日间温度(℃)
[0,5.2,12.8,3.4], # 降雨量(mm)
15)
股票收益率分析(金融量化):
高波动率(>0.2)时收益率分布更分散,低波动率时收益率集中在±5%
Histogram2Plot([0.15,0.22,0.08], # 波动率
[-0.03,0.12,0.05], # 日收益率
20)
城市通勤研究(交通规划):
10km/25min区域密度最高,20km以上出现明显的交通效率下降
Histogram2Plot([8,15,5,20], # 通勤距离(km)
[30,45,20,60], # 通勤时间(分钟)
12)
霍纳法则(秦九韶算法)
把表达式转成嵌套形式,提高计算效率.
horner(p)返回多项式p的霍纳形式,
horner(p,var)使用var中的变量.
p是符号表达式,符号函数,符号表达式数组,符号函数数组.
var是变量,符号变量,符号变量数组.
示例1:数值计算优化 - 减少乘法次数
print(horner(3*x^4 + 5*x^3 - 2*x^2 + 7*x + 1))
# 输出: x*(x*(x*(3*x + 5) - 2) + 7) + 1
# 原始需要10次乘法,霍纳形式只需4次乘法
示例2:多项式插值
print(horner(2*x^3 - 3*x^2 + 4*x - 5))
# 输出: x*(x*(2*x - 3) + 4) - 5
示例3:控制系统中的传递函数
print(horner(s^3 + 2*s^2 + 3*s + 4))
# 输出: s*(s*(s + 2) + 3) + 4
示例4:矩阵多项式 - 在数值线性代数中常见
matrix_poly = [[x^3 + 2*x^2 + x + 1, x^2 + 3*x + 2], [4*x^3 - x^2 + 2*x, x^4 + x + 1]]
result = horner(matrix_poly)
print(result)
# 输出: [[x*(x*(x + 2) + 1) + 1, x*(x + 3) + 2],
[x*(x*(4*x - 1) + 2), x*(x^3 + 1) + 1]]
示例5:多元多项式 - 指定变量
print(horner((x*y^3 + 2*x*y^2 + 3*x*y + 4*x, y)))
# 输出: 4*x + y*(3*x + y*(x*y + 2*x))
示例6:多元多项式(指定变量x)
print(horner((x^3*y + 2*x^2*y + 3*x*y + 4*y, x)))
# 输出: x*(x*(x*y + 2*y) + 3*y) + 4*y
示例7:高次多项式 - 计算效率提升明显
print(horner(x^5 + 4*x^4 + 6*x^3 + 4*x^2 + x + 1))
# 输出: x*(x*(x*(x*(x + 4) + 6) + 4) + 1) + 1
示例8:特征多项式
print(horner(x^3 - 6*x^2 + 11*x - 6))
# 输出: x*(x*(x - 6) + 11) - 6
示例9:数值稳定性测试(接近零的系数)
print(horner(x^4 + 0.001*x^3 + 0.0001*x^2 + x + 1))
# 输出: x*(x*(x*(1.0*x + 0.001) + 0.0001) + 1.0) + 1.0
示例10:复杂矩阵表达式
complex_matrix = [[x^2 + y*x + y^2, x^3 + 2*x*y], [x + y^2, x^2*y + x + 1]]
print(horner(complex_matrix, y))
#输出: [[x^2 + y*(x + y), x^3 + 2*x*y],
[x + y^2, x^2*y + x + 1]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.matrices import MatrixBase, MutableDenseMatrix
from sympy.polys.polyfuncs import horner
def horner_nested_polynomial(input_str):
"""
将输入的多项式或矩阵中的每个元素转换为霍纳嵌套形式。
参数:
input_str: 字符串,表示SymPy可解析的表达式。可以是多项式、矩阵或元组(矩阵或表达式,变量)。
返回:
SymPy表达式或矩阵,表示霍纳形式的多项式。若输入错误则返回错误信息。
示例:
>>> x, y = sp.symbols('x y')
>>> horner_nested_polynomial("x**3 + 2*x**2 + 3*x +4")
x*(x*(x + 2) + 3) + 4
>>> horner_nested_polynomial("[[x**3, x**2 + 2*x], [x+1, 5]]")
Matrix([
[ x**3, x*(x + 2)],
[ x + 1, 5]])
>>> horner_nested_polynomial("(x**2 + x*y + y**2, y)")
y*(x + y) + x**2
>>> horner_nested_polynomial("([[x**3 + y*x, x + y]], y)")
Matrix([[x*y + x**3, x + y]])
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def eval_horner(expression, wrt_var=None):
"""内部函数:应用霍纳法则到单个表达式"""
if wrt_var is not None:
poly = sp.poly(expression, wrt_var)
else:
poly = sp.poly(expression)
return horner(poly, wrt=wrt_var)
# 处理元组输入(表达式/矩阵,变量)
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.free_symbols for e in expr):
result = eval_horner(*expr)
else:
error = True
elif expr.free_symbols:
# 处理普通表达式
result = eval_horner(expr)
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例测试
if __name__ == "__main__":
print(horner_nested_polynomial("9*x**4+8*x**3+7*x**2+6*x+5"))
# x*(x*(x*(9*x + 8) + 7) + 6) + 5
希尔伯特变换
H = htrans(f) 返回符号函数 f 的希尔伯特变换. 默认情况下, 独立变量为 t, 变换变量为 x.
f — 输入, 符号表达式, 符号函数
示例1: 正弦信号 - 基本测试
result = htrans(sin(t))
t_vals, H, y = result
plt.figure(figsize=(12, 8))
plt.subplot(2, 3, 1)
plt.plot(t_vals, y, 'b-', label='Original: sin(t)')
plt.plot(t_vals, H, 'r--', label='Hilbert: -cos(t)')
plt.plot(t_vals, -np.cos(t_vals), 'g:', label='Theoretical: -cos(t)')
plt.legend()
plt.title('正弦信号')
plt.grid(True)
示例2: 余弦信号
result = htrans(cos(t))
t_vals, H, y = result
plt.subplot(2, 3, 2)
plt.plot(t_vals, y, 'b-', label='Original: cos(t)')
plt.plot(t_vals, H, 'r--', label='Hilbert: sin(t)')
plt.plot(t_vals, np.sin(t_vals), 'g:', label='Theoretical: sin(t)')
plt.legend()
plt.title('余弦信号')
plt.grid(True)
示例3: 调幅信号 (AM信号)
result = htrans((1+0.5*cos(2*t))*cos(10*t))
t_vals, H, y = result
plt.subplot(2, 3, 3)
plt.plot(t_vals, y, 'b-', label='AM Signal')
plt.plot(t_vals, H, 'r--', label='Hilbert Transform')
plt.legend()
plt.title('调幅信号')
plt.grid(True)
# 计算包络
envelope = np.abs(signal.hilbert(y))
plt.plot(t_vals, envelope, 'g-', linewidth=2, label='Envelope')
plt.plot(t_vals, -envelope, 'g-', linewidth=2)
示例4: 调频信号 (FM信号)
result = htrans(cos(10*t + 2*sin(2*t)))
t_vals, H, y = result
plt.subplot(2, 3, 4)
plt.plot(t_vals, y, 'b-', label='FM Signal')
plt.plot(t_vals, H, 'r--', label='Hilbert Transform')
plt.legend()
plt.title('调频信号')
plt.grid(True)
示例5: 脉冲信号 (矩形脉冲)
创建一个矩形脉冲
t_vals = np.linspace(0, 2 * np.pi, 1000)
y_rect = np.where((t_vals > np.pi / 2) & (t_vals < 3 * np.pi / 2), 1, 0)
H_rect = np.imag(signal.hilbert(y_rect))
plt.subplot(2, 3, 5)
plt.plot(t_vals, y_rect, 'b-', label='Rectangular Pulse')
plt.plot(t_vals, H_rect, 'r--', label='Hilbert Transform')
plt.legend()
plt.title('矩形脉冲')
plt.grid(True)
示例6: 多频信号
result = htrans(sin(t) + 0.5*sin(3*t))
t_vals, H, y = result
plt.subplot(2, 3, 6)
plt.plot(t_vals, y, 'b-', label='Multi-frequency')
plt.plot(t_vals, H, 'r--', label='Hilbert Transform')
plt.legend()
plt.title('多频信号')
plt.grid(True)
plt.tight_layout()
plt.show()
示例7: 解析信号和瞬时频率计算
result = htrans(cos(5*t + sin(2*t))) # FM信号
t_vals, H, y = result
analytic_signal = signal.hilbert(y)
# 计算瞬时幅度(包络)
instantaneous_amplitude = np.abs(analytic_signal)
# 计算瞬时相位
instantaneous_phase = np.unwrap(np.angle(analytic_signal))
# 计算瞬时频率
instantaneous_frequency = (np.diff(instantaneous_phase) /
(2.0 * np.pi * (t_vals[1] - t_vals[0])))
plt.figure(figsize=(15, 10))
plt.subplot(3, 1, 1)
plt.plot(t_vals, y, 'b-', label='Original Signal')
plt.plot(t_vals, instantaneous_amplitude, 'r--', label='Instantaneous Amplitude')
plt.legend()
plt.title('信号和瞬时包络')
plt.grid(True)
plt.subplot(3, 1, 2)
plt.plot(t_vals, instantaneous_phase, 'g-')
plt.title('瞬时相位')
plt.grid(True)
plt.subplot(3, 1, 3)
plt.plot(t_vals[:-1], instantaneous_frequency, 'm-')
plt.title('瞬时频率')
plt.xlabel('Time')
plt.grid(True)
plt.tight_layout()
plt.show()
示例8: 单边带调制 (SSB)
基带信号
baseband_freq = 2
carrier_freq = 20
t_vals = np.linspace(0, 2 * np.pi, 1000)
baseband_signal = np.cos(baseband_freq * t_vals)
carrier = np.cos(carrier_freq * t_vals)
生成解析信号(单边带)
analytic_baseband = signal.hilbert(baseband_signal)
ssb_signal = np.real(analytic_baseband * np.exp(1j * carrier_freq * t_vals))
plt.figure(figsize=(12, 8))
plt.subplot(3, 1, 1)
plt.plot(t_vals, baseband_signal)
plt.title('基带信号')
plt.grid(True)
plt.subplot(3, 1, 2)
plt.plot(t_vals, ssb_signal)
plt.title('单边带调制信号')
plt.grid(True)
# 频谱分析
from scipy.fft import fft, fftfreq
plt.subplot(3, 1, 3)
fft_ssb = fft(ssb_signal)
freqs = fftfreq(len(ssb_signal), t_vals[1] - t_vals[0])
plt.plot(freqs[:len(freqs) // 2], np.abs(fft_ssb[:len(fft_ssb) // 2]))
plt.title('单边带信号频谱')
plt.xlabel('Frequency (Hz)')
plt.grid(True)
plt.tight_layout()
plt.show()
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import scipy.signal as signal
import matplotlib.pyplot as plt
def hilbert_transform_func(input_str):
"""
对标MATLAB的htrans函数,计算输入表达式的数值希尔伯特变换。
参数:
input_str (str): 以't'为变量的数学表达式,例如'sin(t)'、'exp(t)*cos(t)'等。
返回:
tuple: (t_values, H_values) 包含时间序列和对应的希尔伯特变换数值结果。
或 str: 错误信息。
"""
try:
# 步骤1: 将输入字符串转换为SymPy表达式
expr = sp.sympify(input_str)
t = sp.symbols('t')
# 步骤2: 检查表达式是否含有符号't',若无则报错
if not expr.has(t):
return f"错误: 表达式必须包含变量't',但输入为'{expr}'"
# 步骤3: 替换所有其他符号为1(例如,处理如'a*sin(t)'中的'a')
free_symbols = expr.free_symbols - {t}
subs_dict = {symbol: 1 for symbol in free_symbols}
expr_substituted = expr.subs(subs_dict)
# 步骤4: 将SymPy表达式转换为NumPy函数
expr_numpy = sp.lambdify(t, expr_substituted, modules='numpy')
# 步骤5: 生成时间序列(0到2π,1000个点)
t_vals = np.linspace(0, 2 * np.pi, 1000)
# 步骤6: 计算原始信号y(t)
y = expr_numpy(t_vals)
# 步骤7: 使用SciPy计算希尔伯特变换(注意:返回的是解析信号,虚部为Hilbert变换)
analytic_signal = signal.hilbert(y)
H = np.imag(analytic_signal)
return (t_vals, H, y) # 同时返回原始信号用于比较
except sp.SympifyError:
return f"错误: 无法解析输入表达式 '{input_str}'"
except Exception as e:
return f"错误: {str(e)}"
# 示例使用
if __name__ == "__main__":
# 示例1: 计算sin(t)的希尔伯特变换(理论值为-cos(t))
input_expr = "sin(t)"
result = hilbert_transform_func(input_expr)
if isinstance(result, tuple):
import matplotlib.pyplot as plt
t_vals, H, y = result
plt.figure(figsize=(10, 6))
plt.plot(t_vals, H, '--', label='Computed Hilbert')
plt.xlabel('t')
plt.legend()
plt.title('Hilbert Transform Demo')
plt.show()
else:
print(result)
赫尔维茨黎曼函数
Z=Hurwitz-zeta(s,a)为数字或符号输入s和a计算Hurwitz zeta函数.只有当s不为1且a既不是0也不是负整数时,才定义Hurwitz zeta函数.
Z=hurwitzZeta(n,s,a)返回参照变量s的n阶hurwitz-zeta(s,a)的导数.
s是数字,数组,符号数,符号变量,符号函数,符号表达式,符号数组.
a是数字,数组,符号数,符号变量,符号函数,符号表达式,符号数组.
n是导数的阶数,非负整数.
示例1: 黎曼ζ函数(特殊情况)
print("ζ(2) =", hurwitzZeta(2, 1)
print("ζ(4) =", hurwitzZeta(4, 1)
print("ζ(0) =", hurwitzZeta(0, 1)
#ζ(2) = 1.6449340668482264
#ζ(4) = 1.0823232337111381
#ζ(0) = -0.5
示例2: 狄利克雷级数
print("ζ(2, 0.5) =", hurwitzZeta(2, 0.5)
print("ζ(3, 0.25) =", hurwitzZeta(3, 0.25)
#ζ(2, 0.5) = 4.934802200544679
#ζ(3, 0.25) = 64.66386996876847
示例3: 导数计算
print("ζ''(2, 1) =", hurwitzZeta(2, 1, 2)
#ζ''(2, 1) = oo
示例4: 数值数组计算
s_values = [2, 3, 4]
a_values = [0.5, 1.0, 1.5]
for s in s_values:
for a in a_values:
result = hurwitzZeta(s, a)
print(f"ζ({s}, {a}) = {result}")
#ζ(2, 0.5) = 4.934802200544679
#ζ(2, 1.0) = 1.6449340668482264
#ζ(2, 1.5) = 0.9348022005446793
#ζ(3, 0.5) = 8.41439832211716
#ζ(3, 1.0) = 1.2020569031595942
#ζ(3, 1.5) = 0.41439832211716
#ζ(4, 0.5) = 16.234848505667074
#ζ(4, 1.0) = 1.0823232337111381
#ζ(4, 1.5) = 0.23484850566707288
示例5: 在数论中的应用 - 狄利克特征
L(s, χ) = ∑ χ(n)/n^s 可以用Hurwitz ζ函数表示
def dirichlet_L(s, chi, modulus):
"""使用Hurwitz ζ函数计算狄利克雷L函数"""
result = 0
for a in range(1, modulus + 1):
if chi(a) != 0:
result += chi(a) * hurwitzZeta(s, a / modulus)
return result / (modulus ** s)
# 定义模4的特征
def chi_mod4(n):
if n % 4 == 1:
return 1
elif n % 4 == 3:
return -1
else:
return 0
L_value = dirichlet_L(1, chi_mod4, 4)
print(f"L(1, χ) = {L_value}")
#L(1, χ) = nan
示例6: 在物理学中的应用- 玻色-爱因斯坦统计:
在理想玻色气体中,粒子数密度与ζ(3/2)相关
zeta_3_2 = hurwitzZeta(1.5, 1)
print(f"ζ(3/2) = {zeta_3_2}")
#ζ(3/2) = 2.612375348685488
#这个值出现在玻色-爱因斯坦凝聚的临界温度公式中
示例7: 在概率论中的应用 - Zipf分布
Zipf分布的归一化常数与ζ函数相关
def zipf_constant(s, N):
"""计算Zipf分布的归一化常数"""
return 1.0 / abs(hurwitzZeta(s, 1)
s_zipf = 2.0
norm_const = zipf_constant(s_zipf, 100)
print(f"Zipf分布(s={s_zipf})的归一化常数: {norm_const}")
#Zipf分布(s=2.0)的归一化常数: 0.6079271018540267
示例8: 解析延拓
计算s<1时的ζ函数值(通过解析延拓)
negative_s = [-1, -2, -3]
for s in negative_s:
result = hurwitzZeta(s, 1)
print(f"ζ({s}) = {result}")
# 这些值与伯努利数相关
#ζ(-1) = -0.08333333333333333
#ζ(-2) = 0
#ζ(-3) = 0.008333333333333333
示例9: 特殊函数关系
ζ(s, a) 与多伽玛函数的关系
from mpmath import polygamma
s_poly = 3
a_poly = 0.5
zeta_val = hurwitzZeta(s_poly, a_poly)
polygamma_val = (-1) ** s_poly * polygamma(s_poly - 1, a_poly) / factorial(s_poly - 1)
print(f"ζ({s_poly}, {a_poly}) = {zeta_val}")
print(f"通过多伽玛函数: {polygamma_val}")
#ζ(3, 0.5) = 8.41439832211716
#通过多伽玛函数: 8.41439832211716
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from mpmath import zeta as mp_zeta
def hurwitz_zeta_function(input_expr):
"""
对标MATLAB的hurwitzZeta函数,计算Hurwitz zeta函数或其导数。
Hurwitz zeta函数定义: ζ(s, a) = ∑_{k=0}^∞ 1/(k + a)^s
导数定义: ζ^{(n)}(s, a) = d^n/ds^n ζ(s, a)
参数:
input_expr (str/tuple): 输入表达式,可以是以下形式:
- "(s, a)" 字符串,计算ζ(s, a)
- "(s, a, n)" 字符串,计算n阶导数ζ^{(n)}(s, a)
- 包含s和a的元组或矩阵
n (int, optional): 导数阶数,如果输入元组中已包含则优先使用元组中的n
返回:
SymPy表达式/矩阵或错误信息。
示例:
>>> hurwitz_zeta_function("(2, 0.5)")
-1.46035450880959
>>> hurwitz_zeta_function("(s, a, 1)", s=2, a=0.5)
-2.40411380631918
"""
try:
expr = sp.sympify(input_expr)
error = False
result = None
def hurwitz_zeta_sym(s_val, a_val, n_val=None):
zeta_expr = sp.zeta(s_val, a_val)
if n_val is not None and s_val.free_symbols:
vars = s_val.free_symbols
result = zeta_expr.rewrite(sp.lerchphi).diff(*vars, n_val)
else:
result = zeta_expr.rewrite(sp.lerchphi)
return result
def hurwitz_zeta_math(s_val, a_val, n_val=None):
if n_val:
n = float(n_val)
result = mp_zeta(s_val, a_val, n)
else:
result = mp_zeta(s_val, a_val)
return result
if isinstance(expr, tuple):
if len(expr) == 2:
derivative_order = None
elif len(expr) == 3 and expr[2].is_integer and expr[2] > 0:
derivative_order = expr[2]
else:
error = True
if all(e.is_number for e in expr[:2]):
params = tuple(complex(e) for e in expr[:2])
result = hurwitz_zeta_math(*params, derivative_order)
elif any(e.free_symbols for e in expr[:2]):
result = hurwitz_zeta_sym(*expr)
else:
error = True
return result if not error else f"输入错误: {input_expr}"
except Exception as e:
return f"错误:{e}"
# 示例使用
if __name__ == "__main__":
# 示例1: 标量计算
print("ζ(2, 0.5) =", hurwitz_zeta_function("(2,0.5)"))
# 4.93480220054468
# 示例2: 导数计算
s = sp.Symbol('s')
expr = hurwitz_zeta_function("s, 0.5, 1")
print("ζ'(s, 0.5) =", expr)
# Derivative(lerchphi(1, s, 0.5), s)
超几何函数的累积分布函数
hygecdf(x,M,K,N)使用相应的总体大小M,总体中具有所需特征的项目数量K和提取的样本数量N, 计算x中每个值的超几何cdf. x,M,K和N的向量或矩阵输入必须具有相同的大小. 标量输入被扩展为与其他输入具有相同维数的常数矩阵.
x -- 标量, 符号变量, 向量, 矩阵, 多维数组
M, K, N -- 数值标量, 向量, 矩阵, 多维数组
示例1: 基本的标量计算
print("hygecdf(2, 50, 10, 5) =", hygecdf(2, 50, 10, 5)
#hygecdf(2, 50, 10, 5) = 0.9517396968037909
#解释: 从50个物品中(其中10个是目标物品),抽取5个,最多抽到2个目标物品的概率
示例2: 质量检测应用
场景: 一批100个产品中有5个次品,随机抽取10个检测
M = 100 # 总体大小
K = 5 # 次品数
n = 10 # 抽样数
质量检测场景: 100个产品中5个次品,抽检10个
for x in range(0, 6):
prob = hygecdf(x, M, K, n)
print(f" 最多发现 {x} 个次品的概率: {float(prob):.4f}")
# 最多发现 0 个次品的概率: 0.5838
# 最多发现 1 个次品的概率: 0.9231
# 最多发现 2 个次品的概率: 0.9934
# 最多发现 3 个次品的概率: 0.9997
# 最多发现 4 个次品的概率: 1.0000
# 最多发现 5 个次品的概率: 1.0000
示例3: 生物统计 - 基因研究
场景: 种群中有1000个体,其中50个有特定基因,随机捕捉100个研究
M_bio = 1000
K_bio = 50
n_bio = 100
基因研究: 1000个体中50个有特定基因,随机捕捉100个
thresholds = [0, 1, 2, 5, 10]
for x in thresholds:
prob = hygecdf(x, M_bio, K_bio, n_bio)
print(f" 最多发现 {x} 个有特定基因个体的概率: {float(prob):.6f}")
# 最多发现 0 个有特定基因个体的概率: 0.004476
# 最多发现 1 个有特定基因个体的概率: 0.030773
# 最多发现 2 个有特定基因个体的概率: 0.105637
# 最多发现 5 个有特定基因个体的概率: 0.616636
# 最多发现 10 个有特定基因个体的概率: 0.992314
示例4: 社会调查 - 投票预测
场景: 城市有10000选民,其中4000支持某候选人,随机调查500人
M_survey = 10000
K_survey = 4000
n_survey = 500
投票调查: 10000选民中4000支持候选人,调查500人
support_levels = [180, 200, 220, 240, 260]
for x in support_levels:
prob = hygecdf(x, M_survey, K_survey, n_survey)
print(f" 最多 {x} 人支持的概率: {float(prob):.4f}")
# 最多 180 人支持的概率: 0.0334
# 最多 200 人支持的概率: 0.5198
# 最多 220 人支持的概率: 0.9721
# 最多 240 人支持的概率: 0.9999
# 最多 260 人支持的概率: 1.0000
示例5: 数组输入计算
x_values = [0, 1, 2, 3, 4]
result_array = hygecdf(x_values, 20, 5, 10)
print("x值:", x_values)
print("CDF值:", [f"{p:.4f}" for p in result_array])
#x值: [0, 1, 2, 3, 4]
#CDF值: ['0.0163', '0.1517', '0.5000', '0.8483', '0.9837']
示例6: 可视化 - CDF曲线
plt.figure(figsize=(15, 10))
# 子图1: 不同总体大小下的CDF
plt.subplot(2, 2, 1)
M_values = [20, 50, 100]
K_ratio = 0.2 # 成功比例
n_ratio = 0.3 # 抽样比例
for M in M_values:
K = int(M * K_ratio)
n = int(M * n_ratio)
x_range = range(0, min(n, K) + 1)
cdf_values = []
for x in x_range:
prob = hygecdf(x, M, K, n)
cdf_values.append(float(prob))
plt.plot(x_range, cdf_values, 'o-', label=f'M={M}, K={K}, n={n}')
plt.xlabel('x (成功次数)')
plt.ylabel('CDF')
plt.title('不同总体大小下的超几何CDF')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图2: 不同抽样比例下的CDF
plt.subplot(2, 2, 2)
M_fixed = 100
K_fixed = 20
n_ratios = [0.1, 0.3, 0.5, 0.7]
for ratio in n_ratios:
n = int(M_fixed * ratio)
x_range = range(0, min(n, K_fixed) + 1)
cdf_values = []
for x in x_range:
prob = hygecdf(x, M_fixed, K_fixed, n)
cdf_values.append(float(prob))
plt.plot(x_range, cdf_values, 'o-', label=f'n={n} (ratio={ratio})')
plt.xlabel('x (成功次数)')
plt.ylabel('CDF')
plt.title('不同抽样比例下的超几何CDF')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图3: 质量控制决策图
plt.subplot(2, 2, 3)
# 场景: 决定可接受的质量水平(AQL)
M_quality = 1000
n_test = 50
defect_rates = [0.01, 0.02, 0.05, 0.1] # 次品率
acceptance_limits = range(0, 11)
for rate in defect_rates:
K_defects = int(M_quality * rate)
prob_accept = []
for limit in acceptance_limits:
prob = hygecdf(limit, M_quality, K_defects, n_test)
prob_accept.append(float(prob))
plt.plot(acceptance_limits, prob_accept, 'o-',
label=f'次品率={rate * 100}%')
plt.xlabel('接受上限 (最大允许次品数)')
plt.ylabel('接受概率')
plt.title('质量控制: OC曲线')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图4: 与二项分布的比较(当总体很大时)
plt.subplot(2, 2, 4)
from scipy.stats import binom
M_large = 10000
K_large = 2000
n_large = 100
p_binom = K_large / M_large # 二项分布的成功概率
x_range = range(0, 31)
hyper_cdf = []
binom_cdf = []
for x in x_range:
# 超几何分布
prob_hyper = hygecdf(x, M_large, K_large, n_large)
hyper_cdf.append(float(prob_hyper))
# 二项分布近似
prob_binom = binom.cdf(x, n_large, p_binom)
binom_cdf.append(prob_binom)
plt.plot(x_range, hyper_cdf, 'bo-', label='超几何分布', markersize=4)
plt.plot(x_range, binom_cdf, 'r--', label='二项分布近似', linewidth=2)
plt.xlabel('x')
plt.ylabel('CDF')
plt.title('超几何分布 vs 二项分布近似 (大总体)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
示例7: 假设检验应用
Fisher精确检验的场景
# 2x2列联表: 治疗组和对照组的成功/失败
# 治疗组: 成功8人,总20人
# 对照组: 成功2人,总20人
M_fisher = 40 # 总人数
K_fisher = 10 # 总成功人数 (8+2)
n_fisher = 20 # 治疗组人数
计算p值 (单边检验)
x_observed = 8
p_value = 1 - float(hygecdf(x_observed - 1, M_fisher, K_fisher, n_fisher)
print(f"Fisher精确检验p值: {p_value:.6f}")
#Fisher精确检验p值: 0.032417
示例8: 符号计算
x_sym, M_sym, K_sym, n_sym = sp.symbols('x M K n')
symbolic_result = hygecdf(x_sym, M_sym, K_sym, n_sym)
符号表达式:
print(symbolic_result)
#Lambda(_k, Sum(Piecewise((binomial(K, _ki)*binomial(-K + M, -_ki + n)/binomial(M, n), (_ki >= 0) & (_ki <= n)), (0, True)), (_ki, 0, _k)))
示例9: 风险评估
金融风险: 投资组合中有100个项目,其中10个高风险
M_portfolio = 100
K_risky = 10
n_selected = 15
投资组合风险评估:
risk_levels = [0, 1, 2, 3, 4, 5]
for x in risk_levels:
prob = hygecdf(x, M_portfolio, K_risky, n_selected)
risk = 1 - float(prob) # 超过x个高风险项目的概率
print(f" 选择超过 {x} 个高风险项目的概率: {risk:.4f}")
# 选择超过 0 个高风险项目的概率: 0.8192
# 选择超过 1 个高风险项目的概率: 0.4625
# 选择超过 2 个高风险项目的概率: 0.1705
# 选择超过 3 个高风险项目的概率: 0.0408
# 选择超过 4 个高风险项目的概率: 0.0063
# 选择超过 5 个高风险项目的概率: 0.0006
示例10: 抽样设计
确定合适的样本量来检测一定比例的问题
M_population = 500
K_problem = 25 # 5%的问题率
confidence = 0.95
抽样设计: 需要多大的样本才能以95%置信度检测到至少一个问题?
sample_sizes = range(10, 101, 10)
for n_sample in sample_sizes:
# 检测到至少一个问题的概率 = 1 - 检测到0个问题的概率
prob_zero = hygecdf(0, M_population, K_problem, n_sample)
prob_at_least_one = 1 - float(prob_zero)
print(f" 样本量 {n_sample}: 检测到至少一个问题的概率 = {prob_at_least_one:.4f}")
if prob_at_least_one >= confidence:
print(f" → 样本量 {n_sample} 满足95%置信度要求")
break
# 样本量 10: 检测到至少一个问题的概率 = 0.4041
# 样本量 20: 检测到至少一个问题的概率 = 0.6488
# 样本量 30: 检测到至少一个问题的概率 = 0.7954
# 样本量 40: 检测到至少一个问题的概率 = 0.8822
# 样本量 50: 检测到至少一个问题的概率 = 0.9330
# 样本量 60: 检测到至少一个问题的概率 = 0.9624
# → 样本量 60 满足95%置信度要求
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.stats import Hypergeometric, cdf
from scipy.stats import hypergeom
def hypergeometric_cumulative_distribution(input_str):
try:
# 将输入的字符串转换为SymPy表达式
expr = sp.sympify(input_str)
# 初始化错误标志为False
error = False
# 初始化结果为None
result = None
# 检查表达式是否为长度为4的元组
if isinstance(expr, tuple) and len(expr) == 4:
if all(e.is_integer for e in expr):
params = tuple(int(e) for e in expr)
"""
计算超几何分布的累积分布函数值
参数:
x_val (int): 累积概率的上限值
m_val (int): 总体大小
k_val (int): 总体中成功的次数
n_val (int): 样本大小
返回:
float: 累积分布函数值,即P(X ≤ x_val)
"""
# 直接调用scipy.stats.hypergeom.cdf函数计算累积分布函数值
result = hypergeom.cdf(*params)
elif any(e.free_symbols for e in expr):
"""
计算超几何分布的累积分布函数值。
参数:
x_val: 随机变量的值
m_val: 总体中的成功元素个数
k_val: 总体的元素个数
n_val: 抽样的元素个数
返回:
超几何分布的累积分布函数值或符号表达式
"""
# 创建一个超几何分布随机变量X
X = Hypergeometric(*expr)
# 返回累积分布函数的符号表达式
result = cdf(X)
else:
error = True
else:
# 如果输入不是长度为4的元组,设置错误标志为True
error = True
# 如果没有错误,返回计算结果;否则返回错误信息
return result if not error else f"输入错误: {input_str}"
except Exception as e:
# 如果在计算过程中出现异常,返回错误信息
return f"错误: {e}"
# 标量输入示例
print(hypergeometric_cumulative_distribution("(2, 50, 10, 5)"))
# 0.9517396968037909
# 符号输入示例
print(hypergeometric_cumulative_distribution("(x, a, b, c)"))
# Lambda(_k, Sum(Piecewise((binomial(b, _ki)*binomial(a - b, -_ki + c)/binomial(a, c), (_ki >= 0) & (_ki <= c)), (0, True)), (_ki, 0, _k)))
超几何函数的逆累积分布函数
Y = hygeinv(P,M,K,N)返回最小的整数X,使得在X处计算的超几何cdf等于或超过P.您可以将P视为在N个图纸中观察到X个有缺陷的项目而不替换K有缺陷的M个项目组的概率.
import matplotlib.pyplot as plt
示例1: 基本的标量计算
print("hygeinv(0.5, 100, 20, 10) =", hygeinv(0.5, 100, 20, 10)
#hygeinv(0.5, 100, 20, 10) = 2.0
#解释: 从100个物品中(20个目标),抽10个,50%分位数是2,即P(X≤2)≥0.5
示例2: 质量控制 - 确定接受标准
场景: 一批1000个产品,允许有2%的次品率(20个次品),抽检50个
M = 1000
K = 20 # 允许的最大次品数
n = 50 # 抽检数量
confidence_levels = [0.90, 0.95, 0.99]
质量控制: 确定不同置信水平下的接受标准
for conf in confidence_levels:
threshold = hygeinv(conf, M, K, n)
print(f" {conf * 100}%置信水平: 最多接受 {int(threshold)} 个次品")
#90.0%置信水平: 最多接受 2 个次品
#95.0%置信水平: 最多接受 3 个次品
#99.0%置信水平: 最多接受 4 个次品
示例3: 抽样检验设计
确定在不同次品率下的接受阈值
M_design = 500
n_sample = 30
defect_rates = [0.01, 0.02, 0.05, 0.10] # 1%, 2%, 5%, 10%次品率
抽样设计: 不同次品率下的95%置信接受标准
for rate in defect_rates:
K_defects = int(M_design * rate)
threshold = hygeinv(0.95, M_design, K_defects, n_sample)
print(f" 次品率{rate * 100}%: 接受阈值 = {int(threshold)}")
# 次品率1.0%: 接受阈值 = 1
# 次品率2.0%: 接受阈值 = 2
# 次品率5.0%: 接受阈值 = 4
# 次品率10.0%: 接受阈值 = 6
示例4: 数组输入计算
p_values = [0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99]
results = hygeinv(p_values, 100, 25, 20)
print("概率分位数:", p_values)
print("对应阈值: ", results)
#概率分位数: [0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99]
#对应阈值: [3. 4. 5. 6. 7. 8. 9.]
示例5: 风险管理应用
金融投资: 100个项目中10个高风险,选择15个项目组合
M_risk = 100
K_risky = 10
n_portfolio = 15
risk_tolerances = [0.05, 0.10, 0.25, 0.50]
风险管理: 不同风险容忍度下的高风险项目上限
for tolerance in risk_tolerances:
threshold = hygeinv(1 - tolerance, M_risk, K_risky, n_portfolio)
print(f" {tolerance * 100}%风险容忍度: 最多 {int(threshold)} 个高风险项目")
# 5.0%风险容忍度: 最多 3 个高风险项目
# 10.0%风险容忍度: 最多 3 个高风险项目
# 25.0%风险容忍度: 最多 2 个高风险项目
# 50.0%风险容忍度: 最多 1 个高风险项目
示例6: 可视化 - 分位数函数曲线
plt.figure(figsize=(15, 10))
# 子图1: 不同置信水平下的接受阈值
plt.subplot(2, 2, 1)
M_viz = 1000
n_viz = 100
defect_rates_viz = [0.01, 0.02, 0.05, 0.10]
confidence_levels_viz = np.linspace(0.5, 0.99, 50)
for rate in defect_rates_viz:
K_viz = int(M_viz * rate)
thresholds = []
for conf in confidence_levels_viz:
threshold = hygeinv(conf, M_viz, K_viz, n_viz)
thresholds.append(threshold)
plt.plot(confidence_levels_viz, thresholds, label=f'次品率{rate * 100}%')
plt.xlabel('置信水平')
plt.ylabel('接受阈值')
plt.title('不同次品率下的接受阈值')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图2: 不同样本量对分位数的影响
plt.subplot(2, 2, 2)
M_fixed = 500
K_fixed = 25
p_fixed = 0.95
sample_sizes = range(10, 101, 5)
thresholds_sample = []
for n_size in sample_sizes:
threshold = hygeinv(p_fixed, M_fixed, K_fixed, n_size)
thresholds_sample.append(threshold)
plt.plot(sample_sizes, thresholds_sample, 'bo-', markersize=4)
plt.xlabel('样本量')
plt.ylabel('95%分位数')
plt.title('样本量对分位数的影响')
plt.grid(True, alpha=0.3)
# 子图3: 运营决策曲线
plt.subplot(2, 2, 3)
# 库存管理: 确定最大可接受的缺陷数量
M_inventory = 200
n_inspect = 20
confidence_ops = np.linspace(0.8, 0.99, 50)
defect_scenarios = [2, 5, 10] # 不同缺陷数量场景
for defects in defect_scenarios:
thresholds_ops = []
for conf in confidence_ops:
threshold = hygeinv(conf, M_inventory, defects, n_inspect)
thresholds_ops.append(threshold)
plt.plot(confidence_ops, thresholds_ops, label=f'{defects}个缺陷')
plt.xlabel('置信水平')
plt.ylabel('最大观察缺陷数')
plt.title('运营决策: 缺陷检测阈值')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图4: 比较不同总体大小的影响
plt.subplot(2, 2, 4)
p_compare = 0.9
K_ratio = 0.1 # 10%的成功比例
n_ratio = 0.2 # 20%的抽样比例
population_sizes = [50, 100, 200, 500, 1000]
thresholds_pop = []
for M_pop in population_sizes:
K_pop = int(M_pop * K_ratio)
n_pop = int(M_pop * n_ratio)
threshold = hygeinv(p_compare, M_pop, K_pop, n_pop)
thresholds_pop.append(threshold)
plt.plot(population_sizes, thresholds_pop, 'ro-', markersize=6)
plt.xlabel('总体大小')
plt.ylabel('90%分位数')
plt.title('总体大小对分位数的影响')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
示例7: 医疗检测应用
疾病筛查: 人群中5%患病,检测100人
M_medical = 10000
K_disease = 500 # 5%患病率
n_test = 100
detection_levels = [0.8, 0.9, 0.95, 0.99]
疾病筛查: 不同检测置信度下的预期最大病例数
for level in detection_levels:
threshold = hygeinv(level, M_medical, K_disease, n_test)
print(f" {level * 100}%置信度: 最多检测到 {int(threshold)} 个病例")
# 80.0%置信度: 最多检测到 7 个病例
# 90.0%置信度: 最多检测到 8 个病例
# 95.0%置信度: 最多检测到 9 个病例
# 99.0%置信度: 最多检测到 11 个病例
示例8: 教育评估
班级中有30名学生,预计60%能达到优秀(18人),随机抽查10人评估
M_class = 30
K_excellent = 18
n_assess = 10
confidence_edu = [0.8, 0.9, 0.95]
教育评估: 不同置信水平下的优秀学生数量预期
for conf in confidence_edu:
threshold = hygeinv(conf, M_class, K_excellent, n_assess)
print(f" {conf * 100}%置信水平: 最多 {int(threshold)} 个优秀学生")
# 80.0%置信水平: 最多 7 个优秀学生
# 90.0%置信水平: 最多 8 个优秀学生
# 95.0%置信水平: 最多 8 个优秀学生
示例9: 环境监测
湖泊中有1000条鱼,污染导致10%死亡(100条),抽样检测50条
M_lake = 1000
K_dead = 100
n_monitor = 50
alert_levels = [0.95, 0.99]
环境监测: 污染警报阈值
for level in alert_levels:
threshold = hygeinv(level, M_lake, K_dead, n_monitor)
print(f" {level * 100}%置信度警报: 发现超过 {int(threshold)} 条死鱼时触发")
# 95.0%置信度警报: 发现超过 9 条死鱼时触发
# 99.0%置信度警报: 发现超过 10 条死鱼时触发
示例10: 生产优化应用
优化生产线: 1000个产品中目标有50个瑕疵,抽检80个
M_production = 1000
K_defect_target = 50
n_quality = 80
improvement_levels = [0.1, 0.25, 0.5, 0.75, 0.9]
生产优化: 质量改进目标
for improvement in improvement_levels:
# 改进后的缺陷数
K_improved = int(K_defect_target * (1 - improvement))
threshold_improved = hygeinv(0.95, M_production, K_improved, n_quality)
threshold_current = hygeinv(0.95, M_production, K_defect_target, n_quality)
print(f" 改进{improvement * 100}%: 接受阈值从{int(threshold_current)}降至{int(threshold_improved)}")
# 改进10.0%: 接受阈值从7降至7
# 改进25.0%: 接受阈值从7降至6
# 改进50.0%: 接受阈值从7降至4
# 改进75.0%: 接受阈值从7降至3
# 改进90.0%: 接受阈值从7降至1
示例11: 边界情况测试
boundary_cases = [
(0.0, 100, 20, 10),
(0.0001, 100, 20, 10),
(0.9999, 100, 20, 10),
(1.0, 100, 20, 10),
(0.5, 100, 0, 10),
(0.5, 100, 100, 10),
]
for p_val, M_val, K_val, n_val in boundary_cases:
result = hygeinv(p_val, M_val, K_val, n_val)
print(f" p={p_val}, M={M_val}, K={K_val}, n={n_val} -> {result}")
# p=0.0, M=100, K=20, n=10 -> 0.0
# p=0.0001, M=100, K=20, n=10 -> 0.0
# p=0.9999, M=100, K=20, n=10 -> 7.0
# p=1.0, M=100, K=20, n=10 -> 10.0
# p=0.5, M=100, K=0, n=10 -> 0.0
# p=0.5, M=100, K=100, n=10 -> 10.0
示例12: 实际决策支持
客户投诉处理: 1000个客户中有50个可能投诉,随机联系100个了解情况
M_customers = 1000
K_complaints = 50
n_contact = 100
客户投诉风险评估:
risk_levels = [0.05, 0.1, 0.2]
for risk in risk_levels:
threshold = hygeinv(1 - risk, M_customers, K_complaints, n_contact)
print(f" 可接受{risk * 100}%风险: 最多遇到 {int(threshold)} 个投诉客户")
if threshold >= 10: # 假设10个投诉是处理上限
print(f" ⚠️ 警告: 可能超出处理能力!")
# 可接受5.0%风险: 最多遇到 9 个投诉客户
# 可接受10.0%风险: 最多遇到 8 个投诉客户
# 可接受20.0%风险: 最多遇到 7 个投诉客户
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.stats import hypergeom
# 定义计算单个元素的逆CDF函数
def compute_inv_cdf(p_val, M_val, K_val, n_val):
# 参数验证
if not (0 <= p_val <= 1):
raise ValueError(f"概率p必须在[0,1]范围内,当前为{p_val}")
# 转换为整数并验证
try:
M_int = int(M_val)
K_int = int(K_val)
n_int = int(n_val)
if M_int != M_val or K_int != K_val or n_int != n_val:
raise ValueError("参数M, K, n必须为整数")
except (TypeError, ValueError):
raise ValueError("参数M, K, n必须为整数")
if M_int <= 0 or K_int < 0 or n_int < 0:
raise ValueError("参数必须满足 M>0, K≥0, n≥0")
if K_int > M_int or n_int > M_int:
raise ValueError("K和n不能超过M")
# 处理边界情况
if p_val <= 0:
return 0
if p_val >= 1:
return min(K_int, n_int)
# 创建分布对象并查找分位数
hg = hypergeom(M_int, K_int, n_int)
max_k = min(K_int, n_int)
for k in range(0, max_k + 1):
if hg.cdf(k) >= p_val - 1e-10: # 浮点容差
return k
return max_k # 理论上不会执行到此
def hypergeometric_inverse_cumulative_distribution(input_str):
"""
计算超几何分布的逆累积分布函数(分位数值),对标Matlab的hygeinv函数。
参数:
input_str: 输入字符串,格式为四元组 (p, M, K, n),各参数可为矩阵或标量。
返回:
数值、SymPy矩阵或错误信息字符串。
示例:
>>> hypergeometric_inverse_cumulative_distribution("(0.5, 10, 5, 3)")
1
>>> hypergeometric_inverse_cumulative_distribution("([[0.1, 0.5], [0.9, 1.0]], 10, 5, 3)")
Matrix([[1, 1], [2, 3]])
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 4:
if all(e.is_number for e in expr):
p, M, K, n = expr # 参数顺序: p, M总体大小, K成功数, n抽样数
# 标量计算
try:
p_val = float(p)
M_val = int(M)
K_val = int(K)
n_val = int(n)
result = compute_inv_cdf(p_val, M_val, K_val, n_val)
except Exception as e:
error = True
result = f"参数错误: {str(e)}"
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
# 标量计算示例
print(hypergeometric_inverse_cumulative_distribution("0.99,1000,10,50"))
# 3
print(hypergeometric_inverse_cumulative_distribution("0.5,1000,10,50"))
# 0
超几何函数的概率密度函数
Y = hygepdf(X,M,K,N)使用相应的总体大小M, 总体中具有所需特征的项目数量K和提取的样本数量N计算X中每个值的超几何pdf. X,M,K和N可以是向量,矩阵,它们都具有相同的大小.标量输入被扩展为与其他输入具有相同维度的常数数组.
M,K和N中的参数必须都是正整数,N≤M. X中的值必须小于或等于所有参数值.
X -- 标量, 符号变量, 向量, 矩阵, 多维数组
M, K, N -- 数值标量, 向量, 矩阵, 多维数组
import matplotlib.pyplot as plt
示例1: 基本的标量计算
result = hygepdf(2, 100, 20, 10)
print(f"hygepdf(2, 100, 20, 10) = {result}")
#hygepdf(2, 100, 20, 10) = 0.3181706296100318
#解释: 从100个物品中(20个目标),抽10个,恰好抽到2个目标物品的概率
示例2: 质量检测应用
场景: 一批100个产品中有5个次品,随机抽取10个检测
M = 100
K = 5 # 次品数
n = 10 # 抽样数
质量检测: 100个产品中5个次品,抽检10个
for x in range(0, 6):
prob = hygepdf(x, M, K, n)
print(f" 恰好发现 {x} 个次品的概率: {float(prob):.6f}")
# 恰好发现 0 个次品的概率: 0.583752
# 恰好发现 1 个次品的概率: 0.339391
# 恰好发现 2 个次品的概率: 0.070219
# 恰好发现 3 个次品的概率: 0.006384
# 恰好发现 4 个次品的概率: 0.000251
# 恰好发现 5 个次品的概率: 0.000003
示例3: 生物统计 - 稀有物种研究
场景: 森林中有200只动物,其中10只是目标物种,随机观察30只
M_bio = 200
K_bio = 10
n_bio = 30
稀有物种研究: 200只动物中10只目标物种,观察30只
observation_counts = [0, 1, 2, 3, 4, 5]
for x in observation_counts:
prob = hygepdf(x, M_bio, K_bio, n_bio)
print(f" 恰好观察到 {x} 只目标物种的概率: {float(prob):.6f}")
# 恰好观察到 0 只目标物种的概率: 0.188941
# 恰好观察到 1 只目标物种的概率: 0.352065
# 恰好观察到 2 只目标物种的概率: 0.283608
# 恰好观察到 3 只目标物种的概率: 0.129914
# 恰好观察到 4 只目标物种的概率: 0.037430
# 恰好观察到 5 只目标物种的概率: 0.007078
示例4: 社会调查 - 选民倾向
场景: 城市有5000选民,其中2000支持某政策,随机调查100人
M_survey = 5000
K_survey = 2000
n_survey = 100
选民倾向调查: 5000选民中2000支持,调查100人
support_levels = [35, 40, 45, 50, 55, 60]
for x in support_levels:
prob = hygepdf(x, M_survey, K_survey, n_survey)
print(f" 恰好 {x} 人支持的概率: {float(prob):.8f}")
# 恰好 35 人支持的概率: 0.04908623
# 恰好 40 人支持的概率: 0.08204364
# 恰好 45 人支持的概率: 0.04780618
# 恰好 50 人支持的概率: 0.01001614
# 恰好 55 人支持的概率: 0.00076205
# 恰好 60 人支持的概率: 0.00002085
示例5: 数组输入计算
x_values = [0, 1, 2, 3, 4, 5]
result_array = hygepdf(x_values, 50, 10, 5)
print("x值:", x_values)
print("概率密度:", [f"{p:.6f}" for p in result_array])
#x值: [0, 1, 2, 3, 4, 5]
#概率密度: ['0.310563', '0.431337', '0.209840', '0.044177', '0.003965', '0.000119']
示例6: 可视化 - 概率质量函数
plt.figure(figsize=(15, 10))
# 子图1: 不同总体大小下的概率分布
plt.subplot(2, 2, 1)
M_values = [20, 50, 100]
K_ratio = 0.2 # 成功比例
n_ratio = 0.3 # 抽样比例
for M in M_values:
K = int(M * K_ratio)
n = int(M * n_ratio)
x_range = range(0, min(n, K) + 1)
pmf_values = []
for x in x_range:
prob = hygepdf(x, M, K, n)
pmf_values.append(float(prob))
plt.plot(x_range, pmf_values, 'o-', label=f'M={M}, K={K}, n={n}')
plt.xlabel('x (成功次数)')
plt.ylabel('概率密度 P(X=x)')
plt.title('不同总体大小下的超几何分布')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图2: 不同抽样比例的影响
plt.subplot(2, 2, 2)
M_fixed = 100
K_fixed = 20
n_ratios = [0.1, 0.3, 0.5, 0.7]
for ratio in n_ratios:
n = int(M_fixed * ratio)
x_range = range(0, min(n, K_fixed) + 1)
pmf_values = []
for x in x_range:
prob = hygepdf(x, M_fixed, K_fixed, n)
pmf_values.append(float(prob))
plt.plot(x_range, pmf_values, 'o-', label=f'n={n} (ratio={ratio})')
plt.xlabel('x (成功次数)')
plt.ylabel('概率密度 P(X=x)')
plt.title('不同抽样比例下的超几何分布')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图3: 质量控制中的概率分布
plt.subplot(2, 2, 3)
# 场景: 不同缺陷率下的质量分布
M_quality = 1000
n_test = 50
defect_rates = [0.01, 0.02, 0.05, 0.1] # 次品率
x_range_quality = range(0, 11)
for rate in defect_rates:
K_defects = int(M_quality * rate)
pmf_values = []
for x in x_range_quality:
prob = hygepdf(x, M_quality, K_defects, n_test)
pmf_values.append(float(prob))
plt.plot(x_range_quality, pmf_values, 'o-',
label=f'次品率={rate * 100}%', markersize=3)
plt.xlabel('检测到的次品数')
plt.ylabel('概率密度')
plt.title('质量控制: 不同缺陷率的概率分布')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图4: 与二项分布的比较
plt.subplot(2, 2, 4)
from scipy.stats import binom
M_large = 10000
K_large = 2000
n_large = 100
p_binom = K_large / M_large # 二项分布的成功概率
x_range = range(0, 31)
hyper_pmf = []
binom_pmf = []
for x in x_range:
# 超几何分布
prob_hyper = hygepdf(x, M_large, K_large, n_large)
hyper_pmf.append(float(prob_hyper))
# 二项分布近似
prob_binom = binom.pmf(x, n_large, p_binom)
binom_pmf.append(prob_binom)
plt.plot(x_range, hyper_pmf, 'bo-', label='超几何分布', markersize=4)
plt.plot(x_range, binom_pmf, 'r--', label='二项分布近似', linewidth=2)
plt.xlabel('x')
plt.ylabel('概率密度')
plt.title('超几何分布 vs 二项分布近似 (大总体)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
示例7: 医学研究 - 疾病检测
场景: 人群中有2%患病,检测50人
M_medical = 10000
K_disease = 200 # 2%患病率
n_test = 50
疾病检测: 10000人中200人患病,检测50人
case_counts = [0, 1, 2, 3, 4, 5]
for x in case_counts:
prob = hygepdf(x, M_medical, K_disease, n_test)
print(f" 恰好检测到 {x} 个病例的概率: {float(prob):.6f}")
#恰好检测到 0 个病例的概率: 0.363257
#恰好检测到 1 个病例的概率: 0.372533
#恰好检测到 2 个病例的概率: 0.186248
#恰好检测到 3 个病例的概率: 0.060498
#恰好检测到 4 个病例的概率: 0.014357
#恰好检测到 5 个病例的概率: 0.002654
示例8: 库存管理
场景: 仓库有500件商品,其中20件有瑕疵,随机检查25件
M_inventory = 500
K_defective = 20
n_inspect = 25
库存检查: 500件商品中20件瑕疵,检查25件
defect_found = [0, 1, 2, 3, 4, 5]
for x in defect_found:
prob = hygepdf(x, M_inventory, K_defective, n_inspect)
print(f" 恰好发现 {x} 件瑕疵品的概率: {float(prob):.6f}")
# 恰好发现 0 件瑕疵品的概率: 0.351194
# 恰好发现 1 件瑕疵品的概率: 0.385081
# 恰好发现 2 件瑕疵品的概率: 0.192119
# 恰好发现 3 件瑕疵品的概率: 0.057887
# 恰好发现 4 件瑕疵品的概率: 0.011792
# 恰好发现 5 件瑕疵品的概率: 0.001723
示例9: 教育评估
场景: 班级有30名学生,其中12名数学优秀,随机抽查8名
M_class = 30
K_excellent = 12
n_sample = 8
学生能力评估: 30人中12人优秀,抽查8人
excellent_counts = range(0, 9)
for x in excellent_counts:
prob = hygepdf(x, M_class, K_excellent, n_sample)
print(f" 恰好 {x} 人优秀的概率: {float(prob):.6f}")
# 恰好 0 人优秀的概率: 0.007476
# 恰好 1 人优秀的概率: 0.065247
# 恰好 2 人优秀的概率: 0.209335
# 恰好 3 人优秀的概率: 0.322054
# 恰好 4 人优秀的概率: 0.258794
# 恰好 5 人优秀的概率: 0.110419
# 恰好 6 人优秀的概率: 0.024154
# 恰好 7 人优秀的概率: 0.002436
# 恰好 8 人优秀的概率: 0.000085
示例10: 符号计算和理论分析
symbolic_result = hygepdf(x, M, K, n)
超几何分布的符号表达式:
print(symbolic_result)
#binomial(K, x)*binomial(-K + M, n - x)/binomial(M, n)
示例11: 选举预测
场景: 选区有1000选民,其中550支持候选人A,随机调查100人
M_election = 1000
K_support = 550
n_poll = 100
print("选举预测: 1000选民中550人支持A,调查100人")
support_levels = [45, 50, 55, 60, 65]
for x in support_levels:
prob = hygepdf(x, M_election, K_support, n_poll)
print(f" 恰好 {x} 人支持A的概率: {float(prob):.8f}")
# 恰好 45 人支持A的概率: 0.00907471
# 恰好 50 人支持A的概率: 0.04804026
# 恰好 55 人支持A的概率: 0.08431185
# 恰好 60 人支持A的概率: 0.04858466
# 恰好 65 人支持A的概率: 0.00891474
示例12: 环境监测
场景: 湖泊有800条鱼,污染导致40条死亡,抽样检测60条
M_lake = 800
K_dead = 40
n_sample = 60
环境污染监测: 800条鱼中40条死亡,检测60条
dead_found = [0, 1, 2, 3, 4, 5, 6, 7, 8]
for x in dead_found:
prob = hygepdf(f"({x}, {M_lake}, {K_dead}, {n_sample})")
print(f" 恰好发现 {x} 条死鱼的概率: {float(prob):.6f}")
# 恰好发现 0 条死鱼的概率: 0.040749
# 恰好发现 1 条死鱼的概率: 0.139510
# 恰好发现 2 条死鱼的概率: 0.228642
# 恰好发现 3 条死鱼的概率: 0.238941
# 恰好发现 4 条死鱼的概率: 0.178951
# 恰好发现 5 条死鱼的概率: 0.102345
# 恰好发现 6 条死鱼的概率: 0.046509
# 恰好发现 7 条死鱼的概率: 0.017254
# 恰好发现 8 条死鱼的概率: 0.005328
示例13: 最可能值分析
分析在给定参数下最可能出现的成功次数
M_analysis = 100
K_analysis = 30
n_analysis = 20
max_prob = 0
most_likely = 0
分析: M=100, K=30, n=20
for x in range(max(0, n_analysis + K_analysis - M_analysis), min(K_analysis, n_analysis) + 1):
prob = hygepdf(x, M_analysis, K_analysis, n_analysis)
prob_val = float(prob)
print(f" P(X={x}) = {prob_val:.6f}")
if prob_val > max_prob:
max_prob = prob_val
most_likely = x
# P(X=0) = 0.000302
# P(X=1) = 0.003553
# P(X=2) = 0.018826
# P(X=3) = 0.059674
# P(X=4) = 0.126808
# P(X=5) = 0.191826
# P(X=6) = 0.214091
# P(X=7) = 0.180287
# P(X=8) = 0.116176
# P(X=9) = 0.057760
# P(X=10) = 0.022238
# P(X=11) = 0.006628
# P(X=12) = 0.001523
# P(X=13) = 0.000268
# P(X=14) = 0.000036
# P(X=15) = 0.000004
# P(X=16) = 0.000000
# P(X=17) = 0.000000
# P(X=18) = 0.000000
# P(X=19) = 0.000000
# P(X=20) = 0.000000
print(f"最可能值: X = {most_likely} (概率 = {max_prob:.6f})")
expected = n_analysis * K_analysis / M_analysis
print(f"期望值: {expected:.2f}")
#最可能值: X = 6 (概率 = 0.214091)
#期望值: 6.00
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.stats import Hypergeometric, density
from scipy.stats import hypergeom
def hypergeometric_probability_density(input_str):
"""
计算超几何分布概率密度函数,对标Matlab的hygepdf函数。
参数:
input_str: 输入字符串,格式为四元组 (x, M, K, n),各参数可为矩阵或标量。
参数说明:
- x: 成功次数
- M: 总体大小
- K: 总体中成功数量
- n: 抽样数量
返回:
数值、SymPy矩阵或错误信息字符串。
示例:
>>> hypergeometric_probability_density("(2, 100, 20, 5)")
0.2022
>>> hypergeometric_probability_density("([0,1,2], 10, 5, 3)")
Matrix([[0.0833, 0.4167, 0.4167]])
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def eval_hypergeometric_pdf(x_val, M_val, K_val, n_val):
"""计算单个元素的概率密度"""
# 参数验证
# 符号计算直接返回表达式
X = Hypergeometric('X', M_val, K_val, n_val)
return density(X)(x_val)
if isinstance(expr, tuple) and len(expr) == 4:
if all(e.is_integer for e in expr):
params = tuple(int(e) for e in expr)
"""
计算超几何分布的概率质量函数(PMF),对标Matlab的hygepdf函数
参数:
x_val (int): 成功次数
M_val (int): 总体大小
K_val (int): 总体中成功的元素个数
n_val (int): 抽取的样本大小
返回:
float: 超几何分布在x_val处的概率密度值
"""
# 直接调用scipy.stats.hypergeom.pmf计算概率密度
result = hypergeom.pmf(*params)
elif any(e.free_symbols for e in expr):
"""计算单个元素的概率密度"""
# 参数验证
X = Hypergeometric('X', *expr[1:])
result = density(X)(expr[0])
else:
error = True
return result if not error else f"输入错误:{input_str}"
except Exception as e:
return f"系统错误: {str(e)}"
# 测试示例
if __name__ == "__main__":
# 标量测试
print(hypergeometric_probability_density("(2, 100, 20, 5)"))
# 输出: 0.20734379349990548
# 符号计算测试
print(hypergeometric_probability_density("(k, 10, 5, 3)"))
# 输出: binomial(5, k)*binomial(5, 3 - k)/120
超几何函数的随机数
R = hygernd(M,K,N)从具有相应总体大小的超几何分布中生成随机数,M,总体中具有所需特征的项目数量K, 以及提取的样本数量N. M,K和N可以是向量,矩阵,它们都具有相同的大小, 这也是R的大小.
M,K或N的标量输入被扩展为与其他输入具有相同维度的常数数组.
R=hyernd(M,K,N,M,N)生成一个M-by-N阵列. M,K,N参数可以是标量或与R大小相同的数组.
M, K, N -- 数值标量, 向量, 矩阵, 多维数组
示例1. 产品质量抽检
场景:从100个产品中抽检20个,已知有15个次品
产品质量抽检:
print(hyernd(100, 15, 20)) # 单次抽检发现的次品数
#[2]
print(hyernd(100, 15, 20, 5)) # 5次抽检的结果
#[2 3 2 3 3]
print(hyernd(100, 15, 20, 3, 2)) # 3×2的抽检结果矩阵
#[[3 3]
[4 6]
[5 6]]
示例2. 生物多样性调查
场景:森林中有200只动物,标记了30只,重新捕获25只进行调查
print(hyernd(200, 30, 25)) # 重捕到的标记动物数量
#[0]
print(hyernd(200, 30, 25, 10)) # 10次调查的结果
#[2 1 2 7 5 2 6 5 1 4]
示例3. 选举民意调查
场景:城市有50000选民,其中18000支持A候选人,调查500人
print(hyernd(50000, 18000, 500)) # 调查中支持A的人数
#[166]
print(hyernd(50000, 18000, 500, 8)) # 8次独立调查结果
#[177 176 210 205 184 195 172 166]
示例4. 医学临床试验
场景:药物试验,100名患者中40人有副作用,随机观察30名
print(hyernd(100, 40, 30)) # 观察到有副作用的患者数
#[13]
print(hyernd(100, 40, 30, 6)) # 6个医疗中心的观察结果
#[12 10 8 12 11 12]
示例5. 库存管理
场景:仓库有不同批次的商品,检查各批次的缺陷品
M_matrix = [[80, 120], [95, 105]] # 各批次商品总数
K_matrix = [[8, 15], [12, 10]] # 各批次缺陷品数
N_matrix = [[10, 15], [12, 8]] # 各批次抽检数
库存管理:
result = hyernd(M_matrix, K_matrix, N_matrix)
各批次发现的缺陷品数:
print(result)
#[[0,2]
[1,2]]
示例6. 教育质量评估
场景:从不同班级随机抽取学生进行测试
全校1000名学生,优秀生200名,随机抽取50名
print(f"优秀生数量: {hyernd(1000, 200, 50)}")
#优秀生数量: [8]
5个班级的模拟结果
print(hyernd(1000, 200, 50, 5))
#[11 7 9 6 9]
示例7. 网络安全检测
场景:检测网络流量中的恶意数据包
10000个数据包中有150个恶意包,随机检查200个
print(f"检测到的恶意包: {hyernd(10000, 150, 200)}")
#[4]
8小时连续监测结果
print(hyernd(10000, 150, 200, 8))
#[3 4 2 1 6 6 5 2]
示例8. 多维度应用场景
复杂场景:不同部门不同时间段的抽检
各部门参数矩阵
departments_M = [[50, 75, 60], [80, 45, 90]] # 各部门物品总数
departments_K = [[5, 8, 6], [12, 4, 9]] # 各部门问题物品数
departments_N = [[10, 15, 12], [16, 8, 18]] # 各部门抽检数
result = hyernd(departments_M, departments_K, departments_N)
各部门抽检发现的问题数:
print(result)
#[[0,2,1]
[1,2,0]]
示例9. 科学研究中的随机抽样
场景:基因研究中稀有基因的发现
1000个基因中有50个目标基因,随机测序100个
for i in range(5):
result = hyernd(1000, 50, 100)
print(f"实验{i + 1}发现的目标基因数: {result}")
#实验1发现的目标基因数: [6]
#实验2发现的目标基因数: [4]
#实验3发现的目标基因数: [2]
#实验4发现的目标基因数: [6]
#实验5发现的目标基因数: [8]
示例10. 市场调研
场景:不同城市消费者偏好调查
各城市参数
cities_population = [[800, 1200], [600, 900]] # 各城市样本量
cities_preference = [[240, 360], [180, 270]] # 偏好某产品的人数
cities_survey = [[80, 120], [60, 90]] # 调查人数
result = hyernd(cities_population, cities_preference, cities_survey)
各城市调查中偏好该产品的人数:
print(result)
#[[18,38]
[17,30]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.stats import hypergeom
import numpy as np
def hypergeometric_random_number(input_str):
"""
生成超几何分布随机数,对标Matlab的hygernd函数。
参数格式:
(M, K, N) -> 单个随机数
(M, K, N, size) -> 指定形状的数组
(M_mat, K_mat, N_mat) -> 矩阵参数,逐元素生成随机数
参数说明:
M: 总体大小(必须为正整数)
K: 成功项数量(0 ≤ K ≤ M)
N: 抽样数量(0 ≤ N ≤ M)
size: 输出形状(整数或元组)
返回:
随机数、SymPy矩阵、numpy数组或错误信息
示例:
>>> hypergeometric_random_number("(100, 20, 5)")
3
>>> hypergeometric_random_number("(100, 20, 5, 3)")
Matrix([[2, 4, 3]])
>>> hypergeometric_random_number("([[90,100],[110,120]], 20, 5)")
Matrix([[2, 3], [1, 4]])
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def generate_rvs(M_val, K_val, N_val, size=None):
"""核心生成函数"""
# 参数验证
M = int(M_val)
K = int(K_val)
N = int(N_val)
if M <= 0 or K < 0 or N < 0:
raise ValueError("参数必须满足 M>0, K≥0, N≥0")
if K > M or N > M:
raise ValueError("K和N不能超过M")
# 生成随机数
if size:
arr = hypergeom.rvs(M, K, N, size=size)
return sp.Matrix(arr) if isinstance(arr, np.ndarray) else arr
else:
return hypergeom.rvs(M, K, N)
# 解析输入参数
if isinstance(expr, tuple):
# 处理标量参数+size参数 ------------------------------------------------
if len(expr) == 3: # 单个随机数
return generate_rvs(*expr)
elif len(expr) >= 4: # 带size参数
M, K, N = expr[:3]
size = tuple(int(x) for x in expr[3:]) if len(expr) > 4 else int(expr[3])
return generate_rvs(M, K, N, size=size)
raise ValueError("输入格式错误,应为 (M,K,N) 或 (M,K,N,size)")
except Exception as e:
return f"错误: {str(e)}"
# 测试示例
if __name__ == "__main__":
# 标量测试
print(hypergeometric_random_number("(100, 20, 5)"))
# 0
# 一维数组测试
print(hypergeometric_random_number("(100, 20, 5, 3)"))
# Matrix([[2],
# [1],
# [0]])
超几何函数的均值和方差
[MN,V] = hygestat(M, K, N)返回具有相应总体大小的超几何分布的均值和方差, M, 总体中具有所需特征的项目数量K, 以及提取的样本数量N. M,K和N的向量或矩阵输入必须具有相同的大小,这也是MN和V的大小.
M,K或N的标量输入被扩展为与其他输入具有相同维度的常数矩阵.
具有参数M,K和N的超几何分布的平均值为NK/M,方差为NK(M-K)(M-N)/[M^2(M-1)].
M, K, N -- 数值标量, 向量, 矩阵.
示例1:质量控制场景
在生产线质量检测中,从100个产品中随机抽取10个,已知有15个次品
mean, var = hygestat(100, 15, 10)
print(f"质量控制 - 平均抽到次品数: {mean}, 方差: {var}")
#质量控制 - 平均抽到次品数: [1.5], 方差: [1.15909091]
示例2:生物多样性研究
在生态调查中,从50只鸟中捕捉20只,已知其中有标记的鸟有8只
mean, var = hygestat(50, 8, 20)
print(f"生态调查 - 平均捕捉标记鸟数: {mean}, 方差: {var}")
#生态调查 - 平均捕捉标记鸟数: [3.2], 方差: [1.64571429]
示例3:选举预测
在选区中,从10000名选民中抽样500人,已知支持某候选人的选民有4500人
mean, var = hygestat(10000, 4500, 500)
print(f"选举预测 - 平均支持者数: {mean}, 标准差: {var ** 0.5}")
#选举预测 - 平均支持者数: [225.], 标准差: [10.84316639]
示例4:库存管理
仓库中有200件商品,其中30件有瑕疵,随机检查25件
mean, var = hygestat(200, 30, 25)
print(f"库存检查 - 平均瑕疵品数: {mean}, 方差: {var}")
#库存检查 - 平均瑕疵品数: [3.75], 方差: [2.80307789]
示例5:科学研究应用
基因研究中,从1000个基因中筛选50个,已知有致病风险的基因有80个
mean, var = hygestat(1000, 80, 50)
print(f"基因研究 - 平均风险基因数: {mean}, 95%置信区间: [{mean - 2 * var ** 0.5}, {mean + 2 * var ** 0.5}]")
#基因研究 - 平均风险基因数: [4.], 95%置信区间: [[0.25861015], [7.74138985]]
示例6:教育评估
从300名学生中随机选取30名评估,已知优秀学生有45名
mean, var = hygestat(300, 45, 30)
print(f"教育评估 - 平均优秀学生数: {mean}, 变异系数: {(var ** 0.5 / mean) * 100}%")
#教育评估 - 平均优秀学生数: [4.5], 变异系数: [41.29994696]%
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.stats import hypergeom
def hypergeometric_mean_variance(input_str):
"""
计算超几何分布的均值与方差,对标Matlab的hygestat函数。
参数格式:
(M, K, N) -> 返回标量均值与方差
(M_mat, K_mat, N_mat) -> 返回同形状的均值矩阵和方差矩阵
参数说明:
M: 总体大小(必须为正整数)
K: 成功项数量(0 ≤ K ≤ M)
N: 抽样数量(0 ≤ N ≤ M)
返回:
(均值, 方差) 元组,或错误信息字符串
示例:
>>> hypergeometric_mean_variance("(100, 20, 5)")
(4.0, 1.2626262626262625)
>>> hypergeometric_mean_variance("([100, 150], [20, 30], [5, 10])")
(Matrix([[4.0, 6.0]]), Matrix([[1.2626, 2.2222]]))
>>> hypergeometric_mean_variance("(50, 60, 30)")
'错误:K必须在0到M之间'
"""
try:
expr = sp.sympify(input_str)
mean_matrix, var_matrix = None, None
error = False
def compute_stats(M_val, K_val, N_val):
"""核心计算函数"""
# 参数验证
try:
M = int(M_val)
K = int(K_val)
N = int(N_val)
except (TypeError, ValueError):
raise ValueError("参数M、K、N必须为整数")
if M <= 0:
raise ValueError("M必须为正整数")
if not (0 <= K <= M):
raise ValueError("K必须在0到M之间")
if not (0 <= N <= M):
raise ValueError("N必须在0到M之间")
# 计算统计量
dist = hypergeom(M, K, N)
return dist.mean(), dist.var()
# 解析输入参数 -----------------------------------------------------------
if isinstance(expr, tuple) and len(expr) == 3:
M, K, N = expr # 参数顺序对应Matlab的hygestat(M, K, N)
# 标量计算模式
try:
mean, var = compute_stats(M, K, N)
return (mean, var)
except Exception as e:
return f"错误:{str(e)}"
else:
return "输入格式错误:应为三元素元组 (M, K, N)"
except Exception as e:
return f"系统错误:{str(e)}"
# 测试示例
if __name__ == "__main__":
# 标量测试
print(hypergeometric_mean_variance("(100, 20, 5)"))
# (1.0, 0.7676767676767676)
广义超几何函数
hypergeom(a,b,z) 根据输入是浮点还是符号,超几何返回浮点或符号结果。
计算这些数字的超几何函数。因为这些数字是浮点数,所以hypergeom返回浮点结果。
a —— 超几何函数的上参数,数字,向量,符号数字,符号变量,符号表达式,符号函数,符号向量
b —— 超几何函数的下参数,数字,向量,符号数字,符号变量,符号表达式,符号函数,符号向量
z —— 标量,数值,符号变量
示例1:基本数学函数表示
指数函数 e^x 的超几何表示
result1 = hypergeom([], [], x)
print(f"e^x = {result1}")
#e^x = exp(x)
正弦函数的超几何表示
result2 = hypergeom([], [1/2], -x**2/4)
print(f"sin(x) = {result2}")
#sin(x) = cos(x)
贝塞尔函数的超几何表示
result3 = hypergeom([], [1], x)
print(f"J_0(x) = {result3}")
#J_0(x) = besseli(0, 2*sqrt(x))
示例2:概率统计应用
二项分布矩生成函数的超几何表示
result4 = hypergeom([-n], [], -x)
print(f"二项分布MGF: {result4}")
#二项分布MGF: (x + 1)**n
泊松分布相关函数
result5 = hypergeom([1], [2], x)
print(f"泊松相关: {result5}")
#泊松相关: exp(x)/x - 1/x
示例3:物理学应用
量子力学 - 谐振子波函数
result6 = hypergeom([-n], [1/2], x**2)
print(f"谐振子波函数: {result6}")
#谐振子波函数: hyper((-n,), (1/2,), x**2)
电磁学 - 勒让德多项式
result7 = hypergeom([-n, n+1], [1], (1-x)/2)
print(f"勒让德多项式: {result7}")
#勒让德多项式: hyper((-n, n + 1), (1,), 1/2 - x/2)
示例4:工程计算
热传导方程的解
result8 = hypergeom([1/2], [3/2], -x**2)
print(f"误差函数: {result8}")
#误差函数: sqrt(pi)*erf(x)/(2*x)
流体力学 - 边界层方程
result9 = hypergeom([1/3], [4/3], x)
print(f"Airy函数相关: {result9}")
#Airy函数相关: exp(-I*pi/3)*lowergamma(1/3, x*exp_polar(I*pi))/(3*x**(1/3))
示例5:数值计算验证
验证特殊值
import math
计算 log(1+x)/x 在 x=1 处的值
result10 = hypergeom([1, 1], [2], -1)
print(f"log(2) = {result10} = {float(result10.evalf())}")
print(f"验证: math.log(2) = {math.log(2)}")
#log(2) = log(2) = 0.6931471805599453
#验证: math.log(2) = 0.6931471805599453
计算 arctan(x)/x 在 x=1 处的值
result11 = hypergeom([1/2], [3/2], -1)
print(f"π/4 = {result11} = {float(result11.evalf())}")
print(f"验证: math.pi/4 = {math.pi / 4}")
#π/4 = sqrt(pi)*erf(1)/2 = 0.746824132812427
#验证: math.pi/4 = 0.7853981633974483
示例6:组合数学应用
二项式系数生成函数
result12 = hypergeom([-n], [], x)
print(f"二项式定理: {result12}")
#二项式定理: (1 - x)**n
超几何分布的概率生成函数
result13 = hypergeom([-a, -b], [c], 1)
print(f"超几何分布PGF: {result13}")
#超几何分布PGF: gamma(c)*gamma(a + b + c)/(gamma(a + c)*gamma(b + c))
示例7:复杂参数计算
复数参数的计算
result14 = hypergeom([1, 2], [3], 0.5)
print(f"数值计算: {result14.evalf()}")
#数值计算: 1.54517744447956
符号计算保持精确
result15 = hypergeom([1, 2], [3], x)
print(f"符号结果: {result15}")
#符号结果: -2/x - 2*log(1 - x)/x**2
分数参数
result16 = hypergeom([1/2, 1/3], [4/3], 1)
print(f"分数参数: {result16} = {result16.evalf()}")
#分数参数: sqrt(pi)*gamma(4/3)/gamma(5/6) = 1.40218210532545
示例8:级数展开验证
验证超几何级数展开
result17 = hypergeom([1, 2], [3], x)
级数展开
series_expansion = sp.series(result17, x, 0, 6)
print(f"级数展开: {series_expansion}")
#级数展开: 1 + 2*x/3 + x**2/2 + 2*x**3/5 + x**4/3 + 2*x**5/7 + O(x**6)
直接计算前几项验证
manual_sum = 1 + (1 * 2) / (1 * 3) * x + (1 * 2 * 3) / (1 * 2 * 3 * 4) * x ** 2 / 2
print(f"手动计算前3项: {manual_sum}")
#手动计算前3项: 0.125*x**2 + 0.666666666666667*x + 1
示例9:特殊函数关系
合流超几何函数(Kummer函数)
result18 = hypergeom([a], [b], x)
print(f"Kummer函数: {result18}")
#Kummer函数: hyper((a,), (b,), x)
高斯超几何函数
result19 = hypergeom([a, b], [c], x)
print(f"高斯超几何函数: {result19}")
#高斯超几何函数: hyper((a, b), (c,), x)
广义超几何函数 pFq
result20 = hypergeom([1, 1, 1], [2, 2], x)
print(f"3F2函数: {result20}")
#3F2函数: polylog(2, x)/x
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def hypergeometric_function_construct(input_str):
"""
构造并简化广义超几何函数,对标MATLAB的hypergeom函数。
参数:
input_str (str): 输入字符串,格式应为'([a1, a2, ...], [b1, b2, ...], z)',其中:
- a1, a2, ... 是上参数列表
- b1, b2, ... 是下参数列表
- z 是变量或数值
返回:
Sympy表达式: 简化后的超几何函数表达式,或错误信息。
"""
try:
# 将输入字符串解析为Sympy表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查输入是否为三元组(上参数,下参数,z)
if isinstance(expr, tuple) and len(expr) == 3:
# 处理上参数列表
a = tuple(expr[0]) if isinstance(expr[0], list) else (expr[0],)
# 处理下参数列表
b = tuple(expr[1]) if isinstance(expr[1], list) else (expr[1],)
z = expr[2]
# 构造超几何函数
hyper_func = sp.hyper(a, b, z)
# 尝试展开为更简单的表达式
result = sp.hyperexpand(hyper_func)
else:
error = True
return result if not error else f"输入格式错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:符号参数,返回未简化形式
input1 = '(a,[],x)'
result1 = hypergeometric_function_construct(input1)
print(f"示例1结果: {result1}")
# (1 - x)**(-a)
# 示例2:可简化的超几何函数
input2 = '([1, 1], [2], -x)'
result2 = hypergeometric_function_construct(input2)
print(f"示例2结果: {result2}")
# log(x + 1)/x
# 示例3:数值参数,返回符号表达式(如需要数值结果可调用.evalf())
input3 = '([1, 1], [2], -1)'
result3 = hypergeometric_function_construct(input3)
print(f"示例3符号结果: {result3}")
# log(2)
print(f"示例3数值结果: {result3.evalf()}")
# 0.693147180559945
平方和的平方根(斜边)
C = hypot(A,B)返回以下方程的计算结果(计算是为了避免下溢或上溢): C = sqrt(abs(A)^2 + abs(B)^2)
A,B — 输入数组,标量,向量,矩阵,多维数组
示例1:几何计算
计算直角三角形的斜边
result1 = hypot(3, 4)
print(f"直角三角形斜边: {result1}")
#直角三角形斜边: 5.0
计算三维空间中的对角线长度
result2 = hypot(3, 4)
z = 12
distance_3d = np.sqrt(result1**2 + z**2)
print(f"三维空间对角线: {distance_3d}")
#三维空间对角线: 13.0
示例2:物理学应用
计算力的合成(两个垂直分力)
force_x = 8 # x方向分力
force_y = 6 # y方向分力
result3 = hypot(force_x, force_y)
print(f"合力大小: {result3} N")
#合力大小: 10.0 N
计算速度合成
v_x = 3 # x方向速度
v_y = 4 # y方向速度
result4 = hypot(v_x, v_y)
print(f"合速度大小: {result4} m/s")
#合速度大小: 5.0 m/s
示例3:工程测量
计算建筑物对角线测量
building_length = 50 # 长度
building_width = 30 # 宽度
result5 = hypot(building_length, building_width)
print(f"建筑物对角线: {result5} 米")
#建筑物对角线: 58.309518948453004 米
计算斜坡的实际长度
horizontal_distance = 100 # 水平距离
vertical_rise = 10 # 垂直升高
result6 = hypot(horizontal_distance, vertical_rise)
print(f"斜坡实际长度: {result6} 米")
#斜坡实际长度: 100.4987562112089 米
示例4:计算机图形学
计算像素点到原点的距离
pixel_x = 1920
pixel_y = 1080
result7 = hypot(pixel_x, pixel_y)
print(f"屏幕对角线像素数: {result7}")
#屏幕对角线像素数: 2202.9071700822983
计算向量长度(多个点)
vectors = ([[1, 2], [3, 4]], [[4, 3], [2, 1]])
result8 = hypot(vectors)
print("向量长度矩阵:")
print(result8)
#向量长度矩阵:
#[[4.12310563,3.60555128]
[3.60555128,4.12310563]]
示例5:统计学应用
计算欧几里得距离(二维数据点)
point1 = [2, 3]
point2 = [5, 7]
diff_x = point2[0] - point1[0]
diff_y = point2[1] - point1[1]
result9 = hypot(diff_x, diff_y)
print(f"两点间欧几里得距离: {result9}")
#两点间欧几里得距离: 5.0
计算误差向量的模
measurement_errors = ([0.1, -0.2, 0.05], [0.15, 0.1, -0.08])
result10 = hypot(measurement_errors)
print(f"误差向量模长: {result10}")
#误差向量模长: [0.18027756 0.2236068 0.09433981]
示例6:电子工程
计算交流电路的阻抗
resistance = 3 # 电阻 (Ω)
reactance = 4 # 电抗 (Ω)
result11 = hypot(resistance, reactance)
print(f"电路阻抗: {result11} Ω")
#电路阻抗: 5.0 Ω
计算信号幅度(I/Q分量)
I_component = 0.8 # 同相分量
Q_component = 0.6 # 正交分量
result12 = hypot(I_component, Q_component)
print(f"信号幅度: {result12}")
#信号幅度: 1.0
示例7:导航和定位
计算GPS坐标间的平面距离(近似)
lat_diff = 0.01 # 纬度差(度)
lon_diff = 0.02 # 经度差(度)
result13 = hypot(lat_diff, lon_diff)
print(f"坐标间近似距离: {result13} 度")
#坐标间近似距离: 0.022360679774997897 度
计算机器人移动路径
movement_x = [1, 2, 3, 4] # x方向移动
movement_y = [2, 3, 1, 5] # y方向移动
result14 = hypot(movement_x, movement_y)
print("各步移动距离:")
print(result14)
#各步移动距离:
#[2.23606798,3.60555128,3.16227766,6.40312424]
示例8:金融分析
计算投资组合的风险(简化模型)
stock_risk = 0.15 # 股票风险
bond_risk = 0.08 # 债券风险
假设股票和债券风险不相关
result15 = hypot(stock_risk, bond_risk)
print(f"投资组合总风险: {result15:.3f}")
#投资组合总风险: 0.170
计算价格变动的幅度
price_changes_x = [1.5, -2.0, 0.8] # 资产A价格变化
price_changes_y = [0.5, 1.2, -0.3] # 资产B价格变化
result16 = hypot(price_changes_x, price_changes_y)
print("价格变动幅度:")
print(result16)
#价格变动幅度:
#[1.58113883,2.33238076,0.85440037]
示例9:批量处理实际数据
处理多个三角形的斜边计算
triangles = ([[3, 6, 9], [5, 8, 12]], [[4, 8, 12], [12, 15, 16]])
result17 = hypot(triangles)
print("多个三角形的斜边:")
print(result17)
#多个三角形的斜边:
#[[5,10,15]
[13,17,20]]
计算复杂形状的对角线
complex_shape = ([10, 20, 30, 40], [15, 25, 35, 45])
result18 = hypot(complex_shape)
print("复杂形状对角线:")
print(result18)
#复杂形状对角线:
#[18.02775638,32.01562119,46.09772229,60.20797289]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def hypotenuse_calculate(input_str):
"""
对标MATLAB hypot函数计算直角三角形的斜边
参数:
input_str (str): SymPy可解析的字符串,格式为:
(n, x) 其中n和x可以是标量或矩阵
返回:
Matrix/float: 计算结果矩阵或标量
"""
try:
expr = sp.sympify(input_str)
error = False
# 检查输入是否为二元组
if not isinstance(expr, tuple) or len(expr) != 2:
return f"输入错误: 需要两个参数 {input_str}"
# 参数解析
a, b = expr[0], expr[1]
# 转换为numpy数组(支持标量和矩阵)
def to_ndarray(val):
if isinstance(val, list):
return np.array(val, dtype=float)
elif isinstance(val, sp.Number):
return float(val)
else:
return None
np_a = to_ndarray(a)
np_b = to_ndarray(b)
if np_a is None or np_b is None:
return f"参数类型错误: 需要数值或矩阵 {input_str}"
# 计算斜边(自动处理广播)
result = np.hypot(np_a, np_b)
# 转换回SymPy格式
if isinstance(result, np.ndarray):
return sp.Matrix(result.tolist())
else:
return float(result)
except Exception as e:
return f"错误: {str(e)}"
# 案例1:标量计算
print(hypotenuse_calculate("(3, 4)"))
# → 5.0
# 案例2:矩阵与标量
print(hypotenuse_calculate("([3,4], 4)"))
# Matrix([[5.00000000000000],
# [5.65685424949238]])
# 案例3:矩阵广播
print(hypotenuse_calculate("([[1,2],[3,4]], [5,6])"))
# Matrix([[5.09901951359278, 6.32455532033676],
# [5.83095189484530, 7.21110255092798]])