基于SymPy动态生成符号求解移动发射机速度的非线性方程组方法
实现方案
动态生成符号变量方法
SymPy原生支持批量生成序列符号,直接调用sp.symbols传入序列格式的命名规则即可,不需要手动逐个定义:
- 首先从输入的
arrival_times中获取脉冲总数量n = len(arrival_times) - 调用
t = sp.symbols(f't1:{n+1}')即可生成长度为n的符号列表,其中t[i]对应第i+1个脉冲的发射时间t_{i+1}
完整实现示例
import sympy as sp def find_transmitter(arrival_times, receiver_coords, c=3e8): # 1. 获取基础维度参数 n_pulse = len(arrival_times) # 脉冲数量 n_receiver = len(arrival_times[0]) # 接收机数量,固定为3 # 2. 定义所有符号变量 # 动态生成脉冲发射时间符号 t = sp.symbols(f't1:{n_pulse+1}') # 固定未知量:初始位置x0、速度v x0, y0, z0 = sp.symbols('x0 y0 z0') vx, vy, vz = sp.symbols('vx vy vz') # 接收机坐标解包 p = [sp.Matrix(coord) for coord in receiver_coords] x0_vec = sp.Matrix([x0, y0, z0]) v_vec = sp.Matrix([vx, vy, vz]) equations = [] # 3. 批量构建方程组 for i in range(n_pulse): ti = t[i] # 第i个脉冲发射时的发射机位置 pos_i = x0_vec + v_vec * (ti - t[0]) for r in range(n_receiver): # 测量得到的到达时间air air = arrival_times[i][r] # 构建等式:c²*(air - ti)² = ||pos_i - p[r]||² left = c**2 * (air - ti)**2 right = (pos_i - p[r]).dot(pos_i - p[r]) equations.append(sp.Eq(left, right)) # 4. 求解方程组 # 未知数顺序可根据需要调整 unknowns = [vx, vy, vz, x0, y0, z0] + list(t) solution = sp.solve(equations, unknowns, dict=True) # 过滤符合物理意义的解(可选) valid_solutions = [] for sol in solution: # 可添加过滤规则:时间非负、速度在合理区间等 valid = True for ti in t: if sol[ti] < 0: valid = False break if valid: valid_solutions.append(sol) return valid_solutions
使用示例
# 示例参数:3台接收机坐标 receivers = [ [0, 0, 0], [1000, 0, 0], [0, 1000, 0] ] # 示例到达时间数据:3个脉冲 arrival = [ [1e-6, 1.001e-6, 1.002e-6], [2e-6, 2.001e-6, 2.002e-6], [3e-6, 3.001e-6, 3.002e-6] ] solutions = find_transmitter(arrival, receivers) for sol in solutions: print("速度v:", [sol['vx'], sol['vy'], sol['vz']])
注意事项
- 非线性方程组可能存在多解,建议根据业务场景添加过滤规则筛选符合物理意义的结果
- 3台接收机场景下,至少需要3个脉冲才能得到定解,脉冲数量越多求解稳定性越高
- 如果测量数据存在噪声,建议改用数值求解方法(比如
scipy.optimize.least_squares)替代SymPy的符号求解,符号求解仅适合理想无噪的小规模场景。
内容的提问来源于stack exchange,提问作者10GeV
相关产品推荐
相关产品推荐

