Примечание: я новичок в симпати и пытаюсь понять, как это работает.
Что у меня сейчас: Я получаю правильные решения, но мне нужно 35 - 50 секунд.
Цель: Чтобы ускорить вычисления, определив уравнение symboli c один раз, а затем повторно используя его с различными переменными.
Настройка: Мне нужно вычислить полином G (t) (t = 6 корней) для каждой итерации l oop. (Всего 220 итераций) G (t) имеет 6 других переменных, которые вычисляются и известны на каждой итерации. Эти переменные отличаются на каждой итерации.
Первая попытка (медленно): Я просто помещаю каждую в одну python функцию, где я определил Gt символически и решил для т . Он работал около 35-40 секунд. function_G вызывается на каждой итерации.
def function_G(f1, f2, a, b, c, d):
t = sp.symbols('t')
left = t * ((a * t + b)**2 + f2**2 * (c*t+d)**2)**2
right = (a*d-b*c) * (1+ f1**2 * t**2)**2 * (a*t+b) * (c*t+d)
eq = sp.expand(left - right)
roots = sp.solveset(Gt, t)
return roots
- Тогда человек дал мне подсказку, что:
Вам нужно только (символически ) определите коэффициенты многочлена один раз, как шаг предварительной обработки. После этого, при обработке каждой итерации, вы просто вычисляете коэффициенты полинома, а затем решаете для корней.
- Я попросил уточнить, кто добавил:
Итак, я определил функцию g (t), а затем использовал sympy.expand для определения всех скобок / показателей степени, а затем sympy.collect для сбора терминов по степеням t. Наконец, я использовал .coeff на выходе команды collect, чтобы получить коэффициенты для подачи в numpy. root.
Вторая попытка: Чтобы следовать совету, я определил G (t) сначала символически и передал его функции, которая запускает l oop вместе с его параметрами symboli c. Таким образом, функция constructGt () вызывается только один раз.
def constructGt():
t, a, b, c, d, f1, f2 = sp.symbols('t a b c d f1 f2')
left = t * ((a * t + b)**2 + f2**2 * (c*t+d)**2)**2
right = (a*d-b*c) * (1+ f1**2 * t**2)**2 * (a*t+b) * (c*t+d)
gt = sp.Eq(left - right, 0)
expanded = sp.expand(gt)
expanded = sp.collect(expanded, t)
g_vars = {
"a": a,
"b": b,
"c": c,
"d": d,
"f1": f1,
"f2": f2
}
return expanded, g_vars
, затем на каждой итерации я передавал функцию и ее параметры для получения корней:
#Variables values:
#a = 0.00011713490404073987
#b = 0.00020253296124588926
#c = 4.235688216068313e-07
#d = 0.012262546040805029
#f1= -0.012553203944721956
#f2 = 0.018529776776949003
def function_G(f1_, f2_, a_, b_, c_, d_, Gt, v):
Gt = Gt.subs([(v['a'], a_), (v['b'], b_),
(v['c'], c_), (v['d'], d_),
(v['f1'], f1_), (v['f2'], f2_)])
roots = sp.solveset(Gt, t)
return roots
Но она становилась еще медленнее около 56 секунд.
Вопрос: Я не понимаю, что я делаю не так? Я также не понимаю, как этот человек использует .coeff (), а затем np.roots на результаты.