2012-02-29 36 views
15

Tôi đang mã hóa một hàm giải quyết một số phương trình đồng thời tùy ý. Số phương trình được thiết lập bởi một trong các tham số của hàm và mỗi phương trình được xây dựng từ một số biểu tượng - như nhiều biểu tượng có phương trình. Điều này có nghĩa rằng tôi không thể chỉ đơn giản là mã hóa các phương trình, hoặc thậm chí là các biểu tượng cần thiết để tập hợp các phương trình; hàm cần có khả năng xử lý bất kỳ số phương trình nào. Vì vậy, câu hỏi của tôi là, làm thế nào để tôi tạo ra một danh sách các biểu tượng?SymPy - Số lượng các ký hiệu tùy ý

Tôi có một giải pháp có thể, nhưng ruột của tôi nói với tôi rằng nó sẽ không hiệu quả lắm. Xin vui lòng cho tôi biết nếu có một cách tốt hơn để làm điều này.

Tôi mới tham gia SymPy và vẫn đang cảm thấy theo cách của mình. Theo như tôi thấy, Biểu tượng cần được xác định bằng một chuỗi. Do đó, tôi có thể tạo chuỗi chuỗi thông qua việc thêm số gia tăng vào một chữ cái (nói 't0', 't1', v.v.), thêm chúng vào danh sách và sau đó tạo các biểu tượng sử dụng các chuỗi đó làm tham số. Những biểu tượng đó sẽ tự được lưu trữ trong một danh sách và sẽ được sử dụng để tạo ra các phương trình.

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... 

Đây có phải là cách tốt nhất để làm điều này hoặc có cách tiếp cận hiệu quả hơn không?

Trả lời

24

Chức năng symbols có thể được sử dụng để dễ dàng tạo ra danh sách các biểu tượng

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

Cảm ơn! Điều đó trông rất đơn giản. – thornate

+1

Nó cũng hoạt động đối với các chữ cái: 'symbols ('a: g')'. – asmeurer

+2

chỉ là một lưu ý ở đây, rằng trong sympy đây là một tuple và không phải là một danh sách ...có một sự khác biệt nhỏ, chủ yếu là, một người không thể định nghĩa mọi thứ cho các thành phần của một danh sách: a0 = t + 1 sẽ đưa ra một lỗi. – user836925

1

Cách tiếp cận của bạn là tốt, mặc dù không cần lưu trữ tên biểu tượng riêng biệt (bạn có thể truy cập tên của biểu tượng qua thuộc tính name).

Ngoài ra, bạn có thể thể hiện sự sáng tạo biểu tượng một chút chính xác hơn (mặc dù không có hiệu quả hơn), ví dụ:

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

Tuy nhiên, đối với trường hợp sử dụng của bạn (các biến tạm thời), biến giả có lẽ là cách để đi:

symbolList = map(Dummy, xrange(numEquations)) 

Đây không phải là thực sự bất kỳ hiệu quả hơn, vì trong nội bộ lớp Dummy cũng đang sử dụng một bộ đếm để tạo tên duy nhất, nhưng đó là một chút bụi và rõ ràng hơn.

1

Bạn có thể làm cho một lớp con của dict có thể tự động trả về 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") sẽ trả về một máy phát điện mà tạo ra t0 , t1, t2, v.v. Bạn có thể sử dụng tham số start để chọn một v bắt đầu khác alue. Và nếu bạn muốn sử dụng các biến giả, hãy sử dụng numbered_symbols("t", cls=Dummy).

1

Với locals() và hiểu từ điển, bạn có thể lặp lại tạo cả hai biểu tượng và biến cục bộ python với tên tương tự. Ví dụ:

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

Kiểm tra rằng nó hoạt động:

>>> print(expand((a0+a2)*(a0+a1**2))) 
a0**2 + a0*a1**2 + a0*a2 + a1**2*a2 
Các vấn đề liên quan