I have a simple system of 1st-order differential equations to be solved in Matlab. It looks like the following:
我有一个简单的一阶微分方程系统需要在Matlab中求解。如下图所示:
function passing
y0 = [0; 0];
t = 0:0.05:1;
y = myprocedure(@myfunc,0.05,t,y0);
myans = y'
end
function f = myfunc(t,y)
f = [-y(1) + y(2);
-0.8*t + y(2)];
end
function y=myprocedure(f,h,t,y0)
n = length(t);
y = zeros(length(y0),n);
y(:,1) = y0;
for i=1:n-1
k1 = f(t(i),y(:,i));
k2 = f(t(i)+h/2, y(:,i)+h/2*k1);
k3 = f(t(i)+h/2, y(:,i)+h/2*k2);
k4 = f(t(i)+h, y(:,i)+h*k3);
y(:,i+1) = y(:,i)+h/6*(k1+2*k2+2*k3+k4);
end
end
So, after running the passing.m file, I have the result:
所以,在跑过终点之后。m文件,我有结果:
>> passing
myans =
0 0
-0.0000 -0.0010
-0.0001 -0.0041
-0.0005 -0.0095
-0.0011 -0.0171
-0.0021 -0.0272
-0.0036 -0.0399
-0.0058 -0.0553
-0.0086 -0.0735
-0.0123 -0.0946
-0.0169 -0.1190
-0.0225 -0.1466
-0.0293 -0.1777
-0.0374 -0.2124
-0.0469 -0.2510
-0.0579 -0.2936
-0.0705 -0.3404
-0.0849 -0.3917
-0.1012 -0.4477
-0.1196 -0.5086
-0.1402 -0.5746
Now, I am trying converting the passing.m code to Fortran 90. I did try lots of things, but I am still lost -- particularly in doing array initializations and passing functions to other functions.
现在,我试着把它转换过来。m到Fortran 90的代码。我确实尝试了很多东西,但还是失败了——特别是在做数组初始化和将函数传递给其他函数时。
Any help is appreciated. Thanks!
任何帮助都是感激。谢谢!
== EDIT:
= =编辑:
I succeeded replicating the above Matlab code in Fortran 90. I still don't know how to construct pointers, but the "interface" statement seems to work. I would appreciate it if you look at the code and provide some input. Thanks.
我在Fortran 90中成功复制了上面的Matlab代码。我仍然不知道如何构造指针,但是“接口”语句似乎可以工作。如果您能看一下代码并提供一些输入,我将不胜感激。谢谢。
module odemodule
implicit none
contains
function odef(a,b)
implicit none
real::a
real::b(2)
real::odef(2)
odef(1) = -b(1) + b(2)
odef(2) = -0.8*a + b(2)
end function odef
subroutine rk4(f,h,t,y0,y)
implicit none
real,dimension(2,21)::y
real,dimension(2)::k1,k2,k3,k4
real::h
real::t(21)
real::y0(2)
integer::i
interface
function f(a,b)
real::a
real::b(2), f(2)
end function f
end interface
y(1,1)=y0(1)
y(2,1)=y0(2)
do i=1,20
k1 = f(t(i),y(:,i))
k2 = f(t(i)+h/2, y(:,i)+h/2*k1)
k3 = f(t(i)+h/2, y(:,i)+h/2*k2)
k4 = f(t(i)+h, y(:,i)+h*k3)
y(:,i+1) = y(:,i)+h/6*(k1+2*k2+2*k3+k4)
end do
end subroutine rk4
end module odemodule
program passing
use odemodule
implicit none
real,parameter::dt=0.05
real::yinit(2)
real::y(2,21)
integer::i
real::t(21)
t(1)=0.0
do i=2,21
t(i)=t(i-1)+dt
end do
yinit(1)=0
yinit(2)=0
call rk4(odef,dt,t,yinit,y)
do i=1,21
write(*,100) y(1,i), y(2,i)
enddo
100 format(f7.4,3x,f7.4)
end program passing
1 个解决方案
#1
4
The best way in Fortran to select functions to pass to other procedures (subroutine or functions) is to use procedure pointers. That way you can write the procedure in a general manner and invoke it with a specific function. Here are some examples: How to alias a function name in Fortran and Function pointer arrays in Fortran
Fortran中选择要传递给其他过程(子程序或函数)的函数的最佳方法是使用过程指针。这样,您就可以以通用的方式编写过程,并使用特定的函数调用它。这里有一些例子:如何在Fortran中别名函数名,在Fortran中别名函数指针数组
There are many ways to initialize arrrays. For example, you can initialize all elements to the same value, e.g.,
初始化arrray的方法有很多。例如,您可以将所有元素初始化为相同的值,例如,
array = 0.0
See http://en.wikipedia.org/wiki/Fortran_95_language_features
参见http://en.wikipedia.org/wiki/Fortran_95_language_features
#1
4
The best way in Fortran to select functions to pass to other procedures (subroutine or functions) is to use procedure pointers. That way you can write the procedure in a general manner and invoke it with a specific function. Here are some examples: How to alias a function name in Fortran and Function pointer arrays in Fortran
Fortran中选择要传递给其他过程(子程序或函数)的函数的最佳方法是使用过程指针。这样,您就可以以通用的方式编写过程,并使用特定的函数调用它。这里有一些例子:如何在Fortran中别名函数名,在Fortran中别名函数指针数组
There are many ways to initialize arrrays. For example, you can initialize all elements to the same value, e.g.,
初始化arrray的方法有很多。例如,您可以将所有元素初始化为相同的值,例如,
array = 0.0
See http://en.wikipedia.org/wiki/Fortran_95_language_features
参见http://en.wikipedia.org/wiki/Fortran_95_language_features