【问题标题】:Solving 4D coupled system by using EULER'S Method用欧拉法求解四维耦合系统
【发布时间】:2016-03-22 10:23:25
【问题描述】:

我想用代码实现下面给出的系统,但是当我将它增加到 1500 次迭代时,我得到以下错误:

Warning (from warnings module):
  File "D:\python test files\sys1.py", line 16
    dy = c*x- x*z + w
RuntimeWarning: overflow encountered in double_scalars

Warning (from warnings module):
  File "D:\python test files\sys1.py", line 17
    dz = -b*z + x*y
RuntimeWarning: overflow encountered in double_scalars

Warning (from warnings module):
  File "D:\python test files\sys1.py", line 18
    du = -h*u - x*z
RuntimeWarning: overflow encountered in double_scalars

Warning (from warnings module):
  File "D:\python test files\sys1.py", line 42
    zs[i+1] = zs[i] + (dz * t)
RuntimeWarning: invalid value encountered in double_scalars

Warning (from warnings module):
  File "D:\python test files\sys1.py", line 15
    dx = a*(y-x) + u
RuntimeWarning: invalid value encountered in double_scalars

Warning (from warnings module):
  File "D:\python test files\sys1.py", line 19
    dw = k1*x - k2*y
RuntimeWarning: invalid value encountered in double_scalars

Warning (from warnings module):
  File "C:\Python27\lib\site-packages\mpl_toolkits\mplot3d\proj3d.py", line 156
    txs, tys, tzs = vecw[0]/w, vecw[1]/w, vecw[2]/w   
RuntimeWarning: invalid value encountered in divide

我的代码:

from __future__ import division
import numpy as np    
import math    
import random   
import matplotlib.pyplot as plt    
from mpl_toolkits.mplot3d import Axes3D        
# import pdb
# pdb.set_trace()

def sys1(x, y, z, u, w , a=10, b=8.0/3.0, c=28, k1=0.4, k2=8, h=-2):

    dx = a*(y-x) + u
    dy = c*x- x*z + w    
    dz = -b*z + x*y    
    du = -h*u - x*z    
    dw = k1*x - k2*y    
    return dx, dy, dz, du, dw

t = 0.01    
itera = 2500

# Need one more for the initial values

xs = np.empty((itera+1,))    
ys = np.empty((itera+1,))    
zs = np.empty((itera+1,))    
us = np.empty((itera+1,))    
ws = np.empty((itera+1,))

# Setting initial values

xs[0], ys[0], zs[0], us[0], ws[0] = (0.1, 0.1, 0.1, 0.1, 0.1)


# Stepping through "time".

for i in range(itera):    
# Derivatives of the X, Y, Z state
    dx, dy, dz, du, dw = sys1(xs[i], ys[i], zs[i], us[i], ws[i])     

    xs[i+1] = xs[i] + (dx * t)
    ys[i+1] = ys[i] + (dy * t)
    zs[i+1] = zs[i] + (dz * t)
    us[i+1] = us[i] + (du * t)
    ws[i+1] = ws[i] + (dw * t)

fig = plt.figure()

ax = fig.gca(projection='3d')
ax.plot(xs, ys, zs)
ax.set_xlabel("X Axis")
ax.set_ylabel("Y Axis")
ax.set_zlabel("Z Axis")
ax.set_title("Lorenz Attractor")
plt.show()

【问题讨论】:

  • 某处被零除,发出警告。
  • 虽然我运行代码时没有收到任何警告。你使用的是什么版本的 python/matplotlib?
  • 我正在使用 python 2.7.6 和 matplotlib 1.3.1。
  • 我查看了您的代码,当 itera 达到值 1590 时,dydu 等于无穷大,dz 等于负无穷大。在此之上,你所有的值,dx,dy,dz,du,dw 都是无穷大的。这就是您的问题所在。
  • 感谢大卫,但我需要系统迭代更多的值,在 MATLAB 中我做到了,但在 python 中它显示了问题,你有什么建议可以用任何其他方式实现吗?

标签: python python-2.7 numpy matplotlib ode


【解决方案1】:

您正在尝试使用一个著名的简单数值方案来模拟一个著名的敏感非线性微分方程系统(实际上是a famously sensitive system增强 版本)。您的解决方案在给定的时间步长上出现分歧,这体现在您的解决方案值首先变为inf(您没有注意到),然后是nan(您仍然没有注意到),最后是@ 987654330@ 在你的无穷大附近玩转时产生除以零。

这是你的输出:

注意坐标轴的限制比例:都在 1e100 以上。这可能告诉你你有无穷无尽的东西。

好消息是,您拥有的同一个程序可以通过减少时间步长来提供合理的输出,这应该始终是您使用欧拉等一阶方法的第一个猜测(尤其是您从 MATLAB实现你的算法是正确的)。

使用t=0.001; itera=25000(左)和t=0.0001; itera=250000(右)的示例输出:

首先,请注意,这两个图是相当合理的,并且明显是有限的。其次,请注意,这两条轨迹虽然具有大致相似的形状,但非常不同。如果你使用更长的迭代(我的意思是更长的总迭代t*itera),差异会逐渐变得更加明显,最终两条轨迹将完全分道扬镳。

您应该确保您了解您正在使用一种非常不准确的方法来绘制一个非常敏感(准确地说:混沌)系统的轨迹。即使使用非常准确的方法,您最终也会积累一些错误,并且您会偏离初始值问题的实际解决方案。你所能期望的只是画出吸引子的大致形状,围绕它的轨迹将不可避免地呈锯齿形。但我相当肯定这就是你的目标。

【讨论】:

  • 非常感谢先生...我犯了那个错误并理解并得到了我想要的非常漂亮的输出。现在如果我想通过使用 4 阶 Runge kutta 方法来实现相同的系统,你能帮助我吗这里?再次感谢您提供如此详细的答案。祝您好运先生。
  • @faiz 这是一个完全不同的问题,您必须自己实现。如果您在此过程中遇到问题并且无法自己解决,请随时就您的新问题提出新问题。如果您认为我的这个答案回答了您在此处提出的问题,请考虑通过单击我的答案左侧的复选标记将我的答案标记为已接受。
  • 我检查添加先生,实际上我问过同样的问题,但我没有得到任何满意的答案,因为在文献中我知道龙格库塔法对一两个方程的实施,但我不知道不知道超过 3 个耦合方程,所以我问了,谢谢先生。
  • @faiz 谢谢。我不明白你为什么说“我没有得到任何满意的答案”,因为那里有一个答案,你在二月份回答说“非常感谢先生”。无论如何,正如那里的用户所说:如果您知道如何为 1d 实现它,那么您应该很容易地为 5d 实现它:在每个时间点使用向量而不是标量,并且每个坐标都由其自己的方程描述。它应该很简单。那么你的问题到底是什么?
  • aahhh 对不起先生,谢谢你的助手,其实我有点不好意思再次提问,但是在这段代码中: for i=2:N+1 k1 = odefunc(time , state ); k2 = odefunc(时间 + 0.5*h, 状态 + 0.5*hk1); k3 = odefunc(时间 + 0.5*h, 状态 + 0.5*hk2); k4 = odefunc(时间 + h, 状态 + h*k3);状态 = 状态 + (h/6)*(k1+2*k2+2*k3+k4); time = time + h 我无法运行这个,我对超过 2d 系统的 K1、K2、K3、K4 的值感到困惑。如何进行更改?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 2011-01-02
  • 2015-07-20
  • 1970-01-01
相关资源
最近更新 更多