1

我正在尝试为我的微分方程课解决这个作业,但遇到了一些问题。

鉴于此 ODE 系统:

dy(1) = y(2) − y(3);
dy(2) = −3*y(2) − 5*sin(ω*y(1));
dy(3) = y(1)*y(2);

omega=3. 初始值:y(1)=0; y(2)=4; y(3)=1;

在和f之间绘制:t=0t=20

f(t) = |2*cos(y1(t)) + y2(t)|

我首先尝试使用以下代码使用 ODE45 模拟方程组:

在编辑器上:

function dy=modelo10(t,y)
    global omega

    dy = zeros(3,1);
    dy(1)= y(2) - y(3);
    dy(2)= -3*y(2) - 5*sin(omega*y(1));
    dy(3)= y(1)*y(2);

end

在命令选项卡上:

>>global omega;
>>omega = 3;
>>[T,Y] = ode45(@modelo10, [0,20], [0,4,1]); 
%% I assign the function to variable f
>>f = @(t) 2.*cos(y(:,1)) + y(:,2);
%% And finally plot it with the values t
>>fplot(f, [0,20]);

我得到一个带有以下错误的空白图表:

Warning: Function behaves unexpectedly on array inputs. To improve 
performance, properly
vectorize your function to return an output with the same size and 
shape as the input
arguments. 
  In matlab.graphics.function.FunctionLine>getFunction
  In matlab.graphics.function.FunctionLine/updateFunction
  In matlab.graphics.function.FunctionLine/set.Function_I
  In matlab.graphics.function.FunctionLine/set.Function
  In matlab.graphics.function.FunctionLine
  In fplot>singleFplot (line 241)
  In fplot>@(f)singleFplot(cax,{f},limits,extraOpts,args) (line 196)
  In fplot>vectorizeFplot (line 196)
  In fplot (line 166) 
Warning: Error updating FunctionLine.

The following error was reported evaluating the function in 
FunctionLine update:
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.

Warning: Error updating FunctionLine.

The following error was reported evaluating the function in 
FunctionLine update:
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false

所以我的问题是要绘制的步骤(或命令)是什么f

我正在使用 MATLAB R2019a。

4

2 回答 2

4

您的第一个问题是定义f

[T,Y] = ode45(@modelo10, [0,20], [0,4,1]); 
f = @(t) 2.*cos(y(:,1)) + y(:,2);

请注意,第一行定义了一个变量Y,但在您使用的第二行中y。这些是不同的变量。这可能对您有用,因为您y在工作区中定义了一个变量,但它做错了事。

接下来,你的fis a function f(t),但它不是使用 input 定义的t。它总是输出相同的东西。fplot期望一个函数输出与其输入大小相同的数组,这是您收到的错误消息。

但是,您不需要在这里定义函数,您可以直接计算所有值f并使用以下方法绘制它们plot

[t,y] = ode45(@modelo10, [0,20], [0,4,1]);
f = 2.*cos(y(:,1)) + y(:,2);
plot(t,f)

此外,我想建议您不要使用global. 您在这里不需要它,您可以将其定义omega为输入参数modelo10

function dy = modelo10(t,y,omega)
   dy = zeros(3,1);
   dy(1) = y(2) - y(3);
   dy(2) = -3*y(2) - 5*sin(omega*y(1));
   dy(3) = y(1)*y(2);
end

然后调用ode45如下:

[t,y] = ode45(@(t,y)modelo10(t,y,omega), [0,20], [0,4,1]);

在这里,@(t,y)modelo10(t,y,omega)定义了一个匿名函数,它带有 的值omega。这个匿名函数有两个输入参数 (ty),这是ode45.

最后,您可以通过modelo10在一行中定义来简化代码:

function dy = modelo10(t,y,omega)
   dy = [ y(2) - y(3); -3*y(2) - 5*sin(omega*y(1)); y(1)*y(2) ];
end

您现在可以执行以下操作:

modelo10 = @(t,y) [ y(2) - y(3); -3*y(2) - 5*sin(omega*y(1)); y(1)*y(2) ];
[t,y] = ode45(modelo10, [0,20], [0,4,1]);
于 2019-05-06T17:06:30.957 回答
2
global omega;
omega = 3;

[T,Y] = ode45(@modelo10, [0,20], [0,4,1]);
  • 从这里 Y 是 T 的函数 --> 不需要为 T = [0,20] 定义新函数 Y = Y(T),这不再是变量而是实数 Y = [Y1(0),.. ., Y1(20); Y2(0),..., Y2(20); Y3(0),..., Y3(20)]

  • 我将函数分配给变量 f

    f = @(t) 2.*cos(y(:,1)) + y(:,2) --> f = abs( 2.*cos(Y(:,1)) + Y(:,2));
    

    小写 y 和大写 Y 是两个不同的变量。matlab中的绝对值函数是abs

  • 最后用值 t 绘制它

    Use plot instead of fplot
    

    实际上你不需要为函数 f 指定输入值,因为它在计算 ode45 时已经包含在内,而 fplot 需要一个关键参数,即函数表达式

    (function handle --> function defined as follow f = @(x)_____). 
    

    输入可以额外添加为第二个参数。

    这是可选的;默认情况下,fplot 评估 [0 5] 范围内的函数

  • 这里 f 是实数而不是函数表达式,它已经被计算过了

        plot(T, f);
    

在此处输入图像描述 函数 f 绘制 T 范围从 0 到 20

于 2019-05-06T17:14:18.077 回答