Dear users of the language julia. I have a problem when using the optimize function of the Optim package. What is the error of the code below?
using Optim
using Distributions
rng = MersenneTwister(1234);
d = Weibull(1,1)
x = rand(d,1000)
function pdf_weibull(x, lambda, k)
k/lambda * (x/lambda).^(k-1) * exp((-x/lambda)^k)
end
function obj(x::Vector, lambda, k)
soma = 0
for i in x
soma = soma + log(pdf_weibull(i,lambda,k))
end
-soma
end
obj(x, pars) = obj(x, pars...)
optimize(vars -> obj(x, vars...), [1.0,1.0])
Output
julia> optimize(vars -> obj(x, vars...), [1.0,1.0])
ERROR: DomainError:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.
Stacktrace:
[1] nan_dom_err at ./math.jl:300 [inlined]
[2] ^ at ./math.jl:699 [inlined]
[3] (::##2#4)(::Float64, ::Float64, ::Float64) at ./<missing>:0
[4] pdf_weibull(::Float64, ::Float64, ::Float64) at ./REPL[6]:2
[5] obj(::Array{Float64,1}, ::Float64, ::Float64) at ./REPL[7]:4
[6] (::##5#6)(::Array{Float64,1}) at ./REPL[11]:1
[7] value(::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Array{Float64,1}) at /home/pedro/.julia/v0.6/NLSolversBase/src/interface.jl:19
[8] initial_state(::Optim.NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}, ::Optim.Options{Float64,Void}, ::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Array{Float64,1}) at /home/pedro/.julia/v0.6/Optim/src/multivariate/solvers/zeroth_order/nelder_mead.jl:139
[9] optimize(::NLSolversBase.NonDifferentiable{Float64,Array{Float64,1},Val{false}}, ::Array{Float64,1}, ::Optim.NelderMead{Optim.AffineSimplexer,Optim.AdaptiveParameters}, ::Optim.Options{Float64,Void}) at /home/pedro/.julia/v0.6/Optim/src/multivariate/optimize/optimize.jl:25
[10] #optimize#151(::Array{Any,1}, ::Function, ::Tuple{##5#6}, ::Array{Float64,1}) at /home/pedro/.julia/v0.6/Optim/src/multivariate/optimize/interface.jl:62
[11] #optimize#148(::Array{Any,1}, ::Function, ::Function, ::Array{Float64,1}) at /home/pedro/.julia/v0.6/Optim/src/multivariate/optimize/interface.jl:52
[12] optimize(::Function, ::Array{Float64,1}) at /home/pedro/.julia/v0.6/Optim/src/multivariate/optimize/interface.jl:52
[13] macro expansion at ./REPL.jl:97 [inlined]
[14] (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:73
It is a simple problem to obtain the maximum likelihood estimates of the parameters that index the weibull distribution.
Best regards.
The reason of your problem is that your definition of pdf_weibull is incorrect. Here is a corrected definition:
function pdf_weibull(x, lambda, k)
k/lambda * (x/lambda)^(k-1) * exp(-(x/lambda)^k)
end
Note that I have moved - sign in exp part of the expression. If you change this all will work as expected.
Now - why does Julia complain with DomainError. The reason is that because of the error in your code you try to calculate the value of something like (-1.0)^0.5. In Julia ^ is implemented in type stable way. This means, in particular, that when it is passed Float64 as both arguments it guarantees to return Float64 or throw an error. Clearly (-1.0)^0.5 cannot be computed in real domain - that is why an error is thrown. If you passed (-1+0im)^0.5 then there would be no error as we are passing a complex number to ^ so the result can also be complex number in a type stable way.
Related
I'm trying to apply automatic differentiation (ForwardDiff) to a function that contains an instance of find_zero (Roots) and am encountering an error that seems to relate to find_zero not accepting the ForwardDiff.Dual type.
Here's a (contrived) minimal working example that illustrates the issue:
using Distributions
using Roots
using StatsFuns
using ForwardDiff
function test_fun(θ::AbstractVector{T}) where T
μ,σ,p = θ;
z_star = find_zero(z -> logistic(z) - p, 0.0)
return pdf(Normal(μ,σ),z_star)
end
test_fun([0.0,1.0,0.75])
ForwardDiff.gradient(test_fun,[0.0,1.0,0.75])
This results in the following error:
ERROR: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3})
Closest candidates are:
Float64(::Real, ::RoundingMode) where T<:AbstractFloat at rounding.jl:200
Float64(::T) where T<:Number at boot.jl:716
Float64(::Irrational{:invsqrt2}) at irrationals.jl:189
...
Stacktrace:
[1] convert(::Type{Float64}, ::ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}) at ./number.jl:7
[2] setproperty!(::Roots.UnivariateZeroState{Float64,ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}, ::Symbol, ::ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}) at ./Base.jl:34
[3] update_state(::Roots.Secant, ::Roots.DerivativeFree{Roots.DerivativeFree{var"#5#6"{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}}}, ::Roots.UnivariateZeroState{Float64,ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}, ::Roots.UnivariateZeroOptions{Float64,Float64,ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3},ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}) at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/derivative_free.jl:163
[4] find_zero(::Roots.Secant, ::Roots.AlefeldPotraShi, ::Roots.DerivativeFree{Roots.DerivativeFree{var"#5#6"{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}}}, ::Roots.UnivariateZeroState{Float64,ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}, ::Roots.UnivariateZeroOptions{Float64,Float64,ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3},ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}, ::Roots.NullTracks) at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/find_zero.jl:868
[5] find_zero(::Roots.DerivativeFree{var"#5#6"{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3}}}, ::Float64, ::Roots.Secant, ::Roots.AlefeldPotraShi; tracks::Roots.NullTracks, verbose::Bool, p::Nothing, kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/find_zero.jl:689
[6] #find_zero#36 at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/derivative_free.jl:123 [inlined]
[7] find_zero at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/derivative_free.jl:120 [inlined]
[8] #find_zero#5 at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/find_zero.jl:707 [inlined]
[9] find_zero at /bbkinghome/asharris/.julia/packages/Roots/TZpjF/src/find_zero.jl:707 [inlined]
[10] test_fun at ./REPL[7856]:3 [inlined]
[11] vector_mode_dual_eval at /bbkinghome/asharris/.julia/packages/ForwardDiff/QOqCN/src/apiutils.jl:37 [inlined]
[12] vector_mode_gradient(::typeof(test_fun), ::Array{Float64,1}, ::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3,Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3},1}}) at /bbkinghome/asharris/.julia/packages/ForwardDiff/QOqCN/src/gradient.jl:106
[13] gradient(::Function, ::Array{Float64,1}, ::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3,Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3},1}}, ::Val{true}) at /bbkinghome/asharris/.julia/packages/ForwardDiff/QOqCN/src/gradient.jl:19
[14] gradient(::Function, ::Array{Float64,1}, ::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3,Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_fun),Float64},Float64,3},1}}) at /bbkinghome/asharris/.julia/packages/ForwardDiff/QOqCN/src/gradient.jl:17 (repeats 2 times)
[15] top-level scope at REPL[7858]:1
[16] run_repl(::REPL.AbstractREPL, ::Any) at /builddir/build/BUILD/julia/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288
I have limited experience using the FowardDiff package and am probably misunderstanding how the Dual type works, so I would really appreciate if someone knows how to solve this issue. Thanks so much!
z_star = find_zero(z -> logistic(z) - p, 0.0)
You have a fixed initial condition which is non-dual. Make it dual.
z_star = find_zero(z -> logistic(z) - p, zero(eltype(θ))
I'm trying to learn Julia via project Euler. And for the largest prime factor problem I ran into an issue with out of memory error and I don't understand why.
I have tried the same solution in Python and had no issues.
function Primes(n)
numbers = Set{Int64}(2:n)
primes = Int64[]
while length(numbers)!=0
p = pop!(numbers,minimum(numbers))
push!(primes,p)
if length(numbers)!=0
numbers = setdiff(numbers,Set{Int64}(2*p:p:maximum(numbers)))
end
end
return primes
end
function LPF(n)
primes = Primes(n//2)
for p in primes
if n%p==0
return p
end
end
end
LPF(600851475143)
this is my error message:
OutOfMemoryError()
Stacktrace:
[1] _growend! at .\array.jl:811 [inlined]
[2] resize! at .\array.jl:1003 [inlined]
[3] rehash!(::Dict{Int64,Nothing}, ::Int64) at .\dict.jl:183
[4] sizehint! at .\dict.jl:242 [inlined]
[5] sizehint! at .\set.jl:64 [inlined]
[6] union!(::Set{Int64}, ::UnitRange{Rational{Int64}}) at .\abstractset.jl:79
[7] Type at .\set.jl:10 [inlined]
[8] Primes(::Rational{Int64}) at .\In[14]:2
[9] LPF(::Int64) at .\In[24]:2
[10] top-level scope at In[25]:1
I am having trouble with pmap() throwing a BoundsError when setting the values of array elements - my code works for 1 worker but not >1. I have written a minimum working example which roughly follows the real code flow:
Get source data
Define set of points over which to iterate
Initialise array points to be calculated
Calculate each array point
The main file:
#pmapdemo.jl
using Distributed
#addprocs(length(Sys.cpu_info())) # uncomment this line for error
#everywhere include(joinpath(#__DIR__, "pmapdemo2.jl"))
function main()
# Get source data
source = Dict{String, Any}("t"=>zeros(5),
"x"=>zeros(5,6),
"y"=>zeros(5,3),
"z"=>zeros(5,3))
# Define set of points over which to iterate
iterset = Dict{String, Any}("t"=>source["t"],
"x"=>source["x"],
"y"=>fill(2, size(source["t"])[1], 1),
"z"=>fill(2, size(source["t"])[1], 1))
data = Dict{String, Any}()
# Initialise array points to be calculated
MyMod.initialisearray!(data, iterset)
# Calculate each array point
MyMod.calcarray!(data, iterset, source)
#show data
end
main()
The functionality file:
#pmapdemo2.jl
module MyMod
using Distributed
#everywhere using SharedArrays
# Initialise data array
function initialisearray!(data, fieldset)
zerofield::SharedArray{Float64, 4} = zeros(size(fieldset["t"])[1],
size(fieldset["x"])[2],
size(fieldset["y"])[2],
size(fieldset["z"])[2])
data["field"] = deepcopy(zerofield)
end
# Calculate values of array elements according to values in source
function calcpoint!((data, source, a, b, c, d))
data["field"][a,b,c,d] = rand()
end
# Set values in array
function calcarray!(data, iterset, source)
for a in eachindex(iterset["t"])
# [additional functionality f(a) here]
b = eachindex(iterset["x"][a,:])
c = eachindex(iterset["y"][a,:])
d = eachindex(iterset["z"][a,:])
pmap(calcpoint!, Iterators.product(Iterators.repeated(data,1), Iterators.repeated(source,1), Iterators.repeated(a,1), b, c, d))
end
end
end
The error output:
ERROR: LoadError: On worker 2:
BoundsError: attempt to access 0×0×0×0 Array{Float64,4} at index [1]
setindex! at ./array.jl:767 [inlined]
setindex! at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/SharedArrays/src/SharedArrays.jl:500 [inlined]
_setindex! at ./abstractarray.jl:1043
setindex! at ./abstractarray.jl:1020
calcpoint! at /home/dave/pmapdemo2.jl:25
#112 at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/process_messages.jl:269
run_work_thunk at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/process_messages.jl:56
macro expansion at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/process_messages.jl:269 [inlined]
#111 at ./task.jl:259
Stacktrace:
[1] (::getfield(Base, Symbol("##696#698")))(::Task) at ./asyncmap.jl:178
[2] foreach(::getfield(Base, Symbol("##696#698")), ::Array{Any,1}) at ./abstractarray.jl:1866
[3] maptwice(::Function, ::Channel{Any}, ::Array{Any,1}, ::Base.Iterators.ProductIterator{Tuple{Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Int64}},Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}}) at ./asyncmap.jl:178
[4] #async_usemap#681 at ./asyncmap.jl:154 [inlined]
[5] #async_usemap at ./none:0 [inlined]
[6] #asyncmap#680 at ./asyncmap.jl:81 [inlined]
[7] #asyncmap at ./none:0 [inlined]
[8] #pmap#213(::Bool, ::Int64, ::Nothing, ::Array{Any,1}, ::Nothing, ::Function, ::Function, ::WorkerPool, ::Base.Iterators.ProductIterator{Tuple{Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Int64}},Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}}) at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/pmap.jl:126
[9] pmap(::Function, ::WorkerPool, ::Base.Iterators.ProductIterator{Tuple{Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Int64}},Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}}) at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/pmap.jl:101
[10] #pmap#223(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::Function, ::Base.Iterators.ProductIterator{Tuple{Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Int64}},Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}}) at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/pmap.jl:156
[11] pmap(::Function, ::Base.Iterators.ProductIterator{Tuple{Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Dict{String,Any}}},Base.Iterators.Take{Base.Iterators.Repeated{Int64}},Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}}) at /build/julia/src/julia-1.1.1/usr/share/julia/stdlib/v1.1/Distributed/src/pmap.jl:156
[12] calcarray!(::Dict{String,Any}, ::Dict{String,Any}, ::Dict{String,Any}) at /home/dave/pmapdemo2.jl:20
[13] main() at /home/dave/pmapdemo.jl:19
[14] top-level scope at none:0
in expression starting at /home/dave/pmapdemo.jl:23
In pmapdemo2.jl, replacing data["field"][a,b,c,d] = rand() with #show a, b, c, d demonstrates that all workers are running and have full access to the variables being passed, however instead replacing it with #show data["field"] throws the same error. Surely the entire purpose of SharedArrays is to avoid this? Or am I misunderstanding how to use it with pmap?
This is a crosspost from the Julia discourse here.
pmap will do the work of passing the data to the processes, so you don't need to use SharedArrays. Typically, the function provided to pmap (and indeed map) will be a pure function (and therefore doesn't mutate any variable) which returns one element of an output array. That function is mapped across each element of the input array, and the pmap function will construct the output array for you. For example, in your case, the code may look a bit like this
calcpoint(source, (a,b,c,d)) = rand() # Or some function of source and the indices a,b,c,d
field["data"] = pmap(calcpoint, Iterators.repeated(source), Iterators.product(a,b,c,d))
I created a UnitRange in Julia and trying to create a plot of x with respect to x and x ^ 2. I have written the following code.
x = [-10:10]
p1 = plot(x, x)
p2 = plot(x, x.^2)
I am getting the following error:
MethodError: no method matching ^(::UnitRange{Int64}, ::Int64)
Closest candidates are:
^(!Matched::Float16, ::Integer) at math.jl:795
^(!Matched::Missing, ::Integer) at missing.jl:120
^(!Matched::Missing, ::Number) at missing.jl:93
...
Stacktrace:
[1] _broadcast_getindex at ./none:0 [inlined]
[2] getindex at ./broadcast.jl:515 [inlined]
[3] copy at ./broadcast.jl:790 [inlined]
[4] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(Base.literal_pow),Tuple{Base.RefValue{typeof(^)},Array{UnitRange{Int64},1},Base.RefValue{Val{2}}}}) at ./broadcast.jl:756
[5] top-level scope at In[18]:3
What is the mistake in my code?
You can change:
x.^2
to:
x[1].^2
When I tried to calculate
julia> -2.3^-7.6
-0.0017818389423254909
But the result given by my calculator is
0.0005506 + 0.001694 i
Just to be safe I tried it again and this time it complains. Why does it not complain when I tried it the first time?
julia> a = -2.3; b = -7.6; a^b
ERROR: DomainError with -2.6:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.
Stacktrace:
[1] throw_exp_domainerror(::Float64) at ./math.jl:35
[2] ^(::Float64, ::Float64) at ./math.jl:769
[3] top-level scope at none:0
[4] eval at ./boot.jl:319 [inlined]
[5] #85 at /Users/ssiew/.julia/packages/Atom/jodeb/src/repl.jl:129 [inlined]
[6] with_logstate(::getfield(Main, Symbol("##85#87")),::Base.CoreLogging.LogState) at ./logging.jl:397
[7] with_logger(::Function, ::Atom.Progress.JunoProgressLogger) at ./logging.jl:493
[8] top-level scope at /Users/ssiew/.julia/packages/Atom/jodeb/src/repl.jl:128
This is an order of operations issue. You can see how Julia's parsing that expression:
julia> parse("-2.3^-7.6")
:(-(2.3 ^ -7.6))
and so the reason you don't have any problems is because you're actually taking 2.3 ^ (-7.6), which is 0.0017818389423254909, and then flipping the sign.
Your second approach is equivalent to making sure that the "x" in "x^y" is really negative, or:
julia> parse("(-2.3)^-7.6")
:(-2.3 ^ -7.6)
julia> eval(parse("(-2.3)^-7.6"))
ERROR: DomainError:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.
Stacktrace:
[1] nan_dom_err at ./math.jl:300 [inlined]
[2] ^(::Float64, ::Float64) at ./math.jl:699
[3] eval(::Module, ::Any) at ./boot.jl:235
[4] eval(::Any) at ./boot.jl:234
And if we follow that instruction, we get what you expect:
julia> Complex(-2.3)^-7.6
0.0005506185144176565 + 0.0016946295370871215im