La (breve) de la documentación para scipy.integrate.ode dice que los dos métodos (dopri5 y dop853) han stepsize de control y densa de salida. En los ejemplos y el propio código, que sólo se puede ver de una manera muy simple para obtener la salida de un integrador. Es decir, parece que sólo el paso del integrador adelante por algunos fijos dt, obtener el valor de la función(s) en ese tiempo, y repetir.

Mi problema tiene bastante variables en escalas de tiempo, así que me gustaría obtener los valores en cualquier momento de los pasos que necesita para evaluar a lograr las tolerancias requeridas. Que es, en un principio, las cosas están cambiando lentamente, por lo que el tiempo de salida de los pasos puede ser grande. Pero como las cosas se ponen interesantes, el tiempo de salida de los pasos tienen que ser más pequeños. Yo en realidad no quiero densa de salida a intervalos iguales, sólo quiero los pasos de tiempo de la función de adaptación de los usos.

EDICIÓN: Denso salida

Una relacionada con el concepto (de casi el opuesto) es «densa de salida», según la cual las medidas adoptadas son tan grandes como el paso a paso, cuida a tomar, pero los valores de la función son interpolados (por lo general con una precisión comparable a la exactitud de los motores paso a paso) a lo que usted desea. El fortran subyacente scipy.integrate.ode es aparentemente capaz de esto, pero ode no tiene la interfaz. odeint, por otro lado, se basa en un código diferente, y no, evidentemente, hacer densa de salida. (Usted puede dar salida a cada momento a su lado derecho está llamado a ver cuando sucede eso, y ver que no tiene nada que ver con la salida de veces).

Para que yo pudiera tomar ventaja de adaptabilidad, mientras yo podía decidir sobre el tiempo de salida de los pasos que quiero antes de tiempo. Por desgracia, para mi sistema favorito, yo no sé ni qué aproximado de la duración de las mismas están en función del tiempo, hasta que se ejecute la integración. Así que voy a tener que combinar la idea de tomar un integrador de paso con esta noción de densa de salida.

EDIT 2: Denso de salida de nuevo

Al parecer, scipy 1.0.0 introdujo soporte para densa de salida a través de una nueva interfaz. En particular, se recomienda alejarse de scipy.integrate.odeint y hacia scipy.integrar.solve_ivp, que como palabra clave dense_output. Si se establece a True, el objeto devuelto tiene un atributo sol que usted puede llamar con una matriz de veces, lo que, a continuación, devuelve las funciones integradas de valores en aquellos tiempos. Que todavía no resuelve el problema para esta pregunta, pero es útil en muchos casos.

InformationsquelleAutor Mike | 2012-10-17

5 Comentarios

  1. 12

    Desde SciPy 0.13.0,

    Los resultados intermedios de la dopri de la familia de soluciones ODE puede
    ahora se puede acceder por un solout función de devolución de llamada.

    import numpy as np
    from scipy.integrate import ode
    import matplotlib.pyplot as plt
    
    
    def logistic(t, y, r):
        return r * y * (1.0 - y)
    
    r = .01
    t0 = 0
    y0 = 1e-5
    t1 = 5000.0
    
    backend = 'dopri5'
    # backend = 'dop853'
    solver = ode(logistic).set_integrator(backend)
    
    sol = []
    def solout(t, y):
        sol.append([t, *y])
    solver.set_solout(solout)
    solver.set_initial_value(y0, t0).set_f_params(r)
    solver.integrate(t1)
    
    sol = np.array(sol)
    
    plt.plot(sol[:,0], sol[:,1], 'b.-')
    plt.show()

    Resultado:
    El uso adaptativo de tamaños de paso con scipy.integrar.la educación a distancia

    El resultado parece ser ligeramente diferentes a los de Tim D, a pesar de que ambos utilizan el mismo servidor. Sospecho que esto tiene que ver con FSAL propiedad de dopri5. En Tim enfoque, creo que el resultado k7 de la séptima etapa se descarta, por lo que 1d se calcula de nuevo.

    Nota: Hay un conocido bug con set_solout no funciona si se establece después de la configuración inicial de los valores de. Se fija como de SciPy 0.17.0.

    • Tenga en cuenta que por ahora (versión 0.16) usted tiene que llamar a set_solout() antes de set_initial_value() o solout no será llamado.
    • He probado el método anterior (dopri5 y vode) y me estoy encontrando que los resultados no son deterministas. Lo que significa que para mi, rigidez, conjunto de Odas, a veces el algoritmo finaliza correctamente y a veces falla (se da la misma entrada). Esto no funciona para mí. ¿Sabe usted cómo la fuerza de este ser determinista, o donde más que yo podría buscar una solución determinista? Gracias.
  2. 12

    He estado mirando esta para tratar de obtener el mismo resultado. Resulta que usted puede usar un hack para obtener el paso a paso de resultados mediante el establecimiento de nsteps=1 en la oda de creación de instancias. Se generará un UserWarning en cada paso (esto puede ser capturado y suprimida).

    import numpy as np
    from scipy.integrate import ode
    import matplotlib.pyplot as plt
    import warnings
    
    
    def logistic(t, y, r):
        return r * y * (1.0 - y)
    
    r = .01
    t0 = 0
    y0 = 1e-5
    t1 = 5000.0
    
    #backend = 'vode'
    backend = 'dopri5'
    #backend = 'dop853'
    
    solver = ode(logistic).set_integrator(backend, nsteps=1)
    solver.set_initial_value(y0, t0).set_f_params(r)
    # suppress Fortran-printed warning
    solver._integrator.iwork[2] = -1
    
    sol = []
    warnings.filterwarnings("ignore", category=UserWarning)
    while solver.t < t1:
        solver.integrate(t1, step=True)
        sol.append([solver.t, solver.y])
    warnings.resetwarnings()
    sol = np.array(sol)
    
    plt.plot(sol[:,0], sol[:,1], 'b.-')
    plt.show()

    resultado:
    El uso adaptativo de tamaños de paso con scipy.integrar.la educación a distancia

    • Que parece hacer el trabajo bien. Ahora, si tan sólo no hubiera pasado semanas trasladar mi código para GSL… 🙂
    • Resulta que se puede suprimir el Fortran-emitido aviso con este pequeño hack solver._integrator.iwork[2] = -1 (voy a editar el código anterior para mostrar este). Esto establece un indicador pasa a través de la Fortran interfaz que suprime la impresión a stdout.
  3. 8

    La integrate método acepta un argumento booleano step que indica el método para devolver un único paso interno. Sin embargo, parece que el ‘dopri5’ y ‘dop853’ solucionadores no lo soportan.

    El código siguiente se muestra cómo se puede obtener la interna de las medidas adoptadas por el solver cuando el ‘vode’ solver se utiliza:

    import numpy as np
    from scipy.integrate import ode
    import matplotlib.pyplot as plt
    
    
    def logistic(t, y, r):
        return r * y * (1.0 - y)
    
    r = .01
    
    t0 = 0
    y0 = 1e-5
    t1 = 5000.0
    
    backend = 'vode'
    #backend = 'dopri5'
    #backend = 'dop853'
    solver = ode(logistic).set_integrator(backend)
    solver.set_initial_value(y0, t0).set_f_params(r)
    
    sol = []
    while solver.successful() and solver.t < t1:
        solver.integrate(t1, step=True)
        sol.append([solver.t, solver.y])
    
    sol = np.array(sol)
    
    plt.plot(sol[:,0], sol[:,1], 'b.-')
    plt.show()

    Resultado:
    El uso adaptativo de tamaños de paso con scipy.integrar.la educación a distancia

    • Sí, tenía miedo de que fue el caso. Tenía la esperanza de que habría una manera fácil de extender dopri5 y dop853, pero mi paciencia se termina en fortran, así que creo que voy a volver a implementar un momento paso a paso. Parece una pena, sin embargo, que en python se deja sin robusto, eficiente y flexible de los integradores de…
    • Necesitaba esta misma funcionalidad, mientras que tratando de convertir una secuencia de comandos de MATLAB que utiliza ode45. He enviado un ticket en Scipy.org Ticket#1820.
    • Bueno, incluso con dopri5 y dop853 siempre se puede almacenar el valor de dentro de la logistic función y acaba de hacer una sola llamada a la integrate método. (Voy a publicar esto como respuesta alternativa.)
    • En otra nota: a mí me gusta cómo la step=True característica no está documentado en todos los.
    • Por favor, ver mi nota por debajo de unos PyDSTool del soporte nativo para densa de salida y pasos internos mediante dopri 853.
  4. 2

    FYI, aunque la respuesta ha sido aceptado ya, debo señalar que para el registro histórico que se denso de salida y arbitraria de muestreo de en cualquier lugar a lo largo de la trayectoria calculada es compatible de forma nativa en PyDSTool. Esto también incluye un registro de todas las adaptativa-determinado de pasos de tiempo utilizado internamente por el solver. Este interfaces con tanto dopri853 y radau5 y genera automáticamente el código de C necesario para conectarse con ellos en lugar de confiar en (mucho más lento) función de python devoluciones de llamada para el lado derecho de la definición. Ninguna de estas características de forma nativa o proporcionado de manera eficiente en cualquier otro python-centrado solver, a mi conocimiento.

  5. -1

    Aquí es otra opción que también debe trabajar con dopri5 y dop853. Básicamente, el buscador va a llamar a la logistic() función tan a menudo como sea necesario para calcular los valores intermedios, de modo que es donde almacenamos los resultados:

    import numpy as np
    from scipy.integrate import ode
    import matplotlib.pyplot as plt
    
    sol = []
    def logistic(t, y, r):
        sol.append([t, y])
        return r * y * (1.0 - y)
    
    r = .01
    
    t0 = 0
    y0 = 1e-5
    t1 = 5000.0
    # Maximum number of steps that the integrator is allowed 
    # to do along the whole interval [t0, t1].
    N = 10000
    
    #backend = 'vode'
    backend = 'dopri5'
    #backend = 'dop853'
    solver = ode(logistic).set_integrator(backend, nsteps=N)
    solver.set_initial_value(y0, t0).set_f_params(r)
    
    # Single call to solver.integrate()
    solver.integrate(t1)
    sol = np.array(sol)
    
    plt.plot(sol[:,0], sol[:,1], 'b.-')
    plt.show()
    • Hay tres pasos de tiempo involucrado. El más grande es el tiempo de salida de paso; lo ode salidas por defecto. Luego tenemos el integrador de adaptación del paso de tiempo, que es donde yo quiero el de salida. El más pequeño es el tiempo intermedio paso que los métodos de Runge-Kutta de estilo integradores (p. ej., dopri5, dop853) de uso. Es decir, dopri5 se llaman en realidad logistic varias veces durante el intermedio de las medidas adoptadas para hacer un solo paso de tiempo. Mi preocupación es que creo que los pasos intermedios han de menor orden de exactitud; la y valor sólo es realmente de primer orden precisa en muchos casos.
    • «Yo creo que los pasos intermedios tienen menor-la exactitud de la orden» ¡Uy, pensé logistic sería llamado con el integrador de adaptación del paso de tiempo. Si no, mi respuesta, por supuesto, no ayuda. Pero está seguro acerca de eso?
    • La idea es construir mejores aproximaciones a la correcta incremento; la combinación de los resultados de varias llamadas le permite cancelar algunos de los términos de error. De hecho, ahora que lo miro, artículo de Wikipedia tiene una sección que explica la «El método de Runge-Kutta», en el que se muestra que la función se evalúa en el punto medio de dos veces con diferentes valores. Por lo que su sol en realidad sería almacenar dos diferentes y valores para la misma t valor en algunos casos, porque la primera fue menos preciso.

Dejar respuesta

Please enter your comment!
Please enter your name here