问题描述
我想编写Fortran code,像R函数序列()的作品。例如:
X< - 序列(0,1,0.1)
会给矢量
X< - C(0,0.1,0.2,...,1)
我将通过仅改变在SEQ第二个参数运行几个模拟在其上序列的长度将发生变化,R中这是很容易完成的,()。我试图做这样的事情Fortran中有动态数组和功能分配给动态改变数组的大小。这至今还没有工作,导致误差
计划接收信号SIGSEGV:段错误 - 无效的内存引用。回溯跟踪此错误:
#0 0x2B371ED7C7D7
#1 0x2B371ED7CDDE
#2 0x2B371F3B8FEF
#3 0x401BE9在MAIN__在test3D.f90:?
分段错误(核心转储)
所以我想知道是否有模仿R函数序列()Fortran中的行为的简单方法。
有关进一步的参考见下文
程序 程序ffl第
隐无
整数参数:: N = 2 ** 12
整数::男,J,L,O,NUM,R,POSI
实(KIND = 8),尺寸(N)::结果
实(KIND = 8):: DT,DK,DP,DTT,laenge,基底,periode,C
实(KIND = 8),尺寸(N,N)::健身,k_opt
实(种类= 8):: T0,T1,T2,T3
实(KIND = 8),尺寸(:),可分配::Ť
实(KIND = 8),尺寸(N):: K,P,TT1
实(KIND = 8),尺寸(6):: x_new,资源,Q0
实(KIND = 8),尺寸(6):: K1,K2,K3,K4
实(KIND = 8):: TS = 0.0
实(KIND = 8):: KS = 0.0,克= 1.0
实(KIND = 8):: PS = 0.1,PE = 40.0
实(KIND = 8):: TTS = 0.0,TTE = 1.0
实(KIND = 8),尺寸(6):: U0,F1,F2,F3,U1
外部::衍生物!计算矢量
DK =(KE-KS)/实(N)!计算分辨率
DP =(PE-PS)/实(N)!计算分辨率
DTT =(TTE-TTS)/实(N)!计算分辨率
K(1)= KS!对于k第一个值= 0.0
P(1)= PS!对于p第一个值= 0.001
TT1(1)= TTS!对于TTS = 0.0第一个值NUM = 10做M = 1,N
K(M)= K(M-1)+ DK!设置分辨率DT基底前pression矢量
TT1(M)= TT1(M-1)+ DTT
做到底做M = 1,N
ρ(M)= PS + 0.1
做到底做M = 1,N
periode = P(米) 做J = 1,N
laenge = TT1(J) 做L = 1,N
基底= K(L) C = NUM * periode!计算模拟的长度
DT =(C-TS)/实(N)!计算时间分辨率
R = 1
T(1)= TS!第一时间值设定为T1 = 0 分配(T(1))!初始化数组维 做一段时间(TS + DT< c)
T(R)= TS
TS = TS + DT
R = R + 1个
调用resize_array
做到底 !初始条件
Q0(1)= 0! X
Q0(2)=基础! ÿ
Q0(3)= 0! ž
Q0(4)= 0!一个
Q0(5)= 1! b
Q0(6)= 0! W¯¯ x_new = Q0!设置初始条件
!解决在使用一个四阶龙格 - 库塔法模型
做O = 1,N
调用衍生物(基底,periode,laenge,叔(升),x_new,K1) T1 = T(O)+ DT / 2
F1 = x_new +(DT * K1)/ 2
调用衍生物(基底,periode,laenge,T1,F1,K2) T2 = T(O)+ DT / 2
F2 = x_new +(DT * K2)/ 2
调用衍生物(基底,periode,laenge,T2,F2,K3) T3 = T(O)+ DT
F3 = x_new +(DT * K3)/ 2
调用衍生物(基底,periode,laenge,T3,F3,K4) RES = x_new +(DT *(K1 + 2 * K2 + 2 * K3 + K4))/ 6
如果(RES(2)LT;基),那么
RES(2)=基础
万一 结果(N)=水库(6) 做到底
健身(J,L)= MAXVAL(结果)/ C
做到底
写(*,*)健身
!POSI = MAXLOC(健身(:,J))
!k_opt(M,J)= K(POSI)!输入该值到最佳K矩阵
做到底
做到底
!写(*,*)k_opt
!回k_opt包含!子程序增加了阵列的由1的大小
子程序resize_array
真实的,尺寸(:),可分配:: tmp_arr
整数::新新=尺寸(T)+ 1分配(tmp_arr(新))
tmp_arr(1:新的)= T
DEALLOCATE(T)分配(T(大小(tmp_arr)))
T = tmp_arr结束子程序resize_array
最终方案ffl第
Fortran 2003的分配后,可分配数组有(重新)分配,程序
程序的Xgrid
隐无
真正的,可分配:: X(:)
整数:: I,N
做N = 5,10,5
X = 0.1 * [(I,I = 0,n)的]
写(*,('X =',100(1X,F0.1)))x
做到底
最终方案的Xgrid
与gfortran 4.8.0编译
,显示一个Fortran单行相当于SEQ(),使输出
X = 0.0 .1 .2 .3 .4 0.5
X = 0.0 .1 .2 .3 .4 0.5 0.6 0.7 0.8 0.9 1.0
I would like to write Fortran code that works like the R function seq(). E.g.:
x <- seq(0,1,0.1)
will give the vector
x <- c(0, 0.1, 0.2, ..., 1)
I will run several simulations over which the length of the sequence will change, in R this is easily done, by just varying the second argument in seq(). I have tried to do something like this in Fortran with dynamical arrays and the function ALLOCATE to dynamically change the size of the array. This has not worked so far and lead to the error
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x2B371ED7C7D7
#1 0x2B371ED7CDDE
#2 0x2B371F3B8FEF
#3 0x401BE9 in MAIN__ at test3D.f90:?
Segmentation fault (core dumped)
so I was wondering whether there is an easy way to mimic the behaviour of the R function seq() in Fortran.
For further reference see the program below
program ffl
implicit none
integer, parameter :: n = 2**12
integer :: m,j,l,o,num,r,posi
real(kind=8), dimension(n) :: results
real(kind=8) :: dt,dk,dp, dtt, laenge, basal, periode,c
real(kind=8), dimension(n,n) :: fitness, k_opt
real(kind=8) :: t0,t1,t2,t3
real(kind=8), dimension(:),allocatable :: t
real(kind=8), dimension(n) :: k,p, tt1
real(kind=8), dimension(6) :: x_new, res, q0
real(kind=8), dimension(6) :: k1,k2,k3,k4
real(kind=8) :: ts = 0.0
real(kind=8) :: ks = 0.0, ke = 1.0
real(kind=8) :: ps = 0.1, pe = 40.0
real(kind=8) :: tts = 0.0, tte = 1.0
real(kind=8), dimension(6) :: u0,f1,f2,f3,u1
external :: derivate
! computing the vectors
dk=(ke-ks)/real(n) ! calculating resolution
dp=(pe-ps)/real(n) ! calculating resolution
dtt=(tte-tts)/real(n) ! calculating resolution
k(1) = ks ! first value for k = 0.0
p(1) = ps ! first value for p = 0.001
tt1(1) = tts ! first value for tts = 0.0
num = 10
do m = 1,n
k(m) = k(m-1)+dk ! setting the basal expression vector with resolution dt
tt1(m) = tt1(m-1)+dtt
end do
do m = 1,n
p(m) = ps + 0.1
end do
do m = 1,n
periode = p(m)
do j = 1,n
laenge = tt1(j)
do l = 1,n
basal = k(l)
c = num * periode ! calculating the length of the simulation
dt=(c-ts)/real(n) ! calculating time resolution
r = 1
t(1) = ts ! setting first time value to t1 = 0
allocate(t(1)) ! Initialize array dimension
do while (ts + dt < c)
t(r) = ts
ts = ts + dt
r = r + 1
call resize_array
end do
! initial conditions
q0(1) = 0 ! x
q0(2) = basal ! y
q0(3) = 0 ! z
q0(4) = 0 ! a
q0(5) = 1 ! b
q0(6) = 0 ! w
x_new = q0 ! set initial conditions
! Solving the model using a 4th order Runge-Kutta method
do o = 1,n
call derivate(basal,periode,laenge,t(l),x_new,k1)
t1 = t(o) + dt/2
f1 = x_new + (dt*k1)/2
call derivate(basal,periode,laenge,t1,f1,k2)
t2 = t(o) + dt/2
f2 = x_new + (dt*k2)/2
call derivate(basal,periode,laenge,t2,f2,k3)
t3 = t(o) + dt
f3 = x_new + (dt*k3)/2
call derivate(basal,periode,laenge,t3,f3,k4)
res = x_new + (dt*(k1+2*k2+2*k3+k4))/6
if (res(2) < basal) then
res(2) = basal
endif
results(n) = res(6)
end do
fitness(j,l) = maxval(results)/c
end do
write(*,*) fitness
!posi = maxloc(fitness(:,j))
!k_opt(m,j) = k(posi) ! inputting that value into the optimal k matrix
end do
end do
!write(*,*) k_opt
!return k_opt
contains
! The subroutine increases the size of the array by 1
subroutine resize_array
real,dimension(:),allocatable :: tmp_arr
integer :: new
new = size(t) + 1
allocate(tmp_arr(new))
tmp_arr(1:new)=t
deallocate(t)
allocate(t(size(tmp_arr)))
t=tmp_arr
end subroutine resize_array
end program ffl
Fortran 2003 has (re-)allocation upon assignment for allocatable arrays, and the program
program xgrid
implicit none
real, allocatable :: x(:)
integer :: i,n
do n=5,10,5
x = 0.1*[(i,i=0,n)]
write (*,"('x =',100(1x,f0.1))") x
end do
end program xgrid
compiled with gfortran 4.8.0, shows a Fortran one-liner equivalent to seq(), giving output
x = .0 .1 .2 .3 .4 .5
x = .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1.0
这篇关于Fortran的数组动态大小,容易R函数序列()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!