微分方程:含导数或微分的方程。
解:满足微分方程的函数。
特解/通解:特解指的是满足微分方程的某一个解;通解指的是满足微分方程的一组解。
阶:微分方程中导数或微分的最高阶数。
线性/非线性:(几何意义:叠加原理)方程中的函数和它的各阶导数都是一次方为线性微分方程,否则为非线性。例:
齐次/非齐次:(代数意义:次数)齐次微分方程中不含常数项,也不含仅由x的各种运算组合构成的项(比如4xx,sinx等),否则为非齐次。
常微分/偏微分:未知函数是一元函数的,叫常微分方程;未知函数是多元函数的叫做偏微分方程。
初值问题和边值问题:附加条件中未知函数及其导数的独立变量取值相同,则为初值问题;附加条件中未知函数及其导数的独立变量取值不同,则为边界值问题。例:
在matlab中解微分方程,方法有两种:
解析解方法:严格按照公式逻辑推导得到的,具有基本的函数形式。
数值解方法:采用某种计算方法,在特定的条件下得到的一个近似数值结果,如有限元法,数值逼近法,插值法等等。
解析解方法可回顾《高等数学》中相关公式。
数值解方法可回顾《数值分析》中相关解法。
由Abel-Ruffini定理,四次及以下的多项式代数方程是能求出根的解析解的,即低阶常系数线性微分方程有一般意义下的解析解。
非线性微分方程只能用数值解法求解,即使看起来很简单的非线性微分方程也是没有解析解的,只有极特殊的非线性微分方程解析可解。
利用dsolve函数
例1.1 输入信号为u(t)=exp(-5*t)*cos(2*t+1)+5,求微分方程diff(y,4)+10*diff(y,3)+35*diff(y,2)+50*diff(y)+24*y=5*diff(u,t,2)+4*diff(u,t)+2*u的通解。初值条件:y(0)=3,y1(0)=2,y2(0)=0,y3(0)=0,求方程的特解。(约定y1代表一阶导数,以此类推)
代码如下:
% y=dsolve(f1,f2,...,fm) 默认自变量为t
% y=dsolve(f1,f2,...,fm,'x') 指明自变量
% f可由字符串表示也可由符号表达式表示
%用字符串表达式,新版本会被移除
syms t;
u=exp(-5*t)*cos(2*t+1)+5;
uu=5*diff(u,t,2)+4*diff(u,t)+2*u;
y=dsolve(['D4y+10*D3y+35*D2y+50*Dy+24*y=',char(uu)]); %求解
y=simplify(y) %化简
%用符号表达式,推荐
syms y(t);
eqn=diff(y,4)+10*diff(y,3)+35*diff(y,2)+50*diff(y)+24*y==uu;
y=dsolve(eqn);
y=simplify(y)
%检验
diff(y,4)+10*diff(y,3)+35*diff(y,2)+50*diff(y)+24*y-uu
%求特解并绘图
syms y(t);
eqn=diff(y,4)+10*diff(y,3)+35*diff(y,2)+50*diff(y)+24*y==uu;
y1=diff(y);y2=diff(y,2);y3=diff(y,3);y4=diff(y,4);
% 需要引入中间变量
% 用字符串求解的情况,不需要引入中间变量。'y(0)=3','Dy(0)=2','D2y(0)=0'...
cond=[y(0)==3,y1(0)==2,y2(0)==0,y3(0)==0];
z=dsolve(eqn,cond);
z=simplify(z)
ezplot(z,[0,5])
fplot(z,[0,5])
% ezplot(fun,[xmin,xmax])绘制fun(x)在以下域上的图形:xmin<x<xmax
% ezplot适用隐式函数
% 推荐fplot代替ezplot
double(subs(z,t,5))
% 验证图像,对自变量赋值,并求小数解
% 改变初值条件,再求特解,用字符串表示方式
z1=dsolve(['D4y+10*D3y+35*D2y+50*Dy+24*y=',char(uu)],...
'y(0)=1/2','Dy(pi)=1','D2y(2*pi)=0','Dy(2*pi)=1/5') %求解
fplot(z1,[0,5])
运行结果:
y =
C1*exp(-4*t) - (547*exp(-5*t)*sin(2*t + 1))/520 - (343*exp(-5*t)*cos(2*t + 1))/520 + C2*exp(-3*t) + C3*exp(-2*t) + C4*exp(-t) + 5/12
ans =0
z =
19*exp(-t) - (69*exp(-2*t))/2 + (73*exp(-3*t))/3 - (25*exp(-4*t))/4 + (97*exp(-t)*sin(1))/60 - (51*exp(-2*t)*sin(1))/13 + (5*exp(-3*t)*sin(1))/8......
ans = 0.5679
z1 =
(exp(-5*t)*(445*cos(2*t + 1) - 65*exp(5*t) + 102*sin(2*t + 1)))/26 - (exp(-5*t)*(537*cos(2*t + 1) - 40*exp(5*t) + 15*sin(2*t + 1)))/24 - (exp(-5*t)*(25*exp(5*t) - 542*cos(2*t + 1) ......


例1.2 求解有复数极点的微分方程diff(y,5)+5*diff(y,4)+12*diff(y,3)+16*diff(y,2)+12*diff(y)+4*y=diff(u)+3*u,输入信号:u(t)=sin(t),初值条件:y(0)=0,y1(0)=0,y2(0)=0,y3(0)=0,y4(0)=0
代码如下:
% 有复数极点的微分方程
syms y(t) u(t);
u=sin(t);
uu=diff(u)+3*u;
eqn=diff(y,5)+5*diff(y,4)+12*diff(y,3)+16*diff(y,2)+12*diff(y)+4*y==uu;
y1=diff(y);y2=diff(y,2);y3=diff(y,3);y4=diff(y,4); % 需要引入中间变量
cond=[y(0)==0,y1(0)==0,y2(0)==0,y3(0)==0,y4(0)==0];
y=dsolve(eqn,cond);
y=simplify(y)
fplot(y,[0,30])
% 检验
diff(y,5)+5*diff(y,4)+12*diff(y,3)+16*diff(y,2)+12*diff(y)+4*y-uu
运行结果:
y =
exp(-t) - cos(t)/5 - (2*sin(t))/5 - (4*exp(-t)*cos(t))/5 + (11*exp(-t)*sin(t))/10 - (t*exp(-t)*cos(t))/2
ans =0

例1.3 求线性微分方程组
代码如下:
%微分方程组,无法检验结果
syms y(t) x(t);
eqn1=diff(x,2)+2*diff(x)==x+2*y-exp(-t);
eqn2=diff(y)==4*x+3*y+4*exp(-t);
[x,y]=dsolve(eqn1,eqn2)
diff(x,2)+2*diff(x)-x+2*y-exp(-t)
diff(y)-4*x+3*y+4*exp(-t)
运行结果:
x =
exp(t*(6^(1/2) + 1))*(6^(1/2)/5 - 1/5)*(C2 + exp(- 2*t - 6^(1/2)*t)*((11*6^(1/2))/3 - 37/4)) - exp(-t)*(C1 + 6*t) - exp(-t*(6^(1/2) - 1))*(6^(1/2)/5 + 1/5)*(C3 - exp(6^(1/2)*t - 2*t)*((11*6^(1/2))/3 + 37/4))
y =
exp(-t)*(C1 + 6*t) + exp(t*(6^(1/2) + 1))*((2*6^(1/2))/5 + 8/5)*(C2 + exp(- 2*t - 6^(1/2)*t)*((11*6^(1/2))/3 - 37/4)) - exp(-t*(6^(1/2) - 1))*((2*6^(1/2))/5 - 8/5)*(C3 - exp(6^(1/2)*t - 2*t)*((11*6^(1/2))/3 + 37/4))
ans =(无法检验)
4*exp(-t)*(C1 + 6*t) - exp(-t) - exp(t*(6^(1/2) + 1))*(6^(1/2)/5 - 1/5)*(C2 + exp(- 2*t - 6^(1/2)*t)*((11*6^(1/2))/3 - 37/4)) + ......
ans =(无法检验)
10*exp(-t) + 6*exp(-t)*(C1 + 6*t) - 4*exp(t*(6^(1/2) + 1))*(6^(1/2)/5 - 1/5)*(C2 + exp(- 2*t - 6^(1/2)*t)*((11*6^(1/2))/3 - 37/4)) +......
例1.4 求解自变量为x的时变线性微分方程(2*x+3)^3*diff(y,3)+3*(2*x+3)*diff(y)-6*y=0
代码如下:
% 自变量为x的时变微分方程
syms x y(x);
y=dsolve((2*x+3)^3*diff(y,3)+3*(2*x+3)*diff(y)-6*y==0);
simplify(y)
(2*x+3)^3*diff(y,3)+3*(2*x+3)*diff(y)-6*y
运行结果:
y =
C1*(x + 3/2) - 2*C2*(x + 3/2)^(1/2) + C3*(2*x + 6)*(x + 3/2)^(1/2)
ans =(无法检验)
12*C2*(x + 3/2)^(1/2) - 6*C1*(x + 3/2) - (2*x + 3)^3*((3*C3)/(2*(x + 3/2)^(3/2)) + (3*C2)/(4*(x + 3/2)^(5/2)) - (3*C3*(2*x + 6))/(8*(x + 3/2)^(5/2))) + (6*x + 9)*(C1 - C2/(x + 3/2)^(1/2) + 2*C3*(x + 3/2)^(1/2) + (C3*(2*x + 6))/(2*(x + 3/2)^(1/2))) - 6*C3*(2*x + 6)*(x + 3/2)^(1/2)
例1.5 求解高阶常系数微分方程组
代码如下:
% 高阶常系数线性微分方程
syms x(t) y(t) z(t);
eqn1=diff(x,2)-x+y+z==0;
eqn2=x+diff(y,2)-y+z==0;
eqn3=x+y+diff(z,2)-z==0;
x1=diff(x);y1=diff(y);z1=diff(z);
cond=[x(0)==1,y(0)==0,z(0)==0,x1(0)==0,y1(0)==0,z1(0)==0];
[x y z]=dsolve(eqn1,eqn2,eqn3,cond)
% 检验,成功
diff(x,2)-x+y+z
x+diff(y,2)-y+z
x+y+diff(z,2)-z
运行结果:
x =
exp(2^(1/2)*t)/3 + exp(-2^(1/2)*t)/3 + cos(t)/3
y =
cos(t)/3 - exp(-2^(1/2)*t)/6 - exp(2^(1/2)*t)/6
z =
cos(t)/3 - exp(-2^(1/2)*t)/6 - exp(2^(1/2)*t)/6
ans =0
ans =0
ans =0
例1.6 求解时变线性微分方程x^2*(2*x-1)*diff(y,x,3)+(4*x-3)*x*diff(y,x,2)-2*x*diff(y,x)+2*y=0
代码如下:
% 自变量为x的时变微分方程
syms x y(x);
eqn=x^2*(2*x-1)*diff(y,x,3)+(4*x-3)*x*diff(y,x,2)-2*x*diff(y,x)+2*y==0;
y=dsolve(eqn);
simplify(y)
% 检验,失败
x^2*(2*x-1)*diff(y,3)-(4*x-3)*x*diff(y,2)-2*x*diff(y)+2*y
运行结果:
y =
-(2*C1 - C3 + 8*C3*x + 32*C2*x^2 + 8*C3*x^2*log(x))/(16*x)
ans =(无法检验)
2*x*((8*C3 + 64*C2*x + 8*C3*x + 16*C3*x*log(x))/(16*x) - (2*C1 - C3 + 8*C3*x + 32*C2*x^2 + 8*C3*x^2*log(x))/(16*x^2))+...
例1.7 求解特殊非线性微分方程diff(x)=x*(1-x^2)
代码如下:
% 特殊非线性方程
syms x(t);
x=dsolve(diff(x)==x*(1-x^2))
运行结果:
x =
(-1/(exp(C1 - 2*t) - 1))^(1/2)
0
1
-1
注:若改为x=dsolve(diff(x)==x*(1-x^2)+1),则无解。
大部分为关于微分方程的初值问题的数值解法,这类问题需要用一阶显式微分方程组描述为
x ' ( t ) = f ( t , x ( t ) )
1、手动编写算法。例如:
四阶定步长Runge-Kutta算法matlab代码如下:
function [tout,yout]=rk_4(fun,tspan,y0)
ts=tspan;
t0=ts(1);
tf=ts(2);
yout=[];
tout=[];
y0=y0(:);
if length(tspan)==3,
h=ts(3);
else,
h=(ts(2)-ts(1))/100;
tf=ts(2);
end
for t = [t0:h:tf] % 对各个时间点循环计算
k1=h*fun(t,y0);
k2=h*fun(t+h/2,y0+k1/2);
k3=h*fun(t+h/2,y0+k2/2);
k4=h*fun(t+h,y0+k3);
y0=y0+(k1+2*k2+2*k3+k4)/6;
yout=[yout;y0.'];
tout=[tout;t];
end
2、ode系列函数:最常用ode45()
介绍
ode45()实现了变步长四阶五级 Runge-Kutta-Felhberg算法,可以使用变步长的方法求解微分方程。ode系列函数功能总结如下:

用法
函数调用:
微分方程/组描述:
控制条件:使用odesrt()函数创建或修改 options 结构体。
例:options = odeset('RelTol',1e-5,'Stats','on','OutputFcn',@odeplot) 指定 1e-5 的相对误差容限、打开求解器统计信息的显示,并指定输出函数 @odeplot 在计算时绘制解。
实例
例2.1 解微分方程组
其中,beta=8/3,Pho=10,sigma=28,初值:x1(0)=x2(0)=0,x3(0)=10e-10
代码1:(不带有附加参数的函数)
f=@(t,x) [-8/3*x(1)+x(2)*x(3);-10*x(2)+10*x(3);-x(1)*x(2)+28*x(2)-x(3)]
% 编写匿名函数描述动态模型
tn=100;
x0=[0;0;1e-10];
[t,x]=ode45(f,[0,tn],x0); %求方程数值解
plot(t,x);
figure;
plot3(x(:,1),x(:,2),x(:,3)); %相空间轨迹三维图
grid % 显示或隐藏坐标区网格线
figure;
comet3(x(:,1),x(:,2),x(:,3)); %绘制动画式轨迹
运行结果:

代码2:(带有附加参数的函数)
函数程序:
function f=c_7_2_fun
% 定义一个接口,通过匿名函数调用
% 通过定义接口的方式,在一个函数文件实例里可编写多个函数
f.lorenz1=@lorenz1;
end
function dx=lorenz1(t,x,b,r,s) % 带有附加参数的微分方程描述曲线
dx=[-b*x(1)+x(2)*x(3);-r*x(2)+r*x(3);-x(1)*x(2)+s*x(2)-x(3)];
end
主程序:
%% 编写带有附加参数的函数
% 函数需列在单独的文件里,且函数名和文件名一致,可通过定义接口的方式,在一个函数文件例里编写多个函数
f=c_7_2_fun % 调用接口
% 设置附加参数的值
b1=8/3;r1=10;s1=28;tn=100;x0=[0;0;1e-10];
[t,x]=ode45(@f.lorenz1,[0,tn],x0,[],b1,r1,s1); % 无需使用和函数一样的变量名
% 求方程数值解
% 空矩阵表示使用默认的控制模版
figure(1);
plot(t,x);
figure(2);
comet3(x(:,1),x(:,2),x(:,3)); %绘制动画式轨迹
grid
%% 改变附加参数的值
b2=2;r2=5;s2=20;tn=100;x0=[0;0;1e-10];
[t2,x2]=ode45(@f.lorenz1,[0,tn],x0,[],b2,r2,s2);
% 求方程数值解
% 空矩阵表示使用默认的控制模版
figure(3);
plot(t2,x2);
figure(4);
comet3(x2(:,1),x2(:,2),x2(:,3)); %绘制动画式轨迹
grid %只针对上一个绘图
% TIPS
%% 使用匿名函数则可以不用附加参数
b=8/3;r=10;s=28;tn=100;x0=[0;0;1e-10];
f=@(t,x) [-b*x(1)+x(2)*x(3);-r*x(2)+r*x(3);-x(1)*x(2)+s*x(2)-x(3)];
% 匿名函数可以直接使用matlab工作空间中的变量
[t,x]=ode45(f,[0,tn],x0); %求方程数值解
plot(t,x);
figure;
plot3(x(:,1),x(:,2),x(:,3)); %相空间轨迹三维图
grid % 显示或隐藏坐标区网格线
注:函数需列在单独的文件里,且函数名和文件名一致,才可保证正常调用,即一个函数对应一个函数文件;现可通过定义接口的方式,在一个函数文件实例里编写多个函数,调用时调用接口。
运行结果:(改变参数前的运行结果同上)

本文仅涉及一般常微分方程求解,对于一些特殊常微分方程的求解方法见同专栏相关文章。
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1