2012-02-29 25 views
15

Estoy codificando una función que resuelve un número arbitrario de ecuaciones simultáneas. El número de ecuaciones se establece mediante uno de los parámetros de la función y cada ecuación se construye a partir de una serie de símbolos, tantos símbolos como ecuaciones hay. Esto significa que no puedo simplemente codificar las ecuaciones, o incluso los símbolos necesarios para armar las ecuaciones; la función necesita ser capaz de manejar cualquier cantidad de ecuaciones. Entonces, mi pregunta es, ¿cómo puedo producir una lista de símbolos?SymPy - Número arbitrario de símbolos

Tengo una posible solución, pero mi instinto me dice que no va a ser muy eficiente. Por favor, avíseme si hay una mejor manera de hacerlo.

Soy nuevo en SymPy y sigo sintiendo lo que quiero decir. Por lo que puedo ver, los símbolos deben definirse con una cadena. Por lo tanto, puedo producir cadenas de serie agregando un número incremental a una letra (digamos 't0', 't1', etc.), agregarlas a una lista y luego crear los símbolos usando esas cadenas como parámetros. Esos símbolos se almacenarían en una lista y se usarían para producir las ecuaciones.

def solveEquations(numEquations): 
    symbolNameList = [] 
    symbolList = [] 
    equationList = [] 
    for i in range(numEquations): 
     name = 't' + str(i) 
     symbolNameList.append(name) 
     symbolList.append(Symbol(name)) 

    for i in range(numEquations): 
     equation = 0 
     for sym in symbolList: 
      equation += sym ** i # Or whatever structure the equation needs 
     equationList.append(equation) 


    #Then go on to solve the equations... 

¿Es esta la mejor manera de hacerlo, o hay un enfoque más eficiente?

Respuesta

24

La función symbols se puede utilizar para generar fácilmente listas de símbolos

In [1]: symbols('a0:3') 
Out[1]: (a₀, a₁, a₂) 

In [2]: numEquations = 15 

In [3]: symbols('a0:%d'%numEquations) 
Out[3]: (a₀, a₁, a₂, a₃, a₄, a₅, a₆, a₇, a₈, a₉, a₁₀, a₁₁, a₁₂, a₁₃, a₁₄) 
+1

Gracias! Eso se ve realmente simple. – thornate

+1

También funciona para letras: 'symbols ('a: g')'. – asmeurer

+2

solo una nota aquí, que en sympy esta es una tupla y no una lista ...existiendo una ligera diferencia, principalmente, uno no puede definir cosas para los elementos de una lista: a0 = t + 1 dará un error. – user836925

1

Su enfoque está bien, aunque no es necesario almacenar los nombres de los símbolos por separado (puede acceder al nombre de un símbolo a través de su propiedad name).

Además, se puede expresar la creación de símbolos un poco más concisa (aunque no más eficientemente), por ejemplo:

symbolList = map(lambda i: Symbol('t' + str(i)), xrange(numEquations)) 

Sin embargo, para su caso de uso (variables temporales), variables ficticias son probablemente el camino a ir:

symbolList = map(Dummy, xrange(numEquations)) 

Esto no es realmente más eficiente, ya que internamente la clase Dummy también está utilizando un contador para generar nombres únicos, pero es un poco más limpio y más claro.

1

Se podría hacer una subclase de dict que devuelve automáticamente Symbols:

import sympy as sym 

class SymDict(dict): 
    # http://stackoverflow.com/a/3405143/190597 
    def __missing__(self, key): 
     self[key]=sym.Symbol(key) 
     return self[key] 

def solveEquations(numEquations): 
    symbol = SymDict() 
    symbolList = ['t'+str(i) for i in range(numEquations)] 
    equationList = [sum(symbol[s]**i for s in symbolList) 
        for i in range(numEquations)] 
    print(equationList) 

solveEquations(3)  
# [3, t0 + t1 + t2, t0**2 + t1**2 + t2**2] 
7

numbered_symbols("t") devolverá un generador que genera t0 , t1, t2, etc. Puede usar el parámetro start para elegir una partida diferente v Alue. Y si desea usar variables ficticias, use numbered_symbols("t", cls=Dummy).

1

Con locals() y comprensión del diccionario, puede generar iterativamente símbolos y variables locales de python con un nombre similar. Por ejemplo:

>>> symbols_dict = dict(('a%d'%k, symbols('a%d'%k)) for k in range(3)) 
>>> locals().update(symbols_dict) 

Comprobar que funciona:

>>> print(expand((a0+a2)*(a0+a1**2))) 
a0**2 + a0*a1**2 + a0*a2 + a1**2*a2 
Cuestiones relacionadas