我最近在 Math SE 上問了這個關于求解非線性方程組的問題。我現在正在嘗試使用SymPyin實作已接受的答案Python。我將首先在這里簡要地重新創建解決方案。
問題。
假設我有三個接收器,通過載體給定的坐標p1,p2和p3。此外,我有一個發射器,它在未知時間t1, t2, t3, t4, ...以已知速度發射無線電脈沖c,它t = t1在向量給定的時間具有未知的初始坐標,并以向量給定x0 = <x,y,z>的未知恒定速度移動v。我的資料包括每個站的脈沖到達時間,表示為air(信號i到達接收器的時間r)。
我的目標是確定這個速度。所附答案中給出的解決方案如下:
發送器在時間的位置
t將由 給出xo = v(t - t1)。因此,發射脈沖時發射器和rth接收器之間的距離ith將由下式給出:
||(ti - t1)v x0 - pr||因此,到達
rth接收器的時間由下式給出:
ti (1/c) * ||(ti - t1)v x0 - pr||我們知道是
air。所以:
c**2(air - ti)**2 = ||v||**2(ti - t1)**2 2(ti -t1)<v, c0 - pr>(其中
<a, b>表示向量a和 的標量/點積b)。這導致了一個
# receivers x # pulses方程組。
(有關更好的格式,請參閱隨附的答案)
執行。
我最熟悉這個SymPy包,所以我試圖使用它的求解器來實作一個解決方案。然而,我對從哪里開始有點困惑。
脈沖數事先未知,因此作為SymPy符號求解器,我必須能夠動態定義變數t1, t2, t3... tn。
我對實作的粗略概述如下:
import sympy as sp
def find_transmitter(arrival_times):
equations = []
for receiver in arrival_times:
for pulse in arrival_times:
equations.append(sp.Eq(c**2(pulse - ti...
sp.solve(equations...
其中arrival_times是一個串列,其中每一列對應一個接收器,每一行對應一個脈沖。IE:
[[a11, a21, a31...],[a12, a22, a32...],[a13, a23, a33...]]
我沒有想到這種方法有一個很好的替代方案。但是,我不確定,例如如何動態定義足夠的ti's 并遍歷它們。也就是說,例如,我將有一個未知數量的方程,如下所示:
equations.append(sp.Eq(c**2(pulse - t1...
equations.append(sp.Eq(c**2(pulse - t2...
equations.append(sp.Eq(c**2(pulse - t3...
equations.append(sp.Eq(c**2(pulse - t4...
equations.append(sp.Eq(c**2(pulse - t5...
.
.
.
有沒有很好的方法來做到這一點?很可能,我忽略了一些明顯的解決方案。
uj5u.com熱心網友回復:
也許令人驚訝的是,可以symbols使用空格作為分隔符動態創建任意數量的符號!
你也可以用下標 _N
arrival_times_count = 100 # from data length
chunksize = 10 # some factor of arrival_times_count
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i n]
from sympy import *
# create a huge collection
collection = symbols(" ".join(f"t_{x}" for x in range(arrival_times_count)), real=True)
# fold it into rows
collection = list(chunks(collection, chunksize))
>>> for row in collection:
... print(row)
...
(t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9)
(t_10, t_11, t_12, t_13, t_14, t_15, t_16, t_17, t_18, t_19)
(t_20, t_21, t_22, t_23, t_24, t_25, t_26, t_27, t_28, t_29)
(t_30, t_31, t_32, t_33, t_34, t_35, t_36, t_37, t_38, t_39)
(t_40, t_41, t_42, t_43, t_44, t_45, t_46, t_47, t_48, t_49)
(t_50, t_51, t_52, t_53, t_54, t_55, t_56, t_57, t_58, t_59)
(t_60, t_61, t_62, t_63, t_64, t_65, t_66, t_67, t_68, t_69)
(t_70, t_71, t_72, t_73, t_74, t_75, t_76, t_77, t_78, t_79)
(t_80, t_81, t_82, t_83, t_84, t_85, t_86, t_87, t_88, t_89)
(t_90, t_91, t_92, t_93, t_94, t_95, t_96, t_97, t_98, t_99)
chunks函式來自如何將串列拆分為大小均勻的塊?
然而,有一個很好的機會,這是一個XY的問題,你可能會更好做這樣的事情打包資料成pandas.DataFrame,lambdifying你的公式,然后打電話.apply()找每一行的結果
uj5u.com熱心網友回復:
動態定義變數的一種骯臟方法是創建一個字串模式(使用 python 代碼),然后使用exec. 因此,您無需通過串列、元組等即可訪問變數……最好的方法是使用替換(向量 -> 組件),因此您可以使用向量和 Lambdify 來執行組件操作。
from sympy import *
n = 4
t_s = ( ''.join((i, str(j))) for i, j in zip('t'*n, range(1, n 1)))
exec( f"{', '.join(t_s)} = symbols('t1:{n 1}')")
print(t2, type(t2))
輸出
t2 <class 'sympy.core.symbol.Symbol'>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/346251.html
