29

任意の数の連立方程式を解く関数をコーディングしています。方程式の数は、関数のパラメーターの1つによって設定され、各方程式は、方程式の数と同じ数のシンボルから作成されます。これは、方程式を単純にハードコーディングすることはできず、方程式をまとめるのに必要な記号さえもできないことを意味します。関数は、任意の数の方程式を処理できる必要があります。だから、私の質問は、シンボルのリストをどのように作成するのですか?

私には1つの可能な解決策がありますが、私の腸はそれがあまり効率的ではないだろうと私に言います。これを行うためのより良い方法があるかどうか私に知らせてください。

私はSymPyに不慣れで、まだ自分の道を感じています。私が見る限り、シンボルは文字列で定義する必要があります。したがって、文字に増分番号(たとえば、「t0」、「t1」など)を追加して一連の文字列を作成し、それらをリストに追加して、それらの文字列をパラメーターとして使用して記号を作成できます。これらのシンボル自体がリストに格納され、方程式を作成するために使用されます。

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

これはこれを行うための最良の方法ですか、それともより効率的なアプローチがありますか?

4

7 に答える 7

45

このsymbols関数を使用すると、シンボルのリストを簡単に生成できます

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₁₄)
于 2012-02-29T03:43:53.977 に答える
13

numbered_symbols("t")t0、、などt1を生成するジェネレータを返します。パラメータをt2使用してstart、別の開始値を選択できます。また、ダミー変数を使用する場合は、を使用しますnumbered_symbols("t", cls=Dummy)

于 2012-10-26T20:47:50.340 に答える
7

トピックにさらに役立つ情報を追加するかどうかはわかりませんが、次の方法を使用してシンボリック変数のリストを作成します。

x = [sympy.symbols('x%d' % i) for i in range(3)]

そして、私はそれを方程式で普通に使うことができます:

eq = x[0]**2 + x[1]*2 + x[2]
print(sympy.diff(eq,x[0]))
>>> 2*x0
于 2019-04-16T15:29:59.633 に答える
4

辞書を理解するlocals()と、同じような名前のシンボルとPythonローカル変数の両方を繰り返し生成できます。例えば:

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

それが機能することを確認します:

>>> print(expand((a0+a2)*(a0+a1**2)))
a0**2 + a0*a1**2 + a0*a2 + a1**2*a2
于 2017-07-16T18:25:51.280 に答える
3

dictあなたは自動的に返すサブクラスを作ることができます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]
于 2012-02-29T03:23:09.513 に答える
2

シンボル名を個別に保存する必要はありませんが、アプローチは問題ありません(シンボルの名前には、そのnameプロパティを介してアクセスできます)。

また、シンボルの作成をもう少し簡潔に表現することもできます(ただし、これ以上効率的ではありません)。例:

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

ただし、ユースケース(一時変数)の場合、ダミー変数がおそらく次の方法です。

symbolList = map(Dummy, xrange(numEquations))

内部的にはクラスが一意の名前を生成するためにカウンターも使用しているため、これは実際にはこれ以上効率的ではありませんがDummy、少しクリーンで明確です。

于 2012-02-29T03:16:53.150 に答える
2

私は@jp-senaによって与えられたアプローチが好きで、私が提案しようとしていることはそれによく似ています。違いは、必要なシンボルの数を知る必要がないことです。インデックスによって必要な数のシンボルにアクセスできるだけです。をシンボルとして使用IndexedBaseします。

>>> x = IndexedBase('x')  # you've got access to a virtual array of x values
>>> solve(x[1]**2 + 1/x[4], x[4])
[-1/x[1]**2]

表示の目的で、置換辞書を作成することをお勧めします。番号付きの記号を作成するには、

>>> reps = dict(zip([x[i] for i in range(n_used+1)], numbered_symbols('c')))
>>> (x[2]**2 + 1/x[4]).subs(reps)
c2**2 + 1/c4

または、26未満の記号を使用している場合は、

>>> reps = dict(zip([x[i] for i in range(n_used+1)], symbols('a:z')))
>>> (x[2]**2 + 1/x[4]).subs(reps)
c**2 + 1/e

ところで、xはIndexedBaseであり、括弧内に表示されている数字のタプルであるIndexedx[1]オブジェクトです。IndexedBaseとIndexedの両方がクエリに表示されます。.basex.indices.free_symbols

>>> (x[1,2] + 3).free_symbols
{x, x[1, 2]}
>>> x[1, 2].indices
(1, 2)
>>> x[1].base
x
于 2019-05-10T13:32:44.247 に答える