Python:列出代数简化

时间:2016-07-03 10:17:26

标签: python list sympy simplify

您好我正在尝试获取列表的常用术语以简化它,例如,如果我的列表是:

     $scope.open = function (size) {
        //call a function that sets CSS property to transparent        
        $scope.setCSSTotransparent();
        var modalInstance = $uibModal.open({
          animation: $scope.animationsEnabled,
          templateUrl: 'myModalContent.html',
          controller: 'ModalInstanceCtrl',
          size: size,
          resolve: {
            items: function () {
              return $scope.items;
            }
          }
        });

是否有任何功能可以作为结果:

List=[['1','A1','B1','Kc','Ka'],['1','A1','B1','D2','Kc','Ka'],['-1','A1','B1','D1','Kc','Ka'],['1','A1','B1','D1','KD','Ka'],['-1','B1','D1','C1','Kc','Ka','KF'],['1','B1','D1','F1','Kc','Kz','Kl']]    

我基本上想要做的是代数减少。

A1 B1 Kc Ka + A1 B1 D2 Kc Ka -A1 B1 D1 Kc Ka + A1 B1 D1 KD Ka - B1 D1 C1 Kc Ka KF + B1 D1 F1 Kc Kz Kl

= A1B1 [D1 [-KcKa + KDKa] + D2KcKa + KcKa] + B1D1 [-C1 [KcKaKF] + F1 [KcKzKl]]

简化的唯一要求是简化的所有术语都需要依赖于K的总和或其余部分。换句话说,一切都需要是K的线性组合的函数; [-KcKa + KDKa]; [KcKaKF] = [[ ' - 1', '的Kc', '嘉'],[ '+ 1', 'KD', '嘉']]; [ '1', '的Kc', '嘉', 'KF']

我尝试使用Sympy,但我遇到的问题是减少的术语来自设备所以我永远不知道符号是什么,并且使用sympy你需要声明符号。任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

首先,将列表转换为SymPy表达式:

In [1]: List=[['1','A1','B1','Kc','Ka'],['1','A1','B1','D2','Kc','Ka'],['-1','A1','B1','D1','Kc','Ka'],['1','A1','B1','D1','KD','Ka'],['-1','B1','D1','C1','Kc','Ka','KF'],['1','B1','D1','F1','Kc','Kz','Kl']]

In [2]: list_add_mul = sympify(List)

In [4]: expr = Add(*map(lambda x: Mul(*x), list_add_mul))

In [5]: expr
Out[5]: 
A₁⋅B₁⋅D₁⋅KD⋅Ka - A₁⋅B₁⋅D₁⋅Ka⋅Kc + A₁⋅B₁⋅D₂⋅Ka⋅Kc + A₁⋅B₁⋅Ka⋅Kc - B₁⋅C₁⋅D₁⋅KF⋅K
a⋅Kc + B₁⋅D₁⋅F₁⋅Kc⋅Kl⋅Kz

现在 expr 是您要使用的SymPy表达式。如果您只想替换某些值,请使用 .subs

请记住定义您要使用的符号:

>>> var("Ka, Kc, Kz")

然后你可以替换:

In [6]: expr.subs({Ka: 25.0, Kc: 7.0, Kz: 3.5})
Out[6]: 
25.0⋅A₁⋅B₁⋅D₁⋅KD - 175.0⋅A₁⋅B₁⋅D₁ + 175.0⋅A₁⋅B₁⋅D₂ + 175.0⋅A₁⋅B₁ - 175.0⋅B₁⋅C₁
⋅D₁⋅KF + 24.5⋅B₁⋅D₁⋅F₁⋅Kl

否则,您可以尝试为变量定义替换规则。例如,将它们放在 dict

{
    Ka: ... ,
    Kc: ... ,
    KD: ... ,
    KF: ... ,
}

您应该使用包含新变量的合适表达式替换 dots 。这些新变量应代表 K 常量的组合。

例如: c1 = -Kc * Ka + KD * Ka ,_ c2 = ... _然后你将这些方程反转。

在您的情况下,您的表达似乎无法正确反转:

>>> solve([Eq(-Kc*Ka + KD*Ka, c1 ), Eq(Kc*Ka*KF, c2), Eq(-Kc*Ka + KD*Ka, c3), Eq(Kc*Ka*KF, c4)], Ka, Kc, KD, KF)
[]

答案 1 :(得分:0)

我想你知道你想要做什么样的代数操作,但你是否因为没有同情心来获得“K”符号? Sympy非常适合猜测变量名称。你可以构造表达式:

In [1]: import sympy

In [2]: List=[['1','A1','B1','Kc','Ka'],['1','A1','B1','D2','Kc','Ka'],['-1','A
   ...: 1','B1','D1','Kc','Ka'],['1','A1','B1','D1','KD','Ka'],['-1','B1','D1',
   ...: 'C1','Kc','Ka','KF'],['1','B1','D1','F1','Kc','Kz','Kl']]    

In [3]: expression = sympy.Add(*[sympy.Mul(*[sympy.S(y) for y in x]) for x in L
   ...: ist] )

In [4]: expression
Out[4]: A1*B1*D1*KD*Ka - A1*B1*D1*Ka*Kc + A1*B1*D2*Ka*Kc + A1*B1*Ka*Kc - B1*C1*D1*KF*Ka*Kc + B1*D1*F1*Kc*Kl*Kz

然后获取符号列表:

In [5]: all_symbols = [x for x in expression.atoms() if type(x)==sympy.Symbol]

In [6]: all_symbols
Out[6]: [Kc, B1, KF, A1, Kz, Ka, D1, C1, F1, D2, KD, Kl]

一旦你有了符号列表,抓住以'K'开头的那些符号就很简单了:

In [7]: solvefor = [x for x in all_symbols if str(x)[0]!="K"]

In [8]: solvefor
Out[8]: [B1, A1, D1, C1, F1, D2]

In [9]: sympy.horner(expression, wrt=solvefor)
Out[9]: B1*(A1*(D1*(KD*Ka - Ka*Kc) + D2*Ka*Kc + Ka*Kc) + D1*(-C1*KF*Ka*Kc + F1*Kc*Kl*Kz))