ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

微分方程建模实战:从SIR模型到时滞Logistic的MATLAB实现

微分方程建模实战:从SIR模型到时滞Logistic的MATLAB实现 1. 项目概述微分方程在数学建模中的核心地位在数学建模的实战领域微分方程绝对算得上是“顶梁柱”级别的工具。无论是描述人口增长、疾病传播还是模拟物理运动、化学反应甚至分析金融市场微分方程都能提供一个强有力的数学框架将动态变化的过程清晰地刻画出来。简单来说当你面对一个系统其未来的状态不仅取决于当前状态更取决于其变化的“趋势”时微分方程就是你最该想到的武器。这个项目标题“数学建模之微分方程(符实现例题和MATLAB源码)”精准地指向了从理论到实践的关键一跃。很多同学学微分方程时公式推导头头是道但一到用计算机求解具体模型、分析结果时就卡壳了。这正是本内容要解决的核心痛点通过具体的、有代表性的例题结合可直接运行的MATLAB源码手把手带你打通“建立方程 - 数值求解 - 结果分析 - 模型优化”的全流程让你不仅懂原理更能亲手实现并看到结果。2. 核心思路与模型选型解析数学建模中使用微分方程绝不是简单地套公式。其核心思路在于“转化”将现实世界中模糊的、定性的问题转化为精确的、定量的微分方程模型。这个过程通常遵循“假设 - 定义变量 - 建立关系 - 构成方程”的路径。2.1 为何选择微分方程模型在建模竞赛或实际研究中选择微分方程模型通常基于以下几个关键考量动态性研究对象的状态随时间连续变化。例如传染病模型中易感者、感染者的数量热传导问题中的温度分布生态模型中种群的数量。依赖性变化率导数依赖于当前状态本身。比如种群增长速率与当前种群规模成正比Malthus模型或受资源限制Logistic模型。记忆性在某些模型中变化率可能还依赖于过去的状态时滞微分方程这能描述像政策生效有延迟、疾病有潜伏期等现象。当你识别出问题具有这些特征时微分方程就是一个非常自然的候选模型。相较于单纯的统计拟合微分方程模型具有更强的机理性和解释性能帮助我们理解系统内在的运行规律而不仅仅是描述数据表象。2.2 常见微分方程模型类型与选型指南面对具体问题选择哪种类型的微分方程是关键第一步。下面是一个快速选型参考模型类型典型形式适用场景MATLAB求解核心函数/工具常微分方程(ODE)dy/dt f(t, y)单变量随时间变化或状态可用有限个变量描述的系统。如自由落体、RC电路充电、单一种群增长。ode45,ode23,ode15s(刚性问题)常微分方程组(ODEs)dY/dt F(t, Y)多个相互关联的变量同时随时间变化。如传染病SIR模型、洛伦兹吸引子、多物种竞争模型。ode45(多数情况),ode15s(刚性系统)偏微分方程(PDE)含有多元偏导数如热方程、波动方程状态在空间和时间上均连续变化。如热量在金属板上的扩散、污染物在河流中的输运、图像处理中的滤波。PDE Toolbox, 有限差分法自定义实现时滞微分方程(DDE)dy/dt f(t, y(t), y(t-τ))系统当前变化率依赖于过去某一时刻的状态。如有潜伏期的流行病模型、供应链库存控制。dde23随机微分方程(SDE)dX μ(t,X)dt σ(t,X)dW系统演化受确定性趋势和随机扰动共同影响。如股票价格模拟、受噪声影响的物理系统。需自定义基于欧拉-丸山法等算法选型心得对于数学建模初学者建议从常微分方程组入手。它们概念相对直观MATLAB支持完善且能覆盖大量经典赛题如人口预测、传染病动力学、战争模型等。在确定使用ODE后还需判断是否为“刚性”问题。简单来说如果系统中不同变量或过程的变化速率差异巨大比如有的反应瞬间完成有的极其缓慢就容易出现刚性此时应选用ode15s等适用于刚性问题的求解器否则用默认的ode45即可它对于大多数非刚性问题是高效且准确的。3. 实战案例一传染病SIR模型建模与实现我们用一个经典的传染病SIR模型作为第一个实战案例。这个模型将人群分为三类易感者(S)、感染者(I)、康复者(R)。它清晰地展示了微分方程组如何描述一个动态交互系统。3.1 模型建立与参数意义假设总人口N不变即不考虑出生与死亡且康复者具有永久免疫力。模型如下易感者变化率 dS/dt 易感者只会因为被感染而减少。感染率与易感者数量S和感染者数量I的乘积成正比因为接触机会比例系数是感染系数β。dS/dt -β * S * I / N这里除以N是为了将接触率标准化有时也直接写为-βSI含义略有不同需在模型中统一。感染者变化率 dI/dt 感染者由易感者转化而来同时会以康复率γ转化为康复者。dI/dt β * S * I / N - γ * I康复者变化率 dR/dt 康复者由感染者转化而来。dR/dt γ * I其中关键参数有两个β (感染率) 衡量疾病传染能力的强弱。值越大传染越快。γ (康复率) 平均感染周期的倒数。例如如果平均感染7天康复则 γ 1/7 ≈ 0.1429/天。一个更重要的衍生参数是基本再生数 R0 β / γ。它表示一个感染者在完全易感人群中平均能传染多少人。R0 1时疾病会爆发R0 1时疾病会逐渐消失。这是分析疫情走向的核心指标。3.2 MATLAB源码实现与逐行解析下面是在MATLAB中实现SIR模型求解和可视化的完整代码。我们将采用函数化的编写方式便于修改参数和复用。% SIR_Model.m % 经典传染病SIR模型模拟 function SIR_Model() % 1. 模型参数设置 beta 0.3; % 感染率可调整以观察不同传染强度 gamma 0.1; % 康复率对应平均感染期10天 R0 beta / gamma; % 基本再生数 fprintf(基本再生数 R0 %.2f\n, R0); % 2. 初始条件 N 1000; % 总人口 I0 1; % 初始感染者1个 S0 N - I0; % 初始易感者 R0_num 0; % 初始康复者 (为避免与R0重名此处用R0_num) y0 [S0; I0; R0_num]; % 初始状态向量 [S; I; R] % 3. 时间范围 (天) tspan [0, 150]; % 模拟150天 % 4. 定义微分方程组函数 % 格式dydt odeSystem(t, y) % y(1)S, y(2)I, y(3)R function dydt odeSystem(~, y) S y(1); I y(2); % R y(3); % 在方程中未直接用到但计算需要守恒 dS_dt -beta * S * I / N; dI_dt beta * S * I / N - gamma * I; dR_dt gamma * I; dydt [dS_dt; dI_dt; dR_dt]; end % 5. 调用ODE求解器 ode45 % RelTol 和 AbsTol 控制求解精度可根据需要调整 options odeset(RelTol, 1e-6, AbsTol, 1e-9); [t, y] ode45(odeSystem, tspan, y0, options); % 6. 提取结果 S y(:, 1); I y(:, 2); R y(:, 3); % 7. 可视化 figure(Position, [100, 100, 1200, 500]); % 设置图形窗口大小 % 子图1人群类别随时间变化 subplot(1, 2, 1); plot(t, S, b-, LineWidth, 2); hold on; plot(t, I, r-, LineWidth, 2); plot(t, R, g-, LineWidth, 2); hold off; grid on; xlabel(时间 (天)); ylabel(人口数量); title([SIR模型动态 (β, num2str(beta), , γ, num2str(gamma), , R_0, num2str(R0, %.2f), )]); legend(易感者 S, 感染者 I, 康复者 R, Location, best); % 子图2相平面图 (S-I图)有助于观察轨迹 subplot(1, 2, 2); plot(S, I, k-, LineWidth, 1.5); xlabel(易感者 S); ylabel(感染者 I); title(S-I 相平面图); grid on; % 8. 输出关键结果 [peakI, peakIndex] max(I); % 找到感染人数峰值 peakTime t(peakIndex); fprintf(疫情峰值信息:\n); fprintf( 峰值感染人数: %.2f (约占总人口 %.1f%%)\n, peakI, peakI/N*100); fprintf( 达到峰值时间: 第 %.1f 天\n, peakTime); fprintf( 最终易感者比例: %.2f%%\n, S(end)/N*100); end代码关键点解析与实操心得函数封装将整个模型封装在一个函数SIR_Model()中这是一个好习惯。它避免了变量在基础工作区的污染也便于将此模型作为子模块集成到更大的分析脚本中。参数集中管理所有参数beta,gamma,N在开头明确定义。修改参数极其方便便于进行参数敏感性分析例如研究β变化对峰值感染人数的影响。嵌套函数定义odeSystem被定义为当前函数的子函数使用function dydt odeSystem(~, y)。它接收时间t和状态向量y返回导数向量dydt。这里用~忽略时间变量因为本模型是自治系统方程右端不显含时间t。求解器选项odeset用于设置求解精度。RelTol相对误差容限和AbsTol绝对误差容限的默认值通常够用但对于结果异常或需要高精度时适当收紧这些容限如设为1e-8是有效的调试手段。结果提取与验证计算完成后可以简单验证SIR是否恒等于N以确保模型守恒律正确。sum(y(end, :))应该非常接近N。可视化与洞察除了绘制时间序列图相平面图S-I图是分析微分方程系统长期行为的强大工具。图中一条从初始点开始的轨迹直观展示了系统演化的路径。踩坑提醒在定义微分方程时最容易出错的是符号和系数。务必根据物理/生物意义仔细检查每个项是正是负。例如在SIR模型中易感者减少所以dS/dt为负感染者增加项为正减少项为负。建议每写完一个方程都口头复述其意义。4. 实战案例二带有时滞的种群增长模型现实中的许多过程存在延迟效应。例如种群增长不仅依赖于当前资源也可能受到过去种群密度对资源消耗影响的延迟反馈。这时时滞微分方程就派上用场了。我们考虑一个带有时滞的Logistic模型也称为Hutchinson方程。4.1 时滞Logistic模型建立标准的Logistic模型为dN/dt r * N * (1 - N/K)。 其中N是种群数量r是内禀增长率K是环境容纳量。时滞版本假设种群的增长受到τ时间前种群规模的影响方程变为dN/dt r * N(t) * (1 - N(t-τ) / K)这个方程的含义是当前的增长潜力受到过去某个时刻t-τ资源竞争程度的影响。时滞τ可能代表繁殖周期、资源再生时间或信息传递延迟。4.2 使用dde23求解与时滞效应分析MATLAB提供了专门的求解器dde23来处理时滞微分方程。与ode45不同我们需要提供历史函数在初始时间之前的状态和时滞常量。% Delayed_Logistic.m % 时滞Logistic种群增长模型 function Delayed_Logistic() % 1. 模型参数 r 0.8; % 增长率 K 100; % 环境容纳量 tau 2; % 时滞时间 (关键参数) % 2. 定义时滞微分方程 % dN/dt r * N * (1 - N(t-tau)/K) ddefun (t, N, Z) r * N * (1 - Z / K); % Z 对应着 N(t-tau) % 3. 定义时滞常量 lags tau; % 可以是一个标量也可以是时滞向量 [tau1, tau2, ...] % 4. 定义历史函数在时间 t t0 时N(t) 的值 % 假设在时滞期间种群数量保持为常数 N0 N0 10; % 初始时刻 t0 的种群数量 history N0; % 对于常数历史可以直接赋值 % 5. 求解时间区间 tspan [0, 50]; % 6. 调用DDE求解器 dde23 sol dde23(ddefun, lags, history, tspan); % 7. 在更密的点上计算解用于平滑绘图 t_eval linspace(tspan(1), tspan(end), 1000); N_eval deval(sol, t_eval); % 8. 可视化 figure(Position, [100, 100, 1000, 400]); % 子图1种群动态 subplot(1, 2, 1); plot(t_eval, N_eval, b-, LineWidth, 2); hold on; % 绘制环境容纳量K作为参考线 plot(tspan, [K, K], r--, LineWidth, 1.5); hold off; grid on; xlabel(时间 t); ylabel(种群数量 N(t)); title([时滞Logistic模型 (r, num2str(r), , K, num2str(K), , \tau, num2str(tau), )]); legend(种群数量 N(t), 环境容纳量 K, Location, best); ylim([0, max(N_eval)*1.1]); % 子图2对比无时滞的标准Logistic解 subplot(1, 2, 2); % 求解标准Logistic方程作为对比 [t_ode, N_ode] ode45((t,y) r*y*(1-y/K), tspan, N0); plot(t_eval, N_eval, b-, LineWidth, 2); hold on; plot(t_ode, N_ode, m--, LineWidth, 2); hold off; grid on; xlabel(时间 t); ylabel(种群数量 N(t)); title(有时滞 vs 无时滞对比); legend([有时滞 (\tau, num2str(tau), )], 无时滞, Location, best); % 9. 分析时滞的影响观察是否出现振荡 % 计算最后若干周期的峰值判断是否稳定 [peaks, locs] findpeaks(N_eval); % 需要Signal Processing Toolbox if length(peaks) 2 fprintf(系统表现出振荡行为。\n); fprintf(最后几个峰值: ); fprintf(%.2f , peaks(end-2:end)); fprintf(\n); % 可以进一步计算振荡周期等 else fprintf(系统趋于稳定平衡。\n); end end时滞模型实现要点与深度分析dde23函数接口核心是定义ddefun其输入参数(t, N, Z)中Z就是延迟状态N(t-τ)。对于多个时滞lags是一个向量Z会变成矩阵每一列对应一个时滞。历史函数history这是DDE求解特有的。它定义了在求解开始时间t0之前状态变量N(t)的行为。可以是常数、函数句柄或更复杂的结构。本例中假设在t0时种群数恒为N0这是一种常见简化。解的提取dde23返回一个结构体sol使用deval函数可以在任意时间点t_eval上计算解的值这比直接使用sol.x和sol.y求解器自适应步长产生的离散点绘图更平滑。时滞效应观察通过调整参数tau可以观察到丰富的动力学行为小τ解的行为接近标准Logistic曲线平滑地趋向于K。中等τ解在趋向K的过程中会发生过冲即种群数量会先超过K然后下降并可能围绕K衰减振荡。大τ可能导致稳定的周期振荡甚至混沌。这是时滞引入非线性效应的典型结果也是研究热点。实操心得调试DDE模型时如果解出现剧烈振荡或数值爆炸首先检查时滞τ是否设置得过大相对于系统的时间尺度1/r。其次检查历史函数是否与初始条件连续。不连续的历史函数可能导致求解初期出现数值困难此时可以尝试使用ddeset设置初始Jump属性或使用更专业的求解器如ddensd。5. 模型校准与参数估计实战建立微分方程模型后参数如SIR模型中的β和γ往往未知。我们需要利用实际观测数据来估计这些参数这个过程称为模型校准或参数估计。这是连接理论模型与现实世界的关键桥梁。5.1 参数估计的基本思路最小化误差思路很直观找到一组参数使得模型输出的曲线与真实数据点之间的“差距”最小。这个“差距”通常用误差的平方和来衡量即最小二乘法。假设我们有时间序列数据t_data和对应的观测值y_data例如每日新增感染人数。我们的模型可以输出对应时间的模拟值y_sim。参数估计问题转化为一个优化问题寻找参数p使得目标函数F(p) sum( (y_sim(p) - y_data).^2 )最小。5.2 基于lsqcurvefit的SIR模型参数估计MATLAB实现我们模拟一份“观测数据”然后演示如何从数据中反推出β和γ。% Parameter_Estimation_SIR.m % SIR模型参数估计示例 function Parameter_Estimation_SIR() % --- 第一部分生成模拟“真实”数据 (用于演示) --- true_beta 0.35; % 真实的感染率 true_gamma 0.1; % 真实的康复率 N 1000; I0 5; S0 N - I0; R0 0; y0_true [S0; I0; R0]; tspan_data 0:1:100; % 每天一个数据点 % 使用真实参数运行模型并加入一些随机噪声模拟现实误差 [~, y_true] ode45((t,y) sir_ode(t, y, true_beta, true_gamma, N), ... tspan_data, y0_true); I_true y_true(:, 2); % 提取感染者数量 % 加入5%的高斯噪声 rng(42); % 固定随机种子使结果可重现 noise_level 0.05; I_data I_true .* (1 noise_level * randn(size(I_true))); % 确保数据非负 I_data max(I_data, 0); fprintf(用于拟合的“真实”参数: beta %.3f, gamma %.3f\n, true_beta, true_gamma); % --- 第二部分定义待拟合的模型函数 --- % 此函数接收参数p和自变量t返回模型预测值此处为I(t) modelFunc (p, t) simulate_SIR_I(p, t, y0_true, N); % --- 第三部分设置初始猜测和边界并进行拟合 --- p0 [0.2, 0.05]; % 参数初始猜测值 [beta_guess, gamma_guess] lb [0.01, 0.01]; % 参数下界 (必须为正) ub [1.0, 0.5]; % 参数上界 % 使用 lsqcurvefit 进行非线性最小二乘拟合 options optimoptions(lsqcurvefit, Display, iter, ... Algorithm, trust-region-reflective); [p_est, resnorm, residual, exitflag, output] ... lsqcurvefit(modelFunc, p0, tspan_data, I_data, lb, ub, options); beta_est p_est(1); gamma_est p_est(2); R0_est beta_est / gamma_est; fprintf(\n--- 拟合结果 ---\n); fprintf(估计的感染率 beta_est %.4f\n, beta_est); fprintf(估计的康复率 gamma_est %.4f\n, gamma_est); fprintf(估计的基本再生数 R0_est %.2f\n, R0_est); fprintf(真实 R0 %.2f\n, true_beta/true_gamma); % --- 第四部分可视化拟合效果 --- % 用估计的参数重新模拟 I_fitted modelFunc(p_est, tspan_data); figure; plot(tspan_data, I_data, bo, MarkerSize, 6, DisplayName, 带噪声的观测数据); hold on; plot(tspan_data, I_fitted, r-, LineWidth, 2, DisplayName, 拟合曲线); plot(tspan_data, I_true, k--, LineWidth, 1.5, DisplayName, 真实曲线无噪声); hold off; grid on; xlabel(时间 (天)); ylabel(感染者数量 I(t)); title(SIR模型参数拟合效果); legend(Location, best); % --- 第五部分评估拟合优度 --- % 计算R平方 SS_res sum(residual.^2); SS_tot sum((I_data - mean(I_data)).^2); R_squared 1 - SS_res / SS_tot; fprintf(拟合优度 R^2 %.4f\n, R_squared); end % --- 辅助函数SIR模型ODE定义 --- function dydt sir_ode(~, y, beta, gamma, N) S y(1); I y(2); dS_dt -beta * S * I / N; dI_dt beta * S * I / N - gamma * I; dR_dt gamma * I; dydt [dS_dt; dI_dt; dR_dt]; end % --- 辅助函数模拟SIR模型并返回I(t) --- function I_sim simulate_SIR_I(p, t, y0, N) % p [beta, gamma] beta p(1); gamma p(2); % 确保时间t是列向量ode45要求如此 if isrow(t) t t; end % 求解ODE [~, y] ode45((tt, yy) sir_ode(tt, yy, beta, gamma, N), ... [min(t), max(t)], y0); % 插值到指定的时间点t上 I_sim interp1(y(:,2), t, linear); % 简单线性插值y(:,2)是I % 注意这里为了简化直接用了ode45输出的I。更严谨的做法是使用deval。 end参数估计的要点与陷阱初始猜测至关重要lsqcurvefit等优化算法对初始值敏感。一个糟糕的初始猜测可能导致算法收敛到局部最优解甚至失败。应根据问题的物理/生物意义给出合理猜测如β通常在0.1-1之间γ与平均感染期相关。参数边界约束使用lb和ub设置参数的物理可行范围如感染率、康复率必须为正能极大提高拟合的稳定性和合理性。数据与模型的匹配确保你拟合的模型输出与观测数据是同一物理量。本例中我们拟合的是感染者数量I(t)。现实中我们可能观测到的是每日新增病例即dI/dt γI近似这时模型函数就需要相应调整。结果评估不要只看拟合曲线“像不像”。残差分析观察residual是否随机分布和R²是基本的评估指标。对于微分方程模型还可以检查估计出的参数是否在生物学/物理学的合理范围内。深度建议对于更复杂的模型或糟糕的数据单一的最小二乘法可能不够鲁棒。可以尝试全局优化算法如particleswarm粒子群或ga遗传算法避免局部最优但计算成本高。贝叶斯估计提供参数的不确定性区间而不仅仅是点估计结果更具统计意义。使用专门工具考虑MATLAB的System Identification Toolbox或第三方工具如Monolix、NONMEM用于药代动力学进行更专业的参数估计。6. 常见问题、调试技巧与性能优化在实际编码和求解微分方程模型时你会遇到各种报错和意外结果。这里汇总了一些典型问题及其解决方法。6.1 求解器报错与解决方案报错信息/现象可能原因排查与解决思路Warning: Failure at t...或Unable to meet integration tolerances1. 方程存在奇点如除以零。2. 解发散至无穷大。3. 问题是刚性的但使用了非刚性求解器如ode45。4. 时间步长过小达到最小步长限制。1. 检查方程在求解区间内是否定义良好。例如Logistic模型中K不能为0。2. 检查模型参数和初始条件是否合理。尝试缩小时间区间tspan。3.换用刚性求解器如ode15s或ode23s。4. 使用odeset放宽精度要求增大RelTol,AbsTol或检查方程尺度是否差异巨大尝试归一化变量。解出现非物理振荡特别是PDE或DDE1. 数值不稳定性。2. 空间/时间步长太大对于自编的有限差分法。3. 时滞参数设置不合理。1. 对于自编算法减小步长是首选。2. 检查离散格式的稳定性条件如CFL条件。3. 对于DDE尝试减小时滞τ或调整历史函数。求解速度极慢1. 方程非常复杂计算导数函数f(t,y)耗时久。2. 时间区间很长或精度要求过高。3. 使用了不适合的求解器。1. 优化导数函数f的代码避免循环使用向量化操作。2. 适当放宽RelTol和AbsTol如从1e-9放到1e-6。3. 对于光滑问题尝试ode113多步法对于刚性问題确保使用ode15s。结果与预期或文献不符1.参数单位不一致最常见。2. 初始条件设置错误。3. 方程符号写反或系数错误。1.彻底检查所有参数的单位。时间单位天/小时、人口单位个体/千分比必须统一。2. 用极简情况验证例如设β0看感染者是否按exp(-γt)衰减。3. 将你的方程与经典文献中的方程逐项比对。6.2 模型验证与敏感性分析一个可靠的模型必须经过验证。量纲一致性检查确保方程每一项的量纲相同。这是发现公式抄写错误的最快方法。极限情况测试在SIR模型中令I00系统应保持不变。令γ极大感染者应立即移除模型退化为SI模型。令β0应无疫情发生。敏感性分析研究模型输出对输入参数变化的敏感程度。这能告诉你哪些参数需要高精度估计哪些影响不大。% 简单的单参数敏感性分析示例以SIR峰值感染人数为例 beta_range linspace(0.1, 0.5, 20); peak_I zeros(size(beta_range)); for i 1:length(beta_range) % 固定其他参数用不同beta模拟 [~, y] ode45((t,y)sir_ode(t,y,beta_range(i),0.1,1000), [0 150], [999 1 0]); peak_I(i) max(y(:,2)); end figure; plot(beta_range, peak_I, o-); xlabel(\beta); ylabel(峰值感染人数); title(峰值感染人数对感染率\beta的敏感性);更高级的方法包括局部敏感性求偏导和全局敏感性分析如Sobol指数。6.3 代码性能优化技巧当模型变得复杂如高维ODE、PDE性能成为瓶颈。向量化这是MATLAB性能提升的黄金法则。避免在导数函数f(t,y)中使用循环。% 慢循环 for i 1:n dydt(i) ... % 计算 end % 快向量化 dydt A * y b; % 假设是线性系统预分配数组在需要存储中间结果时预先用zeros分配足够大小的数组避免动态增长。使用ode求解器的雅可比矩阵对于刚性或复杂问题提供雅可比矩阵导数函数对状态变量的偏导数矩阵能大幅提升ode15s等求解器的速度和稳定性。使用odeset的Jacobian选项。将不变参数声明为外部变量避免在导数函数内部重复计算常量。通过匿名函数或嵌套函数将参数传入。% 推荐方式通过匿名函数传递参数 beta 0.3; gamma 0.1; N1000; odefun (t,y) [ -beta*y(1)*y(2)/N; beta*y(1)*y(2)/N - gamma*y(2); gamma*y(2) ];从理解微分方程在建模中的核心作用到亲手实现SIR、时滞模型再到利用数据校准参数最后掌握调试和优化技巧这套组合拳打下来你面对数学建模中的微分方程问题应该有了充足的底气。记住关键不在于记住所有公式而在于掌握“将问题转化为方程用工具求解并对结果进行批判性分析”的完整工作流。多动手修改代码中的参数观察图形如何变化这种直观感受是任何书本都无法替代的。当你再看到“建立微分方程模型”这样的赛题要求时希望你的第一反应不再是迷茫而是打开MATLAB开始构建你的第一个方程。
返回列表