Frage

Ich muss oft nichtlineare Probleme lösen, bei denen die Anzahl der Variablen die Anzahl der Einschränkungen (oder manchmal umgekehrt) überschreitet. Normalerweise sind einige der Einschränkungen oder Variablen kompliziert überflüssig. Gibt es eine Möglichkeit, solche Probleme zu lösen?

Die meisten scipy -Solvers scheinen davon auszugehen, dass die Anzahl der Einschränkungen der Anzahl der Variablen entspricht und dass der Jakobier nicht singulär ist. leastsq Funktioniert manchmal, aber es versucht nicht einmal, wenn die Einschränkungen weniger als die Anzahl der Variablen sind. Mir ist klar, dass ich einfach rennen könnte fmin an linalg.norm(F), Aber dies ist viel weniger effizient als jede Methode, die den Jakobier nutzt.

Hier ist ein Beispiel für ein Problem, das zeigt, wovon ich spreche. Es hat offensichtlich eine Lösung, aber leastsq gibt einen Fehler. Natürlich ist dieses Beispiel von Hand leicht zu lösen. Ich habe es einfach hierher gesetzt, um das Problem zu demonstrieren.

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)

Die Fehlermeldung, die ich erhalte, lautet:

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

Ich habe das Netz nach einer Antwort gesucht und sogar auf der Scipy -Mailingliste gefragt und keine Antwort erhalten. Im Moment habe ich die Scipy -Quelle so gehackt, dass die newton_krylov Löser verwendet pinv(), aber ich denke nicht, dass dies eine optimale Lösung ist.

War es hilfreich?

Lösung

Wie wäre es mit der Größe der Größe des Rückkehrarrays von f () zur Anzahl der Variablen:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top