Функция вызова - PullRequest
       11

Функция вызова

1 голос
/ 18 февраля 2012

Я не знаю, правильная ли эта комната, чтобы задавать этот вопрос? Если нет, то прошу прощения за это. Я новый пользователь на Фортране и трачу много времени на следующие вещи.

Я построил функцию под названием «loglike», которая возвращает действительное число в зависимости от двух параметров. Я хочу использовать эту функцию для построения алгоритма mcmc

, который выглядит следующим образом.

psi = min(0, loglike(propalpha,propbeta) - loglike(currentalpha,currentbeta))

, где propalpha = currentalpha + noise и propbeta = currentbeta + noise, шумы - это случайные выборки из некоторого распределения.

Теперь я хочу использовать этот алгоритм, вызывая ранее созданную функцию «loglike».

1) как я могу вызвать функцию 'loglike' для новой программы, называемой основной программой
2) как я могу использовать это для подпрограммы?

Любая помощь очень полезна для меня. Заранее спасибо

РЕДАКТИРОВАТЬ:

module mcmc

implicit none

contains

    subroutine subru(A,B, alphaprop, betaprop)
        real, intent(in)::A,B
        real, intent(out)::alphaprop, betaprop
    end subroutine subru

    real function aloglike(A,B)
        real:: A,B,U, aloglike
        aloglike = U
    end function aloglike

end module mcmc


program  likelihood
    use mcmc

    implicit none

    real :: alpha,beta,dist1,dist2,prob1,prob2
    real:: psi,a(1000),b(1000), u1, u2,u, alphaprop, betaprop
    real, dimension(1:1):: loglike
    integer :: t,i,j,k,l
    real, dimension(1:625):: x
    real, dimension(1:625):: y
    integer, dimension(1:625):: inftime

    alpha = 0.5
    beta = 2.0

    open(10, file = 'epidemic.txt', form = 'formatted')
    do l = 1,625
       read(10,*,end = 200) x(l), y(l), inftime(l)
    enddo
200 continue

    loglike = 0.0
    do t=1,10
        do i=1,625
            if(inftime(i)==0 .or. t < (inftime(i)-1)) then
                dist1 = 0.0
                do  j = 1, 625
                    if(t >= inftime(j) .and. inftime(j)/=0)then
                        dist1 = dist1 + sqrt((x(i) - x(j))**2 + (y(i) - y(j))**2)**(-beta)
                    endif
                enddo
                prob1 = 1 - exp(-alpha * dist1)
                loglike = loglike + log(1 - prob1)
            endif

            if(inftime(i) .eq. (t+1)) then
                dist2 = 0.0
                    do k=1, 625
                    if(t >= inftime(k) .and. inftime(k)/=0) then
                        dist2 = dist2 + sqrt((x(i) - x(k))**2 + (y(i) - y(k))**2)**(-beta)
                    endif
                enddo
                prob2 = 1 - exp(-alpha * dist2)
                loglike = loglike + log(prob2)
            endif
        enddo
    enddo

    do i = 2, 1000
        a(1)= 0.0
        b(1) = 0.0
        call subru(a(i),b(i), alphaprop, betaprop)
        call random_number(u1)
        call random_number(u2)

        alphaprop = a(i-1) + (u1*0.4)-0.2
        betaprop= b(i-1) + (u2*0.4)-0.2

        if(alphaprop> 0 .and. alphaprop < 0.2 .and. betaprop > 0 .and. betaprop < 0.2)then
            psi = min(0.0,aloglike(alphaprop,betaprop)- aloglike(a(i-1),b(i-1)))
            call random_number(u)

            if(u < psi)then
                a(i)= alphaprop
                b(i) = betaprop
            else
                a(i) = a(i-1)
                b(i) = b(i-1)
            endif
        endif
    enddo

    do j = 1, 1000
        print *, A(j), A(j), LOGLIKE
    enddo

end program

Ответы [ 2 ]

4 голосов
/ 18 февраля 2012

Самый простой и надежный метод - это поместить ваши функции и подпрограммы в модуль и «использовать» этот модуль из вашей основной программы.Это можно сделать одним файлом.Этот метод делает интерфейсы процедур (функций и подпрограмм) известными, чтобы компилятор мог проверять согласованность между аргументами в вызове (фактические аргументы) и вызываемом (фиктивные аргументы).Эскиз:

module mysubs

implicit none

contains

subroutine sub1 (xyz)
   declarations
   code
end subroutine sub1

function func2 (u)
   declarations
   code
   func2 = ...
end func2

end module mysubs

program myprog

use mysubs

implicit none

declarations...

call sub1 (xyz)

q = func2 (z)

end program myprog

ДОБАВЛЕНО: «неявное нет» используется для отключения неявной типизации, что, на мой взгляд, опасно.Поэтому вам нужно будет ввести все свои переменные, включая имя функции в функции.Вы можете вызывать подпрограммы и функции из других процедур модуля - они будут автоматически известны.Так что вы можете использовать "func2" из "sub1", если хотите.Для сущностей вне модуля, таких как ваша основная программа, вы должны «использовать» модуль.

2 голосов
/ 18 февраля 2012

Это общий способ, которым это будет выглядеть. Обратите внимание, что функции возвращают значение, присваивая результат его собственному имени. return оператор не требуется.

C "loglike" is renamed "aloglike" so implicit typing uses REAL
C A type declaration could be used instead

    function aloglike (alpha, beta)
        aloglike = ... (expression which computes value)
    end

    program whateveryouwanttocallit
       ...
       propalpha = ...
       propbeta = ...
       currentalpha = ...
       currentbeta = ...
       ...
       psi = min(0, aloglike(propalpha,propbeta) - aloglike(currentalpha,currentbeta))
       print *, 'psi = ', psi

    end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...