枫。 Dsolve和功能

时间:2013-07-18 12:37:03

标签: maple dsolve

我有一个我的程序解决的微分方程:

p := dsolve({ic, sys}, numeric, method = rosenbrock);

解决后我们有以下内容:

print(p(10));
      [t = 10., alpha(t) = HFloat(0.031724302221312055), beta(t) = HFloat(0.00223975915581258)]

我需要使用这个alpha(t)和beta(t)如下:

a := t->exp( int(alpha(t)),x=0..t) );
b := t->exp( int(beta(t)),x=0..t) )

绘制情节:

odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue])

这样做的第一件事是:

p := dsolve({sys, ic},  numeric, method=rosenbrock); 
alpha := t->rhs(p(t)[2] );
beta := t->rhs(p(t)[3;
a := t->exp( int(alphat)),x=0..t) );
b := t->exp( int(betat)),x=0..t) );
odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue])

但是代码不起作用,显然,是的,应采取不同的行动。

1 个答案:

答案 0 :(得分:1)

首先,让我们尝试让您的方法工作,并进行一些语法和用法更改。

您没有提供示例的详细信息,因此我构建了微分方程sys和初始条件ic的系统,以便可以执行计算命令。

restart:

sys := diff(alpha(t),t) = -1/200*beta(t),
       diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2:
ic := alpha(0)=0, beta(0)=-1:

p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):

alphat := eval(alpha(t),p):
betat := eval(beta(t),p):

a := unapply( exp( Int(alphat , 0..t) ), t, numeric):
b := unapply( exp( Int(betat , 0..t) ), t, numeric):

evalf(a(20.0)), evalf(b(20.0));

                                              -18
                   5.347592595, 3.102016550 10   

st := time():
P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20,
               thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;

                           16.770 seconds

P;

enter image description here

我使用了output=listprocedure,因此我可以将正确的过程从解决方案p分配到alphatbetat。那些调用次数更有效,而不是原始版本为每个数字t值形成一系列值,然后必须选择某个操作数。它也更稳健,因为它对位置不敏感(如果你改变了变量的名称,可能会因为新的词典排序而改变)。

以上在Intel i7上花了大约16秒。那不是很快。一个原因是数值积分的计算精度高于绘图所需的精度。因此,让我们重新启动(以确保公平的时间安排)并重新计算ab的数字集成的宽松容差。

restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
       diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2:
ic := alpha(0)=0, beta(0)=-1:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):

a := unapply( exp( Int(alphat , 0..t, epsilon=1e-5) ), t, numeric):
b := unapply( exp( Int(betat , 0..t, epsilon=1e-5) ), t, numeric):

evalf(a(20.0)), evalf(b(20.0));

                                              -18
                   5.347592681, 3.102018090 10   

st := time():
P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20,
               thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;

                            0.921 seconds

您可以检查这是否显示相同的情节。

现在让我们对示例进行扩充,以便数字积分由dsolve,numeric本身计算。我们可以通过使用微积分来做到这一点。通过这种方式,我们将它留给数字ode求解器进行自己的误差估计,步长控制,刚度或奇点检测等。

请注意,积分alphatbetat不是我们具有显式函数的函数 - 它们的准确性与数字ode求解紧密相关。这与使用数字ode例程简单地用函数替换数字正交例程来解决问题并不完全相同,我们希望直接计算得到任何所需的精度(包括在任何奇点的任一侧)。

restart:

sys := diff(alpha(t),t) = -1/200*beta(t),
       diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2,
       diff(g(t),t) = alpha(t), diff(h(t),t) = beta(t):
ic := alpha(0)=0, beta(0)=-1,
      g(0)=0, h(0)=0:

p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):

alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
gt := eval(g(t),p):
ht := eval(h(t),p):

exp(gt(20.0)), exp(ht(20.0));

                                                   -18
              5.34759070530497, 3.10201330730572 10   

st := time():
P := plots:-odeplot(p, [[t, exp(g(t))], [t, exp(h(t))]], 0 .. 20,
               thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;

                            0.031 seconds
P;

enter image description here