Многомерная интеграция с quadpack приводит к рекурсивному вызову нерекурсивной процедуры dqage

Я пытаюсь численно выполнить 2D-интеграл, используя библиотеку quadpack double . Поскольку на этом веб-сайте нет встроенного движка Latex, я прилагаю картинку с математикой.

Также ниже прикрепляю свою реализацию этой операции в модуле test_module.

module test_module
  use f90_kind ! defines dp
  use physconst ! defines pi
  use global_variables ! defines the variables for quadpack
  use csv_file ! allows me to write to a csv file

  implicit none

  real(dp) :: a, b, c ! parameters I want to set

contains

  real(dp) function multi_val_func(theta)
    real(dp), intent(in) :: theta

    multi_val_func = exp(theta**2 + c*theta)

  end function multi_val_func

  real(dp) function theta_integral(phi)
    real(dp), intent(in) :: phi

    c = phi*(a+b)

    ! Quadpack variables
    epsabs = 1.0E-14_dp
    epsrel = 0.0E0_dp
    key    = 6
    ilow   = 0.0E0_dp
    ihigh  = 2.0E0_dp*pi

    call dqage(multi_val_func, ilow, ihigh, epsabs, epsrel, key, limit, &
               res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)

    theta_integral = res

  end function theta_integral

  subroutine phi_integral(final_result)
    real(dp),intent(out) :: final_result

    a = 1.0E0_dp
    b = 1.0E0_dp

    ! Quadpack variables
    epsabs = 1.0E-14_dp
    epsrel = 0.0E0_dp
    key    = 6
    ilow   = 0.0E0_dp
    ihigh  = pi

    call dqage(theta_integral, ilow, ihigh, epsabs, epsrel, key, limit, &
               res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)

    final_result = res

    print *, final_result

  end subroutine phi_integral

end module test_module

В основном файле я определяю переменную result, а затем call phi_integral(result). Я компилирую этот код, используя следующий make-файл

FFLAGS = -O0 -fcheck=all -ffree-line-length-none

debug:
    gfortran -c $(FFLAGS) $(srcdir)/f90_kind.f90
    gfortran -c $(FFLAGS) $(srcdir)/physconst.f90
    gfortran -c $(FFLAGS) $(srcdir)/global_variables.f90
    gfortran -c $(FFLAGS) $(extlib_qp)/quadpack_double.f90
    gfortran -c $(FFLAGS) $(extlib_csv)/csv_file.f90
    gfortran -c $(FFLAGS) $(srcdir)/multi_var_integration.f90
    gfortran -c $(FFLAGS) $(srcdir)/main.f90
    gfortran *.o -o debug -lblas -llapack
    rm -f *.o *.mod

Код компилируется, но когда я его запускаю, я получаю следующую ошибку:

Fortran runtime error: Recursive call to nonrecursive procedure 'dqage'

Error termination. Backtrace:
#0  0x103a28d3d
#1  0x103a299f5
#2  0x103a29fd6
#3  0x1039f94b6
#4  0x1039dee59
#5  0x1039fad68
#6  0x1039f9948
#7  0x1039dec7d
#8  0x1039def61
#9  0x1039defa3

Любое предложение по решению этой проблемы приветствуется.

Вы понимаете, что означает «Рекурсивный вызов нерекурсивной процедуры» и каковы последствия? Вероятно, вам лучше попытаться использовать квадратурную процедуру/пакет, предназначенный для двумерных интегралов.

francescalus 18.12.2020 18:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
253
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не каждая подпрограмма или функция в Фортране является реентерабельной или, как ее называет Фортран, «рекурсивной». До Fortran 2018 подпрограмма, которую можно вызвать, находясь уже внутри себя (пусть даже косвенно), должна быть отмечена атрибутом recursive.

Даже если подпрограмма помечена таким образом, она может работать не так, как ожидалось, если она содержит статические (сохраненные) данные или если она использует глобальные переменные (общие блоки, модули).

Я не могу сразу увидеть какие-либо такие статические данные, используемые в http://www.netlib.no/netlib/quadpack/dqage.f, поэтому они могут работать после добавления recursive.

Однако, как указал Франческалус, вам лучше иметь специальную библиотеку 2d-квадратур.

Интеграл theta можно выполнить с помощью функции ошибок erf. См. вольфрам альфа.

Результатом этого является функция одной переменной phi, которую можно вычислить через quadpack. Таким образом, вам не нужна многомерная интегральная процедура.

Другие вопросы по теме