2012-10-17 5 views
18

के साथ अनुकूली चरण आकार का उपयोग scipy.integrate.ode के लिए (संक्षिप्त) दस्तावेज कहता है कि दो विधियां (dopri5 और dop853) में नियंत्रण नियंत्रण और घने आउटपुट हैं। उदाहरणों और कोड को स्वयं देखकर, मैं केवल एक इंटीग्रेटर से आउटपुट प्राप्त करने का एक बहुत ही सरल तरीका देख सकता हूं। अर्थात्, ऐसा लगता है कि आप बस कुछ निश्चित डीटी द्वारा इंटीग्रेटर को आगे बढ़ाएं, उस समय फ़ंक्शन मान प्राप्त करें, और दोहराएं।scipy.integrate.ode

मेरी समस्या में काफी परिवर्तनीय टाइमकैल्स हैं, इसलिए मैं आवश्यक सहनशीलता प्राप्त करने के लिए मूल्यांकन करने के लिए आवश्यक समय पर मूल्यों को प्राप्त करना चाहता हूं। यही है, शुरुआती चीजें धीरे-धीरे बदल रही हैं, इसलिए उत्पादन समय कदम बड़ा हो सकता है। लेकिन जैसे ही चीजें दिलचस्प होती हैं, आउटपुट समय के चरणों को छोटा होना चाहिए। मैं वास्तव में बराबर अंतराल पर घने आउटपुट नहीं चाहता हूं, मैं बस अनुकूली फ़ंक्शन का उपयोग करने के लिए समय कदम चाहता हूं।

संपादित करें: घने उत्पादन

इससे संबंधित एक धारणा (लगभग विपरीत) "घने उत्पादन", है जिससे कदम उठाए के रूप में बड़े स्टेपर लेने के लिए परवाह है के रूप में कर रहे हैं, लेकिन समारोह के मूल्यों अंतर्वेशित (आमतौर पर स्टेपर की शुद्धता के बराबर सटीकता के साथ) जो भी आप चाहते हैं। scipy.integrate.ode अंतर्निहित फोर्टन स्पष्ट रूप से सक्षम है, लेकिन ode में इंटरफ़ेस नहीं है। दूसरी ओर, odeint, एक अलग कोड पर आधारित है, और स्पष्ट रूप से घने आउटपुट करता है। (जब भी ऐसा होता है, तो आप हर बार आउटपुट कर सकते हैं, और देखें कि आउटपुट के समय से इसका कोई लेना-देना नहीं है।)

तो मैं अभी भी अनुकूलता का लाभ उठा सकता हूं, जब तक कि मैं आउटपुट समय चरणों पर निर्णय ले सकता हूं जो मैं समय से पहले चाहता हूं। दुर्भाग्यवश, मेरे पसंदीदा सिस्टम के लिए, मुझे यह भी नहीं पता कि अनुमानित टाइमकैल्स समय के कार्यों के रूप में क्या हैं, जब तक कि मैं एकीकरण चलाता हूं। तो मुझे घने आउटपुट की इस धारणा के साथ एक इंटीग्रेटर कदम उठाने के विचार को गठबंधन करना होगा।

उत्तर

10

SciPy 0.13.0 के बाद से,

स्तोत्र समाधानकर्ताओं की dopri परिवार से मध्यवर्ती परिणाम अब एक solout कॉलबैक फ़ंक्शन द्वारा पहुँचा जा सकता।

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() 

परिणाम: Logistic function solved using DOPRI5

परिणाम हालांकि वे दोनों एक ही बैकेंड का उपयोग करें, से टिम D के थोड़ा अलग हो रहा है। मुझे संदेह है कि dopri5 की एफएसएएल संपत्ति के साथ ऐसा करना है। टिम के दृष्टिकोण में, मुझे लगता है कि सातवें चरण से परिणाम के 7 को त्याग दिया गया है, इसलिए के 1 की गणना फिर से की जाती है।

नोट: bug with set_solout not working if you set it after setting initial values ज्ञात है। इसे SciPy 0.17.0 के रूप में तय किया गया था।

+1

ध्यान रखें कि अभी के लिए (संस्करण 0.16) आपको 'set_sitialout() '** ** ** set_initial_value()' से पहले कॉल करना होगा या हलआउट नहीं कहा जाएगा। –

8

integrate विधि एक बूलियन तर्क step स्वीकार करता है जो एक आंतरिक चरण को वापस करने के तरीके को बताता है। हालांकि, ऐसा लगता है कि 'dopri5' और 'dop853' solvers इसका समर्थन नहीं करते हैं।

निम्न कोड से पता चलता है जब 'vode' solver प्रयोग किया जाता है कि कैसे आप solver द्वारा उठाए गए कदमों का आंतरिक प्राप्त कर सकते हैं:

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() 

परिणाम: Plot of the solution

+1

हाँ, मुझे डर था कि यह मामला था। मैं उम्मीद कर रहा था कि 'dopri5' और' dop853' का विस्तार करने का एक आसान तरीका होगा, लेकिन मेरा धैर्य फोर्टन पर समाप्त होता है, इसलिए मुझे लगता है कि मैं एक टाइम स्टेपर को फिर से कार्यान्वित करूंगा। एक शर्म की बात है, हालांकि, कि अजगर मजबूत, कुशल और लचीला एकीकृतकर्ताओं के बिना छोड़ा गया है ... – Mike

+0

ode45 का उपयोग करने वाली MATLAB स्क्रिप्ट को परिवर्तित करने का प्रयास करते समय मुझे वही कार्यक्षमता चाहिए। मैंने Scipy.org [टिकट # 1820] (http://projects.scipy.org/scipy/ticket/1820) पर टिकट जमा कर दिया है। –

+0

@ माइक: ठीक है, यहां तक ​​कि 'dopri5' और' dop853' के साथ भी आप हमेशा 'लॉजिस्टिक' फ़ंक्शन के अंदर से मूल्य को स्टोर कर सकते हैं और केवल 'एकीकृत' विधि में एक ही कॉल कर सकते हैं। (मैं इसे वैकल्पिक उत्तर के रूप में पोस्ट करने जा रहा हूं।) – balu

12

मैं इस पर देख रहा है एक ही परिणाम प्राप्त करने की कोशिश करने के लिए। यह पता चला है कि आप ओडीई तत्काल में nsteps = 1 सेट करके चरण-दर-चरण परिणाम प्राप्त करने के लिए हैक का उपयोग कर सकते हैं। यह हर कदम पर उपयोगकर्ता चेतावनी उत्पन्न करेगा (इसे पकड़ा और दबाया जा सकता है)।

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() 

परिणाम:

+0

ऐसा लगता है कि यह काम ठीक है। अब, अगर मैंने केवल जीएसएल को अपना कोड पोर्ट करने में सप्ताह नहीं बिताए हैं ... :) – Mike

+2

यह पता चला है कि आप इस छोटे हैक 'solver._integrator.iwork [2] = -1' के साथ फोरट्रान-उत्सर्जित चेतावनी को दबा सकते हैं (मैं इसे दिखाने के लिए उपरोक्त कोड संपादित करूंगा)। यह फोर्ट्रान इंटरफेस के माध्यम से एक ध्वज पारित करता है जो stdout को प्रिंटिंग दबाता है। –

-1

यहाँ एक और विकल्प है कि यह भी dopri5 और dop853 के साथ काम करना चाहिए। असल में, solver logistic() समारोह के रूप में अक्सर के रूप में की जरूरत मध्यवर्ती मूल्यों की गणना करने ताकि जहां हम परिणाम की दुकान है कॉल करेगा:,

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() 
+1

यहां तीन बार कदम शामिल हैं। आउटपुट समय चरण सबसे बड़ा है; डिफ़ॉल्ट रूप से क्या ode' outputs। तब हमारे पास इंटीग्रेटर का अनुकूली समय कदम है, जहां मैं आउटपुट चाहता हूं। सबसे छोटा इंटरमीडिएट टाइम चरण है जो रनगे-कुट्टा-स्टाइल इंटीग्रेटर्स (उदा।, 'डोपरी 5',' डॉप 853') उपयोग करते हैं। यही है, 'डोपरी 5' वास्तव में एक बार कदम उठाने के लिए किए गए मध्यवर्ती कदमों के दौरान कई बार 'लॉजिस्टिक' कहलाएगा। मेरी चिंता यह है कि मेरा मानना ​​है कि उन मध्यवर्ती चरणों में निम्न-आदेश सटीकता है; 'y' मान वास्तव में कई मामलों में केवल प्रथम क्रम सटीक है। – Mike

+0

"मुझे विश्वास है कि उन मध्यवर्ती चरणों में निम्न-आदेश सटीकता है" ओह, मैंने सोचा कि 'लॉजिस्टिक' को इंटीग्रेटर के अनुकूली समय चरण के साथ बुलाया जाएगा। यदि नहीं, तो मेरा उत्तर का जवाब मदद नहीं करता है। लेकिन इसके बारे में निश्चित हैं? – balu

+0

विचार सही वृद्धि के लिए बेहतर अनुमान बनाने के लिए है; एकाधिक कॉल के परिणामों को संयोजित करने से आप कुछ त्रुटि शर्तों को रद्द कर सकते हैं। असल में, अब जब मैं इसे देखता हूं, विकिपीडिया के आलेख में एक अनुभाग है ["* * * रनगे-कुट्टा विधि"] (https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#The_Runge। E2.80.93Kutta_method), जिसमें यह दिखाता है कि फ़ंक्शन का मूल्यांकन चरण-मध्य बिंदु पर दो बार अलग-अलग मानों के साथ किया जाता है।तो आपका 'सोल' वास्तव में कुछ मामलों में समान 'टी' मान के लिए दो अलग-अलग 'y' मानों को संग्रहीत करेगा, क्योंकि पहला कम सटीक था। – Mike

2

FYI करें, हालांकि एक जवाब पहले से ही स्वीकार किया गया है, मैं ऐतिहासिक रिकॉर्ड के लिए बाहर ले जाना चाहिए से घने आउटपुट और मनमाने ढंग से नमूनाकरण गणना की गई प्रक्षेपण के साथमें मूल रूप से समर्थित है।इसमें सॉल्वर द्वारा आंतरिक रूप से उपयोग किए जाने वाले सभी अनुकूली-निर्धारित समय चरणों का रिकॉर्ड भी शामिल है। यह dopri853 and radau5 दोनों के साथ इंटरफेस करता है और दाईं ओर की तरफ परिभाषा के लिए (बहुत धीमे) पायथन फ़ंक्शन कॉलबैक पर निर्भर होने के बजाय उनके साथ इंटरफ़ेस के लिए आवश्यक सी कोड उत्पन्न करता है। इन सुविधाओं में से कोई भी मेरे ज्ञान के लिए किसी अन्य पायथन-केंद्रित सॉल्वर में मूल रूप से या कुशलता से प्रदान नहीं किया जाता है।