# How to replace macro argument with expr as being typed manually?

Given a macro `@NLobjective` which have the following usage example: `@NLobjective(m, Min, 11 x² - 484 x + 12358)`
I want to write a function that returns the last expression `11 x² - 484 x + 12358`.
Function implementation:

``````function CreateEq(x::VariableRef, arr::Array)
s = 0
for i in arr
s += (x-i)^2
end
return :(@NLobjective(m, Min, begin \$(s) end))
end
``````

given x and `S = [5,6,7,9,11,16,20,22,23,24,99]`

Output from `eval(CreateEq(x,S))` is understood in a different way that writing `@NLobjective(m, Min, 11 x² - 484 x + 12358)` and gives the following error message:

ERROR: Unexpected quadratic expression 11 x² - 484 x + 12358 in nonlinear expression. Quadratic expressions (e.g., created using @expression) and nonlinear expressions cannot be mixed.

Questions:

• How to make `begin \$(s) end` be substituted as manually writing `11 x² - 484 x + 12358`?

What are you trying to achieve? There is probably a better way to do it.

Do you want something like?

``````function create_eq(model, x, arr)
return @expression(model, sum((x - i)^2 for i in arr))
end
``````

I want to get around this setup:

`````` my_expr = CreateEq(x,S)
@variable(m, aux)
@constraint(m, aux == my_expr)
``````

I have tried your function using this: `@NLobjective(m, Min, @eval(create_eq(m,x,S)))`, but it gives the same error

So I assume you want to include an affine or quadratic expression within a nonlinear objective? And you followed the work-around in the docs? http://www.juliaopt.org/JuMP.jl/v0.19.2/nlp/#Syntax-notes-1

At present, the work-around is recommended:

``````function create_eq(model, x, arr)
aux = @variable(model)
@constraint(model, aux == sum((x - i)^2 for i in arr))
return aux
end

model = Model()
@variable(model, x)
ex = create_eq(model, x, [1, 2, 3])
@NLobjective(model, Min, ex)
``````

1 Like

Yes, that is it.

Thanks I will use your solution.

Here is the solution:

``````function CreateEq(x::VariableRef, arr::Array)
s = Expr(:call,:+)
for i in arr
push!(s.args, :((x - \$i)^2))
end
return s
end
``````

call it like that for macros:

`````` eval(:(@NLobjective(m, Min, \$(CreateEq(x,S)))))
``````