#julia
#Юлия
Вопрос:
Вот мой код:
using Plots
using SpecialFunctions
using QuadGK
kappa = 1
B = 1
xi = (kappa/B)^4
function correlation(x)
quadgk(q -> q * SpecialFunctions.besselj0(x*q)/(q^4 xi), 0, 1e6)[1]/kappa
end
r = range(-20, 20, length = 1001)
plot(r, correlation(r))
Я получаю сообщение об ошибке в функции Бесселя. Я понимаю, что аргумент является проблемой и что он должен иметь формат ::BigFloat
, ::Float16
, или ::Float32
, но я не знаю, как это сделать. Я попытался написать x .* q
вместо этого, но проблема остается той же, я получаю ошибку:
ERROR: MethodError: no method matching besselj0(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}})
Кроме того, я ищу способ написать infinity вместо 1e6
.
Комментарии:
1. Ответ на второй вопрос, вероятно
Inf
, <strike> , но я не знаю, принимает ли QuadGK это как границу интеграции.</strike> Похоже, это так .
Ответ №1:
Просто замените correlation(r)
на correlation.(r)
в вашем коде, чтобы использовать широковещательную передачу, как объясняется здесь .
Суть вашей проблемы в том, что функции Julia по умолчанию недоступны для трансляции — обычно для этого нужно зарегистрироваться (особенно когда вы работаете с числовым кодом). Вот базовый пример:
julia> sin(1)
0.8414709848078965
julia> sin([1])
ERROR: MethodError: no method matching sin(::Array{Int64,1})
Closest candidates are:
sin(::BigFloat) at mpfr.jl:727
sin(::Missing) at math.jl:1197
sin(::Complex{Float16}) at math.jl:1145
...
Stacktrace:
[1] top-level scope at REPL[2]:1
julia> sin.([1])
1-element Array{Float64,1}:
0.8414709848078965
Однако в вашем случае correlation
функция довольно дорогая. В таком случае я обычно использую ProgressMeter.jl для отслеживания хода вычислений (он показывает, сколько времени вы можете ожидать завершения вычислений). Так что вы можете написать:
using ProgressMeter
result = @showprogress map(correlation, r)
и используйте map
функцию, чтобы применить correlation
функцию ко всем элементам r
(в этом случае результат будет таким же, как для трансляции).
Наконец, ваши вычисления будут намного быстрее, если вы не будете использовать глобальные переменные в quadgk
. Лучше передавать kappa
and xi
в качестве аргументов функции вот так:
function correlation(x, kappa, xi)
quadgk(q -> q * SpecialFunctions.besselj0(x*q)/(q^4 xi), 0, 1e6)[1]/kappa
end
result = @showprogress map(x -> correlation(x, kappa, xi), r)