How can I use funtions defined in a column vector individually?

4 ビュー (過去 30 日間)
Divyaprakash
Divyaprakash 2021 年 7 月 10 日
コメント済み: Divyaprakash 2021 年 7 月 15 日
I am looking to solve a problem using ode45 and Runge-Kutta method. For ode45 I hav defined the function as follows.
odefun = @(x,T) [T(2); -a*(Ta-T(1))];
I want to use each of the individual function defined in each row in my Runge-Kutta function. Can I extract them from the odefun above or do I need to define them separately again as two anonymous function?
  2 件のコメント
Divyaprakash
Divyaprakash 2021 年 7 月 11 日
The RK function that I have written takes only one function at a time. If I have two simultanneous firt order ODE, then I define them with two anonymous functions. What I want to do is use the same format of odefun as used in ode45, in my RK4 code as well. But I am unable to figure out how that's done. I went through ode45 implementation in MATLAB, however I am unable to figure it out. Please help me understand how the ode45 routine acceses the rows of odefun individually. My code for RK4 is given below.
Edit: I had posted a different code below. I have changed it.
function [t,y] = RK4(fun,t0,tN,h,y0)
% RK4: Solves IVP using using Runge-Kutta Method
% [t,y] = RK4(fun,t0,tN,h,y0):
% Solves the given IVP using Runge-Kutta fourth order method
% https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
%
% input:
% fun = An anonymous function describing y'(t) = f(t,y)
% t0 = Initial value of t
% y0 = Intial value of y at t0
% tN = Final value of y
% h = Step size
% output:
% t = Values of t
% y = Values of y calculated at all t
%
% Author: Divyaprakash
t = t0:h:tN;
nt = numel(t);
y = zeros(1,nt);
y(1) = y0;
for i = 1:nt-1
k1 = fun(t(i),y(i));
k2 = fun(t(i)+h/2, y(i)+h*k1/2);
k3 = fun(t(i)+h/2, y(i)+h*k2/2);
k4 = fun(t(i)+h,y(i)+h*k3);
y(i+1) = y(i) + 1/6*h*(k1 + 2*k2 + 2*k3 + k4);
end
end

サインインしてコメントする。

採用された回答

Jan
Jan 2021 年 7 月 11 日
A small modification of your code let accept RK4 vector functions also:
function [t, y] = RK4(fun, t0, tN, h, y0)
t = t0:h:tN;
nt = numel(t);
y = zeros(numel(y0), nt);
y(:, 1) = y0;
for i = 1:nt-1
k1 = fun(t(i), y(:, i));
k2 = fun(t(i)+h/2, y(:, i) + h*k1/2);
k3 = fun(t(i)+h/2, y(:, i) + h*k2/2);
k4 = fun(t(i)+h, y(:, i) + h*k3);
y(:, i+1) = y(:, i) + h * (k1 + 2*k2 + 2*k3 + k4) / 6;
end
  4 件のコメント
Divyaprakash
Divyaprakash 2021 年 7 月 15 日
Thanks. I was unaware of these license requirements.

サインインしてコメントする。

その他の回答 (1 件)

Steven Lord
Steven Lord 2021 年 7 月 11 日
Please help me understand how the ode45 routine acceses the rows of odefun individually.
It doesn't, not the way I think you mean it.
odefun = @(x,T) [T(2); -a*(Ta-T(1))];
This is not two "individual function[sic] defined in each row in my Runge-Kutta function". This is one anonymous function that accepts two inputs, x and T (which must have at least two elements) and returns a vector as its output. That vector has at least two elements assuming neither a nor Ta were empty, but still just one function.
You could call your odefun with two inputs and then index into the vector that odefun returns, but that does not make odefun two functions in any way, shape, or form.
f = @(x, y) [sind(x); cosd(y)];
z = f(45, 135)
z = 2×1
0.7071 -0.7071
z(2) - cosd(135)
ans = 0
Because of the way f is constructed and called, z(2) is cosd(135).
  1 件のコメント
Divyaprakash
Divyaprakash 2021 年 7 月 11 日
Okay. So if I want to use the same formulation of odefun as in ode45 in my RK code, then I should just index into the corresponding output as in the code below? Do you recommend some better way or is this fine?
I am using N to index into the output in the code below.
for i = 1:nt-1
k1 = fun(t(i),y(i));
k2 = fun(t(i)+h/2, y(i)+h*k1(N)/2);
k3 = fun(t(i)+h/2, y(i)+h*k2(N)/2);
k4 = fun(t(i)+h,y(i)+h*k3(N));
y(i+1) = y(i) + 1/6*h*(k1(N) + 2*k2(N) + 2*k3(N) + k4(N));
end

サインインしてコメントする。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by