54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
import numpy as np
|
|
|
|
def generate_laguerre_basis(poles:list|np.ndarray, s: np.ndarray):
|
|
basis = np.zeros((len(poles)+1,len(s)),dtype=complex)
|
|
|
|
product = np.ones(len(s),dtype=complex)
|
|
|
|
basis[0] = np.ones(len(s),dtype=complex) # φ_0 = 1
|
|
i = 0
|
|
while i < len(poles):
|
|
if np.real(poles[i]) >= 0:
|
|
raise ValueError(f"极点必须在左半平面: {poles[i]}")
|
|
|
|
# 复对首 (正虚部)
|
|
if np.iscomplex(poles[i]) and np.imag(poles[i]) > 0:
|
|
if i + 1 >= len(poles):
|
|
raise ValueError("复极点缺少共轭")
|
|
pc = poles[i + 1]
|
|
if not np.isclose(pc, np.conj(poles[i])):
|
|
raise ValueError("复极点未按 (p, p*) 顺序排列 (正虚部在前)")
|
|
sigma = -np.real(poles[i]) # >0
|
|
scale = np.sqrt(2 * sigma)
|
|
r = np.abs(poles[i])
|
|
denom = (s - poles[i]) * (s - pc)
|
|
|
|
# 两个基函数
|
|
phi_p = scale * (s - r) / denom * product
|
|
phi_pc = scale * (s + r) / denom * product
|
|
|
|
# product 先乘 (s + p^*)/(s - p),再乘 (s + p)/(s - p^*)
|
|
product = product * (s + pc) / (s - poles[i])
|
|
product = product * (s + poles[i]) / (s - pc)
|
|
|
|
basis[i + 1] = phi_p
|
|
basis[i + 2] = phi_pc
|
|
i += 2
|
|
continue
|
|
|
|
# 复对次 (负虚部) —— 应该被首元素处理,出现表示顺序错误
|
|
if np.iscomplex(poles[i]) and np.imag(poles[i]) < 0:
|
|
raise ValueError("检测到负虚部复极点但其共轭尚未处理,请将正虚部成员放在前面。")
|
|
|
|
# 实极点
|
|
sigma = -np.real(poles[i])
|
|
if sigma <= 0:
|
|
raise ValueError("实极点实部应为负 (稳定)。")
|
|
scale = np.sqrt(2 * sigma)
|
|
phi = scale / (s - poles[i]) * product
|
|
# 更新乘积
|
|
product = product * (s + poles[i]) / (s - poles[i])
|
|
i += 1
|
|
basis[i + 1] = phi
|
|
return basis
|