2017-11-18 138 views
2

我是Octave的新手,所以我想在创建更复杂的项目之前做一些简单的示例工作。未能用Octave解决简单的ODE

我想解决ODE dy/dx = a*x+b,但没有成功。下面是代码:

%Funzione retta y = a*x + b. Ingressi: vettore valori t; coefficienti a,b 
clear all; 
%Inizializza argomenti 
b = 1; 
a = 1; 
x = ones(1,20); 
function y = retta(a, x, b) %Definisce funzione 
y = ones(1,20); 
y = a .* x .+ b; 
endfunction 
%Calcola retta 
x = [-10:10]; 
a = 2; 
b = 2; 
r = retta(a, x, b) 
c = b; 
p1 = (a/2)*x.^2+b.*x+c %Sol. analitica di dy/dx = retta % 
plot(x, r, x, p1); 
% Risolve eq. differenziale dy/dx = retta % 
y0 = b; x0 = 0; 
p2 = lsode(@retta, y0, x) 

,输出是:

retta3code 
r = 

-18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 

p1 = 

Columns 1 through 18: 

82 65 50 37 26 17 10  5  2  1  2  5 10 17 26 37 50 65 

Columns 19 through 21: 

82 101 122 

error: 'b' undefined near line 9 column 16 
error: called from: 
error: retta at line 9, column 4 
error: lsode: evaluation of user-supplied function failed 
error: lsode: inconsistent sizes for state and derivative vectors 
error: /home/fabio/octave_file/retta3code.m at line 21, column 4 

所以,retta正常工作的第一次,但在lsode使用时出现故障的功能。 这是为什么发生?需要改变什么才能使代码正常工作?

+0

从手册lsode: “FCN的第一个参数是一个字符串,内联或函数句柄,它们命名函数f来调用以计算方程组右侧的向量,该函数的格式必须为XDOT = f(X, T)'其中XDOT和X是矢量,T是标量。“这对你的“retta”功能是否正确? – Andy

+0

在我的情况下,它应该是ydot = f(y,x,a,b)。我必须测试它。 –

回答

3

不知何故,你仍然想念故事的一些重要部分。为了解决一个ODE y'=f(y,x)需要定义一个函数

function ydot = f(y,x) 

其中ydot具有相同的尺寸y,都需要成为载体,甚至˚F它们是尺寸1的x是一个标量。由于某些传统原因,lsode(用于多个求解器包中的FORTRAN代码)倾向于使用次数较少的订单(y,x),在大多数教科书和其他求解器中,您会发现订单(x,y)

然后得到溶液样品ylist在采样点xlist你叫

ylist = lsode("f", y0, xlist) 

其中xlist(1)是初始时间。

f的内部独立于样本列表list和它的大小。它是一个独立的问题,您可以使用多元评价来计算的东西精确解像

yexact = solexact(xlist) 

pass parameters,使用anonymous functions,像

function ydot = f(y,x,a,b) 
    ydot = [ a*x+b ] 
end 

a_val = ... 
b_val = ... 
lsode(@(y,x) f(y,x,a_val, b_val), y0, xlist) 
+0

在提出问题之前,我确定矢量长度相同。我对Octave很陌生,但并不那么绿。如果参数'a'和'b'被分配了一个超出函数值的值,'rdot'将不会被评估。 –

+0

评估'rdot'时不应该有任何媒介。无论是'x'还是'y'还是'ydot'。只有界面迫使你将标量换成维度1的向量。 – LutzL

+0

无论如何,谢谢你,有关将参数传递给'lsode'的部分正是我所追求的。 –

0

下面修改的代码有效,但我希望能够定义参数ab以外的函数,然后将它们作为参数传递给rdot

x = [-10,10]; 
a = 1; 
b = 0; 
c = b; 
p1 = (a/2).*(x.^2)+b.*x+c %Sol. analitica di dy/dx = retta % 
function ydot = rdot(ydot, x) 
a = 1; 
b = 0; 
ydot = ones(1,21); 
ydot = a.*x .+ b; 
endfunction 
y0 = p1(1); x0 = 0; 
p2 = lsode("rdot", y0, x, x0)' 
plot(x, p1, "-k", x, p2, ".r");