Как упростить уравнение симпи?

Рассмотрим это простое матричное уравнение:

from sympy import *

c_a, s_a = symbols('c_a s_a')
k_1, k_2, k_3, k_4, k_5, k_6 = symbols('k_1 k_2 k_3 k_4 k_5 k_6')
x,y,z = symbols('x y z')

equation = Eq(MatrixSymbol('R',4,4), Matrix([
[     c_a*k_1 - k_1 + 1, -c_a*k_4 + k_4 - s_a*z, -c_a*k_5 + k_5 + s_a*y,         0],
[-c_a*k_4 + k_4 + s_a*z,      c_a*k_2 - k_2 + 1, -c_a*k_6 + k_6 - s_a*x,         0],
[-c_a*k_5 + k_5 - s_a*y, -c_a*k_6 + k_6 + s_a*x,      c_a*k_3 - k_3 + 1,         0],
[                     0,                      0,                      0, c_a + s_a]]))

Некоторое время я пытался упростить, но безуспешно ... как видите, существует множество возможных факторизаций (например: k_1*(c_a-1), k_4(1-c_a), ...). Я пробовал многие из существующих доступных методов sympy для упрощения https://docs.sympy.org/latest/tutorial/simplification.html, но не повезло ... фактор, упрощение, сбор, применение функций (фактор), упрощение (сила = Истина) и т. д.

Я новичок в sympy, поэтому, вероятно, есть какой-то очевидный способ еще больше упростить этот тип уравнений, если это так, то как?

Кроме того, мне просто интересно упростить rhs уравнения, а не lhs. Можно ли упростить любой из них или оба?


person BPL    schedule 01.05.2020    source источник
comment
Может быть, скорее математическая проблема?   -  person Torxed    schedule 01.05.2020
comment
Я пришел сюда и подумал: да, я постараюсь ответить! Потом я увидел уравнение и испугался ;-)   -  person xilpex    schedule 01.05.2020
comment
@Torxed Сначала я подумал, что это будет для сайта обмена математическим стеком, но потом решил, что это не так. Речь идет о том, что я не могу правильно использовать sympy ... что я почти уверен, что это может решить эту простую проблему без особых усилий ...: /   -  person BPL    schedule 01.05.2020


Ответы (1)


Это случай, сделанный своими руками. У вас может сработать что-то вроде следующего:

>>> def most_collect(eq):
...     f = eq.free_symbols
...     if not f: return eq
...     F = sorted(f, key=lambda x: eq.count(x))
...     return collect(eq, F[-1])
>>> equation.rhs.applyfunc(most_collect)
Matrix([
[    k_1*(c_a - 1) + 1, k_4*(1 - c_a) - s_a*z, k_5*(1 - c_a) + s_a*y,         0],
[k_4*(1 - c_a) + s_a*z,     k_2*(c_a - 1) + 1, k_6*(1 - c_a) - s_a*x,         0],
[k_5*(1 - c_a) - s_a*y, k_6*(1 - c_a) + s_a*x,     k_3*(c_a - 1) + 1,         0],
[                    0,                     0,                     0, c_a + s_a]])
person smichr    schedule 01.05.2020
comment
Спасибо, сэр! Действительно хороший ответ, он действительно работает для меня ... кстати, я предполагаю, что вы симпатичный ниндзя, так что ... могу я спросить, когда вы решите, что сейчас хорошее время для рассмотрения дела DIY? Как симпатичный новичок, я начал с использования simpleify (который, как я читал, использовал некоторые эвристики), а затем просто использовал встроенные функции ... Для этой простой формулы было очевидно, что мы могли бы сделать лучше для более сложных ... откуда вы знаете ты не получил от симпи все самое лучшее? Кстати ... оффтопный вопрос, а есть ли простой способ извлечь имеющиеся символы из одного уравнения? - person BPL; 01.05.2020
comment
Матрица - это набор выражений, и в вашем случае у каждого из них был шаблон - символ, встречающийся более чем в одном термине, - который не включал каждый раз один и тот же символ. Так что это не обычная ситуация. Вы знаете, что не получили лучшего, когда вам не нравится то, что у вас есть ;-) Что касается извлечения доступных символов: см. Использование функцией eq.free_symbols; этот атрибут дает набор всех используемых несвязанных символов. - person smichr; 01.05.2020