2012-02-18 18 views
5

A menudo tengo que resolver problemas no lineales en los que el número de variables supera el número de restricciones (o, a veces, al revés). Por lo general, algunas de las restricciones o variables son redundantes de una manera complicada. ¿Hay alguna manera de resolver esos problemas?Optimización de SciPy para sistemas con restricciones limitadas

La mayoría de los simples solucionadores parecen suponer que el número de restricciones es igual al número de variables, y que el jacobiano no es anular. leastsq funciona a veces pero ni siquiera intenta cuando las restricciones son menores que el número de variables. Me doy cuenta de que podría simplemente ejecutar fmin en linalg.norm(F), pero esto es mucho menos eficiente que cualquier método que haga uso de Jacobian.

Aquí hay un ejemplo de un problema que demuestra de lo que estoy hablando. Obviamente tiene una solución, pero leastsq da un error. Por supuesto, este ejemplo es fácil de resolver a mano, simplemente lo puse aquí para demostrar el problema.

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) 

El mensaje de error que consigo es:

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 

me han rastreado la red para una respuesta e incluso se han preguntado en la lista de correo SciPy, y no obtuvo respuesta. Por ahora, pirateé la fuente SciPy para que el solucionador newton_krylov use pinv(), pero no creo que esta sea una solución óptima.

+0

Lo que tienes es una pregunta scipy o es en realidad una matemática que llevaba una barba falsa? – talonmies

+0

Creo que es una pregunta descarada. Puedo resolver este tipo de problemas utilizando solucionadores personalizados que he escrito, pero preferiría poder utilizar los solucionadores de scipy existentes. Además, el fsolve de matlab parece ser capaz de resolver estos. Esta parece ser una situación común y es difícil de creer que Scipy no pueda manejarlo (aparentemente). –

+0

'fsolve' utiliza un método de región de confianza IIRC. Entonces, ¿realmente quieres saber si hay una función análoga para 'fsolve'? – talonmies

Respuesta

3

¿Qué hay de cambiar el tamaño de la matriz regreso de F() para el número de variables:

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 
+0

Gracias, esto parece funcionar. ¿Hay alguna razón por la cual esto no se hace automáticamente? Si no hay efectos secundarios, sugiero un relleno automático como un parche. –

Cuestiones relacionadas