質問

私はしばしば、変数の数が制約の数(または時にはその逆)を超える非線形の問題を解決する必要があります。通常、制約または変数の一部は複雑な方法で冗長です。そのような問題を解決する方法はありますか?

ほとんどのScipyソルバーは、制約の数が変数の数に等しいと想定しているようで、ヤコビアンは非singularであると考えています。 leastsq 時々機能しますが、制約が変数の数よりも少ない場合でも試していません。走ることができることに気づきました fmin の上 linalg.norm(F), 、しかし、これはヤコビアンを利用するどの方法よりもはるかに効率的ではありません。

ここに、私が話していることを示す問題の例があります。明らかに解決策がありますが、 leastsq エラーが発生します。もちろん、この例は手作業で簡単に解決できます。問題を示すためにここに置いただけです。

import numpy as np
import scipy.optimize

mat = np.random.randn(5, 7)

def F(x):
    y = np.dot(mat, x)
    return np.array([ y[0]**2 + y[1]**3 + 12, y[2] + 17 ])

x0 = np.random.randn(7)
scipy.optimize.leastsq(F, x0)

私が得るエラーメッセージは次のとおりです。

Traceback (most recent call last):
  File "question.py", line 13, in <module>
    scipy.optimize.leastsq(F, x0)
  File "/home/dstahlke/apps/scipy/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 278, in leastsq
    raise TypeError('Improper input: N=%s must not exceed M=%s' % (n,m))
TypeError: Improper input: N=7 must not exceed M=2

私は回答を求めてネットを精査し、Scipyメーリングリストでも尋ねましたが、応答はありませんでした。今のところ、私はscipyソースをハッキングしました。 newton_krylov ソルバーは使用します pinv(), 、しかし、これは最適な解決策ではないと思います。

役に立ちましたか?

解決

f()から変数の数への返品配列のサイズを変更するのはどうですか:

import numpy as np
import scipy.optimize

mat = np.random.randn(5, 7)

def F(x):
    y = np.dot(mat, x)
    return np.resize(np.array([ y[0]**2 + y[1]**3 + 12, y[2] + 17]), 7)

while True:    
    x0 = np.random.randn(7)
    r = scipy.optimize.leastsq(F, x0)
    err = F(r[0])
    norm =  np.dot(err, err)
    if norm < 1e-6:
        break

print err
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top