You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

numpy中empty()与zeros()初始化洛伦兹吸引子绘图异常问题咨询

洛伦兹吸引子绘图异常示意图

问题原因

核心bug是初始值赋值的位置写反了:代码中先执行了20000次迭代计算,才给三个数组的索引0位置赋预设的初始值(0., 1., 1.05)。迭代过程中计算索引1及之后的数值时,用到的索引0位置的值,完全是数组初始化时自带的默认值,根本不是设定的初始条件,属于典型的未定义行为。

不同初始化方式表现不一致的原因:

  • np.empty()创建数组时不会对内存空间做任何赋值操作,数组元素是对应内存位置残留的旧数据,值完全随机。之前能跑出正确图形纯靠运气:内存残留值刚好满足洛伦兹迭代的混沌触发条件,就得到了看似正确的结果,本质是错误代码碰巧跑出了符合预期的输出。
  • np.zeros()会把数组所有元素初始化为0。当dydt用zeros初始化时,迭代用到的dydt[0]为0,代入第一步迭代公式后,所有后续计算值都会沿着固定线性路径变化,不会进入混沌状态,最终绘制出直线。
  • 单独把dxdt、dzdt换成zeros初始化仍能出图,是因为这两个位置初始为0时,只要dydt[0]的随机残留值不为0,仍然能碰巧触发混沌迭代路径,不代表代码逻辑正确。

原代码还存在两处显性问题:一是迭代公式中dzdt[i\]多了多余的反斜杠,会触发语法错误;二是fig.gca(projection='3d')的写法在高版本matplotlib中已被废弃。

修复方案

把初始值赋值语句移动到迭代循环之前,先给数组起始位赋正确的初始值,再开始迭代计算。修正后无论用np.empty()还是np.zeros()初始化数组,都能稳定得到正确的洛伦兹吸引子图形。

修正后的代码如下:

import numpy as np
import matplotlib.pyplot as plt

# 混沌模型参数
σ = 10
ρ = 28
β = 8/3

dt = 0.01  # 迭代步长
num_steps = 20000
    
# 初始化数组
dxdt = np.zeros(num_steps + 1)
dydt = np.zeros(num_steps + 1)
dzdt = np.zeros(num_steps + 1)

# 先赋初始值,再做迭代
dxdt[0], dydt[0], dzdt[0] = (0., 1., 1.05)

# 迭代计算
for i in range(num_steps):
    dxdt[i+1] = dxdt[i] + σ*(dydt[i] - dxdt[i])*dt
    dydt[i+1] = dydt[i] + (dxdt[i] * (ρ - dzdt[i]) - dydt[i])*dt
    dzdt[i+1] = dzdt[i] + (dxdt[i] * dydt[i] - β * dzdt[i])*dt

# 绘图
fig = plt.figure(figsize=(16, 16), dpi=400)
ax = fig.add_subplot(projection='3d')
ax.plot(dxdt, dydt, dzdt, lw=0.5)
ax.set_xlabel("X Axis")
ax.set_ylabel("Y Axis")
ax.set_zlabel("Z Axis")
ax.set_title("Lorenz Attractor")
plt.show()

内容的提问来源于stack exchange,提问作者Trissa Shamp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 13:54:25