生成方程组

时间:2016-06-04 22:14:52

标签: python

我试图创建一个能够生成在单独程序中求解的方程组的函数。方程式由同位素衰变树生成,但为简单起见,我有以下树:

decay tree

所以这可以成为2个可能的衰变链:

[(A,0,1,5), (B,1,.4,4), (C,0,.4,0)]

[(A,0,1,5), (B,1,.6,6), (C,0,.6,0)]

格式为(种类,数量,衰变概率,半衰期)。我试图制作一个能自动为衰变树建立方程组的函数,这可能比这更复杂。对于任何树,规则都是相同的:

对于某些具有父母Y_1,Y_2,...,Y_n的物种X:

X_final =每个父物种的总和(Y_n衰减的概率 - > X * Y_n的量/ Y_n的半衰期) - X的量/ X的半衰期,可以表示为:

equation

并且链中的每个物种将具有其自己的等式以便稍后解决。所以为此,我想要以下方程组:

A_f = - A_i/5
B1_f = .4 * A_i/5 - B1_i / 4
B2_f = .6 * A_i/5 - Β2_i / 6
C = B1_i / 4 + B2_i / 6

此外,如果半衰期为0,则表示它是稳定的。目前,我通过制作字符串字典来生成方程系统,但我认为有更好的方法。在我用字符串制作系统之后,我计划稍后将字符串转换为变量。这是我的代码:

A = 'A'
B = 'B'
C = 'C'
D = 'D'

chain1 = [(A,0,1,5),(B,1,.4,4),(C,0,.4,0),(D,0,.4,0)]
chain2 = [(A,0,1,5),(B,2,.6,6),(C,0,.6,0),(D,0,.6,0)]
master_chain = [chain1, chain2]

def equation_builder(master_chain):
    master_equations = {}
    m = 0
    for chain in master_chain:
        n = 0
        for item in chain:
            if item == chain[0]:
                equation = {str(item[0]) + str(item[1]) + 'f' :\
                '-' +  str(item[0]) + str(item[1])  + 'i/' +  str(item[3])}
                master_equations.update(equation)
            elif str(item[0])+str(item[1])+'f' not in master_equations:
                equation = {str(item[0]) + str(item[1]) + 'f' :\
                str(item[2]/chain[n-1][2])+str(chain[n-1][0]) + 
                str(chain[n-1][1])+'i/' + str(chain[n-1][3])+\
                '-'+str(item[0])+str(item[1])+'i/'+str(item[3])}
                master_equations.update(equation)
            elif str(item[0])+str(item[1])+'f' in master_equations \
            and master_chain[m-1][n-1] != master_chain[m][n-1]:
                old_equation = master_equations[str(item[0])+str(item[1])+'f']
                new_equation = old_equation + '+' +\
                str(item[2]/chain[n-1][2])+str(chain[n-1][0]) +\
                str(chain[n-1][1])+'i/' + str(chain[n-1][3])
                equation = {str(item[0])+str(item[1])+'f' : new_equation}
                master_equations.update(equation)
            n += 1
        m += 1

    return master_equations

if __name__ == '__main__':
    print equation_builder(master_chain)

1 个答案:

答案 0 :(得分:4)

使用SymPy。 SymPy是一个符号计算工具箱,非常适合这个用例。您可以使用A = sympy.Symbol("A")创建符号,然后在表达式中使用A,就像使用任何变量一样。例如,如果AB是符号,那么如果您写C=A*exp(B)print C将输出A*exp(B)。使用表达式的args属性,您还可以访问任何表达式的语法树表示,如果您想进一步处理方程式,这可能很有用。

这是一个使用你的图表的例子(我不太明白你是如何得出结果的,所以这可能需要一些调整,但它应该足以得到这个想法):

import sympy as sp

A, B1, B2, C = sp.symbols("A, B1, B2, C")

chain1 = [(A,0,1,5),(B1,1,.4,4),(C,0,0.4,0)]
chain2 = [(A,0,1,5),(B2,2,.6,6),(C,0,0.6,0)]
master_chain = [chain1, chain2]

finals = {}
for subchain in master_chain:
    for i, (species, number, decay_prob, half_life) in enumerate(subchain):
        input_species = sp.Symbol(str(species) + "_i")
        if species not in finals:
            finals[species] = -input_species / half_life if half_life else 0
        if i < len(subchain) - 1:
            (other_species, other_number, other_decay_prob, other_half_life) = subchain[i+1]
            if other_species not in finals:
                finals[other_species] = -sp.Symbol(str(other_species) + "_i") / other_half_life if other_half_life else 0
            finals[other_species] += input_species * decay_prob / half_life

print finals

输出

{C: 0.1*B1_i + 0.1*B2_i, B2: A_i/5 - B2_i/6, A: -A_i/5, B1: A_i/5 - B1_i/4}

请注意Symbol("x") == Symbol("x"),例如,符号由其字符串表示形式标识,因此您可以在每次需要时安全地重新创建符号。