# JuMP/CPLEX: retrieve value of array-variables in callback

**URL:** <https://discourse.julialang.org/t/jump-cplex-retrieve-value-of-array-variables-in-callback/54933>\
**Category:** Optimization (Mathematical)\
**Created:** [February 9, 2021, 3:12pm UTC](https://discourse.julialang.org/t/jump-cplex-retrieve-value-of-array-variables-in-callback/54933 "2021-02-09T15:12:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike\_k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike_k/32/211864_2.png) [@mike\_k](https://discourse.julialang.org/u/mike_k)\
**Post date:** [February 9, 2021, 3:12pm UTC](https://discourse.julialang.org/t/jump-cplex-retrieve-value-of-array-variables-in-callback/54933/1 "2021-02-09T15:12:42Z")

</div>

Dear folks,  
I use JuMP (v0.21.4) and CPLEX (v0.7.3) and try to get the current variable values of sparse/dense-axis-array variables in a solver-specific callback. A quite long MWE based on the one in the documentation is given below.  
Retrieving single values works, however, I then need to create the wanted structures first. After solving is finished the values can be easily obtained by

```julia
y_val = value.(model[:y])
z_val = value.(model[:z])

```

Is there any similar approach for callbacks? Or at least a more efficient (and/or less buggy) approach than the work-around in the example below?

```julia
using JuMP, CPLEX, SparseArrays

function my_callback_function(cb_data::CPLEX.CallbackContext, context_id::Clong, model, I, K)
    CPLEX.load_callback_variable_primal(cb_data, context_id)

    #THIS WORKS
    y_val = zeros(Float64, length(I))
    for i in I
        y_val[i] = callback_value(cb_data, model[:y][i])
    end
    println("y: $y_val")

    z_val = spzeros(Float64, length(I), 5)
    for i in I, k in K[i]
        z_val[i,k] = callback_value(cb_data, model[:z][i,k])
    end

    #THIS DOES NOT WORK
    # y_val = callback_value.(cb_data, model[:y])
    # z_val = callback_value.(cb_data, model[:z])

    return
end

function main()
    I = 1:2
    K = [[1, 4, 5], [2, 3 ,4]]
    model = direct_model(CPLEX.Optimizer())
    MOI.set(model, MOI.NumberOfThreads(), 1)
    @variable(model, y[i in I], Bin)
    @variable(model, z[i in I, k in K[i]], Bin)
    @constraint(model, sum(y) <= 1)
    @objective(model, Max, sum(y) )

    function callCallback(cb_data::CPLEX.CallbackContext, context_id::Clong)
        if context_id != CPX_CALLBACKCONTEXT_CANDIDATE
            return
        end
        ispoint_p = Ref{Cint}()
        ret = CPXcallbackcandidateispoint(cb_data, ispoint_p)
        if ret != 0 || ispoint_p[] == 0
            return # No candidate point available or error
        end
        my_callback_function(cb_data, context_id, model, I, K)
        return
    end
    MOI.set(model, CPLEX.CallbackFunction(), callCallback)
    optimize!(model)
    println("OV: ", objective_value(model) )

    #this works
    y_val = value.(model[:y])
    z_val = value.(model[:z])
    return
end
main()

```

Thanks in advance. Best, mike\_k

---

<div class="post-metadata">

**Author:** ![mike\_k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike_k/32/211864_2.png) [@mike\_k](https://discourse.julialang.org/u/mike_k)\
**Post date:** [February 9, 2021, 4:21pm UTC](https://discourse.julialang.org/t/jump-cplex-retrieve-value-of-array-variables-in-callback/54933/2 "2021-02-09T16:21:31Z")

</div>

I found a solution:

```julia
y_val = callback_value.(Ref(cb_data), model[:y])
z_val = callback_value.(Ref(cb_data), model[:z])

```

does the job (although I do not understand why the Ref(.) is needed).

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 9, 2021, 5:53pm UTC](https://discourse.julialang.org/t/jump-cplex-retrieve-value-of-array-variables-in-callback/54933/3 "2021-02-09T17:53:33Z")

</div>

The `Ref` has nothing to do with `callback_value` specifically, but is a trick used together with any broadcasted functions (i.e., with the dot between name and starting parenthesis). Every argument to a broadcasted function need to be a “container” of sorts, if it is a single element, the single element is used for each of the multiple calls, if it has multiple elements, each element is used in a different call (the first element of all vectors with multiple elements is used in the first call, then the second, and so on) and the results are assembled in a collection (often a `Vector`) and returned (`y_val` and `z_val` in your case).

Any other single-element zero-dimensional container works, I use the tuple constructor actually:

```julia
y_val = callback_value.((cb_data,), model[:y])
z_val = callback_value.((cb_data,), model[:z])

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [February 9, 2021, 9:02pm UTC](https://discourse.julialang.org/t/jump-cplex-retrieve-value-of-array-variables-in-callback/54933/4 "2021-02-09T21:02:04Z")

</div>

I opened a PR to fix this: [https://github.com/jump-dev/CPLEX.jl/pull/354](https://github.com/jump-dev/CPLEX.jl/pull/354)
