Translate Matlab code to Julia code

I am trying to translate my Matlab code to Julia code, so I can use Julia as my main tool in teaching. I ran into an issue that I could not solve.

Below is my Matlab code:

clear all
m = 0; % mean
sd= 1; %std deviation

charfunc = @(v) exp(1i*m*v-0.5.*(sd^2).*(v.^2));
M=1/(2*pi);
X=3;
a=-100;
b=100;
func2 = @(v) exp(-1i.*v*X).*charfunc(v);

res1 = M*real(quad(func2,a,b))
res2 = normpdf(X,m,sd)

Below is my Julia code:

using QuantEcon, Distributions
m = 0 #mean
sd = 1 #standard deviation


function charfunc(v)
    exp(im*m*v-0.5.*(sd^2).*(v.^2))
end

M = 1/(2*pi)
X = 3
a = -100
b = 100

function func2(v)
    exp(-im.*v*X).*charfunc(v)
end

nodes, weights = qnwlege(65, a, b)

integral = do_quad(func2, nodes, weights) #integration between a and b

res1 = real(integral)*M

d = Normal(0,1)

res2 = pdf(d, X)

I expect res1 to be equal to res2. In my Julia code, I could not get the correct answer, but I am not sure where the bug is.

Not sure what the qnwlege and do_quad function are, but using the basic quadrature function in base (quadgk, which returns a tuple of the result and the error), I do get similar values. Do you need lower error bounds?

julia> res1 = real(quadgk(func2, a, b)[1])*M
0.004431848411938444

julia> res2 = pdf(d, X)
0.0044318484119380075

Thanks so much. I did not know that the basic quadrature function is available in Julia.

Note also that you don’t need the .* in your integrand. Unlike in Matlab, the integrand is called on scalar arguments—it doesn’t need to be vectorized for performance.

(What will hurt performance in Julia is your use of a global variable in the integrand.)

2 Likes

Rewritten to remove global variables:

using QuadGK, Distributions

charfunc(v, μ, σ) = exp(1im * μ * v - 0.5σ^2 * v^2)
func2(v, μ, σ, X) = exp(-1im * v * X)*charfunc(v, μ, σ)
mypdf(μ, σ, X) = real(quadgk(v -> func2(v, μ, σ, X), -Inf, Inf)[1])/2pi

pdf(Normal(0,1), 3) ≈ mypdf(0, 1, 3)

(note that quadgk can use indefinite limits)

2 Likes