2009-09-28 10 views
1

je face à un problème dans la routine d'optimisation scipy « leastsq », si j'exécute le programme suivant, il ditscipy « Réduire au minimum la somme des carrés d'un ensemble d'équations »

raise errors[info][1], errors[info][0] 
TypeError: Improper input parameters. 

et parfois index out of range for an array ...

from scipy import * 
import numpy 
from scipy import optimize 
from numpy import asarray 
from math import * 

def func(apar): 
    apar = numpy.asarray(apar) 
    x = apar[0] 
    y = apar[1] 
    eqn = abs(x-y) 
    return eqn 

Init = numpy.asarray([20.0, 10.0]) 
x = optimize.leastsq(func, Init, full_output=0, col_deriv=0, factor=100, diag=None, warning=True) 
print 'optimized parameters: ',x 
print '******* The End ******' 

Je ne sais pas quel est le problème avec mon appel func optimize.leastsq(), s'il vous plaît aidez-moi

+0

Pouvez-vous formater votre code s'il vous plaît? Cela permettra aux gens de vous aider plus facilement :). – notJim

+1

Votre 'func()' pourrait simplement être écrit comme 'def func (apar): return abs (apar [0] -apar [1])'. Il n'y a pas besoin de coercition, car 'leastsq' passe les tableaux de Numpy à la fonction minimisée. – EOL

Répondre

2

leastsqleastsq fonctionne avec des vecteurs de sorte que la fonction résiduelle, func, doit retourner un vecteur de longueur au moins deux. Donc, si vous remplacez return eqn par return [eqn, 0.], votre exemple fonctionnera. En cours d'exécution donne:

optimized parameters: (array([10., 10.]), 2) 

qui est l'une des nombreuses réponses correctes pour le minimum de la différence absolue.

Si vous voulez minimiser une fonction scalaire, fmin est la solution, optimize.fmin(func, Init).

Le problème ici est que ces deux fonctions, bien qu'elles se ressemblent pour un scalaire, visent des objectifs différents. leastsq trouve l'erreur de moindre carré, généralement à partir d'un ensemble de courbes idéalisées, et est juste une façon de faire un "meilleur ajustement". D'autre part, fmin trouve la valeur minimale d'une fonction scalaire.

De toute évidence, le vôtre est un exemple de jouet, pour lequel aucun de ces éléments n'a vraiment de sens, alors la façon dont vous allez dépendre dépend de votre objectif final.

+0

On dirait que tu as raison. Cependant, si cela est vrai, cela ressemble à un bug pour moi. Le minimiseur devrait être capable de minimiser une fonction scalaire simple, s'il peut "minimiser" une liste de nombres ... Que pensez-vous? – EOL

+0

@EOL - Donc, je ne reçois pas un upvote pour la bonne réponse parce que vous n'aimez pas la façon dont scipy fonctionne? Foule difficile. Mais je suis d'accord qu'il semble que cela devrait fonctionner sans ce kludge, et ce serait une chose facile à corriger. – tom10

+0

@ tom10 Vous pourriez être intéressé à vérifier ma réponse ... :) – EOL

1

il suffit de regarder la least squares docs, il pourrait Soit que votre fonction func est définie incorrectement. Vous supposez que vous recevez toujours un tableau d'au moins la longueur 2, mais la fonction d'optimisation est incroyablement vague sur la longueur du tableau que vous recevrez. Vous pouvez essayer d'écrire pour afficher ce qui est apar, pour voir ce que vous obtenez réellement. Si vous utilisez quelque chose comme ipython ou le shell python, vous devriez obtenir des traces de pile qui vous montrent exactement sur quelle ligne l'erreur se produit, alors commencez là. Si vous ne pouvez pas le comprendre à partir de là, l'affichage de la trace de la pile nous aiderait probablement.

+0

Lire attentivement le document * soigneusement et soigneusement * est un bon conseil. Les minimiseurs généraux ont une longue histoire d'interfaces confuses et délicates. Essayez d'en écrire un un jour, et vous verrez pourquoi. – dmckee

+1

il suppose que 'apar' a * au moins * 2 éléments, pas exactement deux. Ce qui ne contredit pas votre point de vue, juste une correction mineure. – SilentGhost

+0

@SilentGhost: merci, corrigé. – notJim

1

Puisque vous voulez minimiser une fonction simple scalaire (func() retourne une valeur unique, pas une liste de valeurs), scipy.optimize.leastsq() doit être remplacé par un appel à l'un des fmin fonctions (avec les arguments appropriés):

x = optimize.fmin(func, Init) 

fonctionne correctement! En effet, leastsq() minimise la somme des carrés d'une liste de valeurs. Il ne semble pas fonctionner sur une (liste contenant une) valeur unique, comme dans votre exemple (même si elle pourrait, en théorie).

+0

Oui, je suis conscient que cela fonctionne avec 'optimize.fmin' mais je veux essayer avec 'optimize.leastsq' –