Я пытаюсь вызвать модуль, написанный на Fortran в R studio, но последний неожиданно вылетает.
Я пробовал с другими примерами на Фортране (факториальная и MC оценка числа пи), и они сработали хорошо.
Единственное различие, которое я вижу между моим кодом, который не работает, и этими примерами в том, что я использовал оболочку подпрограммы для своей чистой функции (вызывая другую чистую функцию), тогда как эти примеры опирались только на подпрограммы, и тот факт, что моя функция имеет вектор в качестве входных данных.
Вот процедура, которую я выполнил (или набрал код):
R CMD SHLIB mypath/myfile.f90 #this compiles without problem; code supplied below.
dyn.load('ptoh') #This is just the given name of the wrapper subroutine
.Fortran('ptoh', dimen=as.integer(dimen), p=as.matrix(p), m=as.integer(m), h=integer(1) )
где я произвольно установил в R: dimen<-3; p<-c(4,6,7); m=3;
Ты хоть представляешь, почему он падает? Правильный ли способ создания моей обертки? Это проблема, связанная с bind(C, name="ptoh_")
?
Я уже очень благодарю вас за вашу помощь.
Жиль
Я работаю на Mac под управлением HighSierra с последней версией R.
Код в 'myfile.90' следующий:
module hilbert
implicit none
contains
pure function rotate_right(x, d, dimen)
integer, intent(in) :: x, d, dimen
integer :: rotate_right, tmp, mask
mask = 2 ** dimen - 1
rotate_right = shiftr(x, d)
tmp = shiftl(x, dimen - d)
rotate_right = iand(ior(rotate_right, tmp), mask)
end
pure function rotate_left(x, d, dimen)
integer, intent(in) :: x, d, dimen
integer :: rotate_left, tmp, mask
mask = 2 ** dimen - 1
rotate_left = shiftl(x, d)
tmp = shiftr(x, dimen - d)
rotate_left = iand(ior(rotate_left, tmp), mask)
end
pure function gc(i)
integer, intent(in) :: i
integer :: gc
gc = ieor(i, shiftr(i, 1))
end
pure function entry_point(i)
integer, intent(in) :: i
integer :: entry_point
if(i == 0) then
entry_point = 0
else
entry_point = gc(2 * ((i - 1) / 2))
end if
end
pure function exit_point(i, dimen)
integer, intent(in) :: i, dimen
integer :: exit_point, mask
mask = 2 ** dimen - 1
exit_point = ieor(entry_point(mask - i), 2 ** (dimen - 1))
end
pure function inverse_gc(g, dimen)
integer, intent(in) :: g, dimen
integer :: inverse_gc, j
inverse_gc = g
j = 1
do while(j < dimen)
inverse_gc = ieor(inverse_gc, shiftr(g, j))
j = j + 1
end do
end
pure function intercube_g(i) result(g)
integer, intent(in) :: i
integer :: g
g = trailz(ieor(gc(i), gc(i + 1)))
end
pure function intracube_d(i, dimen) result(d)
integer, intent(in) :: i, dimen
integer :: d
if(i == 0) then
d = 0
else if(modulo(i, 2) == 0) then
d = modulo(intercube_g(i - 1), dimen)
else
d = modulo(intercube_g(i), dimen)
end if
end
pure function transform(e, d, b, dimen) result(t)
integer, intent(in) :: e, d, b, dimen
integer :: t
t = rotate_right(ieor(b, e), d + 1, dimen)
end
pure function inverse_transform(e, d, b, dimen) result(t)
integer, intent(in) :: e, d, b, dimen
integer :: t
t = transform(rotate_right(e, d + 1, dimen), dimen - d - 2, b, dimen)
end
pure function ptoh(dimen, p, m) result(h)
integer, intent(in) :: dimen, p(dimen), m
integer :: h, e, d, i, j, l, w
h = 0
e = 0
d = 2
do i = m - 1, 0, -1
l = 0
do j = 1, dimen
l = l + 2 ** (j - 1) * ibits(p(j), i, 1)
end do
l = transform(e, d, l, dimen)
w = inverse_gc(l, dimen)
e = ieor(e, rotate_left(entry_point(w), d + 1, dimen))
d = modulo(d + intracube_d(w, dimen) + 1, dimen)
h = ior(shiftl(h, dimen), w)
end do
end
subroutine ptoh_R_wrapper(dimen, p, m, h) bind(C, name="ptoh_")
integer :: dimen, p(dimen), m, h, ptoh
external ptoh
h = ptoh(dimen, p, m)
end
end