Good morning,
I encounter some issues when some complex numbers arise in my optimisation. I think it might be due to my function u(c) = c^gamma where sometimes c turns out negative (c being different expressions defined in code below and not a choice variable:  c1_ND,  c1_D,  c2ND(θ), c2D).
My code is below and I apologize for its length. The reason I am not cutting it is that I am not sure where the error comes from and also that it works for some values of gamma. A working example of it is to limit the values of the parameter gamma can take by doing aversion=2 and riskaversion = collect(range(3.0, length=Para.aversion, stop=30.0)): then it works for those values in the loop on gamma (loop at the end).
My question is: is there a way to deal with complex numbers arising for some values of my parameters gamma with the currently used optim? (Or should i turn to JuMP and define a condition on the expressions of c ( c1_ND,  c1_D,  c2ND(θ), c2D)  - which seems second best to me?)
Many thanks.
using Optim
using QuadGK
using QuantEcon
using Interpolations
using LineSearches
module Para 
    Re=1.3
    Rl=1.1
    E=2.0
    points=2
    lowerB=0.01
    aversion=3
end
    import ..Para
function solve(Gamma::AbstractFloat, centralized::Bool = true)
    
    u(c) = (c+0im).^Gamma
    
    function bk_obj(Sb::AbstractFloat, 
                    c_bar::AbstractFloat,
                    D::AbstractFloat)
        Lf= Para.Rl/(Para.Re- Para.Rl) * D * c_bar
        Sf= Para.E - D - Lf
        
        if centralized
                P_star= (Lf /Sb)
            else 
                P_star= Para.Re / Para.Rl
        end
        θhigh = (Para.Re * (1 - Sb) + Para.Re * (1 - Sb) * (P_star) - c_bar * (P_star) * D) / (c_bar * D * (Para.Re - (Lf / Sb)) )
        c1_ND = D * c_bar
        c1_D = (1 - Sb) + Lf
        c2ND(θ) = (((1 - Sb) - θ* c_bar * D) * Para.Rl + Sb * Para.Re + Lf * Para.Rl + Sf * Para.Re ) / (1 - θ)
        c2D(θ) = (1 - Sb) + Lf + ( (Sb + Sf) * Para.Re ) / (1 - θ)
        val1(θ) = u(θ * c1_ND + (1 - θ)* c2ND(θ)) 
        val2(θ) = u(θ * c1_D + (1 - θ)* c2D(θ)) 
        return -(quadgk(val1, 0.1, θhigh)[1] + quadgk(val2, θhigh, 0.999)[1])
    end #end of obj of bank
        grid = collect(range(Para.lowerB, length=Para.points, stop=Para.E))
        Sb = Vector{Float64}(undef,Para.points)
        cbar = Vector{Float64}(undef,Para.points)
        D_vec = Vector{Float64}(undef,Para.points)
        Res = Array{Float64}
        suboptimizer = GradientDescent(linesearch=LineSearches.Static())
        for (i,D) in enumerate(grid)
            bk(x) = bk_obj(x[1], x[2], D)
            D_vec[i]= D
            lower = [0.001, 0.001]
            upper = [D, 1.0]
            x0 = [0.01, 0.3]
                if i==1
            res = optimize(bk, lower, upper, x0, Fminbox(suboptimizer))
                    else 
            res = optimize(bk, lower, upper, Res, Fminbox(suboptimizer))
        end
            Res= Optim.minimizer(res)
            Sb[i]=Optim.minimizer(res)[1]
            cbar[i]=Optim.minimizer(res)[2]
         end
    D_row = (D_vec,) 
    Sb_int = interpolate(Sb, BSpline(Constant()))
    cbar_int = interpolate(cbar, BSpline(Constant()))
    Sb_func = extrapolate(Sb_int, Line())
    cbar_func = extrapolate(cbar_int, Line())
    function HH_obj(D::AbstractFloat) 
    Lf= Para.Rl/(Para.Re- Para.Rl) * D * cbar_func(D)
    Sf= Para.E - D - Lf
        
        if centralized
            P_star= (Lf /1 - Sb_func(D))
        else 
            P_star= Para.Re / Para.Rl
        end
    θhigh = (Para.Re * (1 - Sb_func(D)) + Para.Re * (1 - Sb_func(D)) * (P_star) - cbar_func(D) * (P_star) * D) / (cbar_func(D) * D * (Para.Re - (Lf / Sb_func(D))) )
    c1_ND = D * cbar_func(D)
    c1_D = (1 - Sb_func(D)) + Lf
    c2ND(θ) = (((1 - Sb_func(D)) - θ* cbar_func(D) * D) * Para.Rl + Sb_func(D) * Para.Re + Lf * Para.Rl + Sf * Para.Re ) / (1 - θ)
    c2D(θ) = (1 - Sb_func(D)) + Lf + ( (Sb_func(D) + Sf) * Para.Re ) / (1 - θ)
    val1(θ) = u(θ * c1_ND + (1 - θ)* c2ND(θ)) 
    val2(θ) = u(θ * c1_D + (1 - θ)* c2D(θ)) 
    return -(quadgk(val1, 0.1, θhigh)[1] + quadgk(val2, θhigh, 0.999)[1])    
    end
    x0_HH = [1.0]
    lowerHH = [Para.lowerB]
    upperHH = [1.9]
    fct_HH(x) = HH_obj(x[1])
    suboptimizer = GradientDescent(linesearch=LineSearches.Static())
    resHH= optimize(fct_HH, lowerHH, upperHH, x0_HH, Fminbox(suboptimizer))
    
    D_star_cent=Optim.minimizer(resHH)[1]
    
     if centralized
            D_star_cent=Optim.minimizer(resHH)[1]
            Sb_star_cent=Sb_func(D_star_cent)
            cbar_star_cent=cbar_func(D_star_cent)
            U_star_cent= -(HH_obj(D_star_cent))
            
            return  D_star_cent, Sb_star_cent, cbar_star_cent, U_star_cent
        
    else 
            D_star_dec=Optim.minimizer(resHH)[1]
            Sb_star_dec=Sb_func(D_star_dec)
            cbar_star_dec=cbar_func(D_star_dec)
            U_star_dec= -(HH_obj(D_star_dec))
            
            return D_star_dec, Sb_star_dec, cbar_star_dec, U_star_dec
    end
    
    
end
    riskaversion = collect(range(3, length=Para.aversion, stop=30))
    Gamma_vec = Vector{Float64}(undef,Para.aversion)
    diffU = Vector{Float64}(undef,Para.aversion)
    diffSb = Vector{Float64}(undef,Para.aversion)
    diffD = Vector{Float64}(undef,Para.aversion)
for (i,Gamma) in enumerate(riskaversion) 
    
    solve(Gamma, true)
    D_star_cent=solve(Gamma, true)[1]
    Sb_star_cent=solve(Gamma, true)[2]
    cbar_star_cent=solve(Gamma, true)[3]
    U_star_cent= solve(Gamma, true)[4]
    
    solve(Gamma, false)
    D_star_dec=solve(Gamma, false)[1]
    Sb_star_dec=solve(Gamma, false)[2]
    cbar_star_dec=solve(Gamma, false)[3]
    U_star_dec= solve(Gamma, false)[4]
    
    Gamma_vec[i]= Gamma
    diffU[i] = U_star_cent - U_star_dec 
    diffSb[i] = Sb_star_cent - Sb_star_dec 
    diffD[i] = D_star_cent - D_star_dec 
        
end
    return diffU, diffSb, diffD, Gamma_vec
and the error:
InexactError: Float64(Float64, 0.0 - 601724.3363405127im)
Stacktrace:
 [1] Type at .\complex.jl:37 [inlined]
 [2] convert(::Type{Float64}, ::Complex{Float64}) at .\number.jl:7
 [3] barrier_combined(::Array{Float64,1}, ::Array{Float64,1}, ::Nothing, ::Array{Float64,1}, ::getfield(Optim, Symbol("##55#61")){OnceDifferentiable{Float64,Array{Float64,1},Array{Float64,1}},getfield(Optim, Symbol("##54#60")){Array{Float64,1},Array{Float64,1}}}, ::Base.RefValue{Float64}) at C:\Users\arquie\.julia\packages\Optim\wi7Vp\src\multivariate\solvers\constrained\fminbox.jl:65
 [4] (::getfield(Optim, Symbol("##57#63")){getfield(Optim, Symbol("##55#61")){OnceDifferentiable{Float64,Array{Float64,1},Array{Float64,1}},getfield(Optim, Symbol("##54#60")){Array{Float64,1},Array{Float64,1}}}})(::Nothing, ::Array{Float64,1}) at C:\Users\arquie\.julia\packages\Optim\wi7Vp\src\multivariate\solvers\constrained\fminbox.jl:236
 [5] optimize(::OnceDifferentiable{Float64,Array{Float64,1},Array{Float64,1}}, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Fminbox{GradientDescent{InitialPrevious{Float64},Static,Nothing,getfield(Optim, Symbol("##13#15"))},Float64,getfield(Optim, Symbol("##46#48"))}, ::Optim.Options{Float64,Nothing}) at C:\Users\arquie\.julia\packages\Optim\wi7Vp\src\multivariate\solvers\constrained\fminbox.jl:224
 [6] #optimize#53(::Bool, ::Symbol, ::Function, ::Function, ::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}, ::Fminbox{GradientDescent{InitialPrevious{Float64},Static,Nothing,getfield(Optim, Symbol("##13#15"))},Float64,getfield(Optim, Symbol("##46#48"))}, ::Optim.Options{Float64,Nothing}) at C:\Users\arquie\.julia\packages\Optim\wi7Vp\src\multivariate\solvers\constrained\fminbox.jl:164
 [7] optimize at C:\Users\arquie\.julia\packages\Optim\wi7Vp\src\multivariate\solvers\constrained\fminbox.jl:163 [inlined] (repeats 2 times)
 [8] solve(::Float64, ::Bool) at .\In[16]:71
 [9] top-level scope at .\In[16]:155