# Summing exponential expressions in NLP

**URL:** <https://discourse.julialang.org/t/summing-exponential-expressions-in-nlp/102640>\
**Category:** Optimization (Mathematical)\
**Created:** [August 9, 2023, 2:29pm UTC](https://discourse.julialang.org/t/summing-exponential-expressions-in-nlp/102640 "2023-08-09T14:29:03Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![lgo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lgo/32/48751_2.png) [@lgo](https://discourse.julialang.org/u/lgo)\
**Post date:** [August 9, 2023, 2:29pm UTC](https://discourse.julialang.org/t/summing-exponential-expressions-in-nlp/102640/1 "2023-08-09T14:29:03Z")

</div>

I have the NLP below that I want to solve with JuMP. The problem transforms the original time-series x\_t into a new time-series x'\_t with a different integral but the same shape and extremes. The objective function minimizes the difference between the integral of the transformed time-series and a target value. The first constraint defines the transformation based on the three variables \alpha,\beta and \gamma. Finally, the last two constraints fix the extreme values of the transformed time-series.

min (u -\sum\_t x'\_t)^2  
 x'\_t = \alpha \cdot x\_t^\beta + \gamma \forall t  
 x'\_{t\_{min}} = a\_{min}  
 x'\_{t\_{max}} = a\_{max}

My current Julia code looks like this:

> model = Model(Ipopt.Optimizer)
> 
> % define transformation variables  
> exp\_var = @variable(model, exp, lower\_bound = 0.0, upper\_bound = 1000, start = rand(0:25))  
> multi\_var = @variable(model, multi, lower\_bound = 0.0, upper\_bound = 1000, start = rand(0:25))  
> add\_var = @variable(model, add, lower\_bound = -1000, upper\_bound = 1000, start = rand(-25:25))
> 
> % define time-series variable  
> scaledTs\_var = @variable(model, tSteps[1:numSteps])
> 
> % definition of transformed time-series  
> @NLconstraint(model, def[i = 1:numSteps], scaledTs\_var[i] == multi\_var \* ts\_arr[i]^exp\_var + add\_var)
> 
> % enforce extremes  
> @constraint(model, minVal, scaledTs\_var[minStep\_int] == min\_fl)  
> @constraint(model, maxVal, scaledTs\_var[maxStep\_int] == max\_fl)
> 
> % set objective  
> @objective(model, Min, (sum(scaledTs\_var)- utz\_fl)^2)

However, this formulation is not really robust and frequently the solver fails. I used to solve this with GAMS and learned that most NLP solvers handle this problem much better if I just substitute the transformed time-series in the problem like this:

min (u - \sum\_t (\alpha \cdot x\_t^\beta + \gamma))^2  
 \alpha \cdot x\_{t\_{min}} ^\beta + \gamma = a\_{min}   
 \alpha \cdot x\_{t\_{max}} ^\beta + \gamma = a\_{max}

The problem is that in Julia I can’t sum the exponential expressions in the objective function.

> @objective(model, Min, (sum(map(i → multi\_var \* ts\_arr[i]^exp\_var + add\_var,1:numSteps))- utz\_fl)^2)

The code above just returns:

> LoadError: `begin...end` blocks are not supported in nonlinear macros. The nonlinear expression must be a single statement.

---

<div class="post-metadata">

**Author:** ![blob](https://avatars.discourse-cdn.com/v4/letter/b/ebca7d/32.png) [@blob](https://discourse.julialang.org/u/blob)\
**Post date:** [August 9, 2023, 3:43pm UTC](https://discourse.julialang.org/t/summing-exponential-expressions-in-nlp/102640/2 "2023-08-09T15:43:17Z")

</div>

I wasn’t able to reproduce your error because the code didn’t run (some missing values). If you have an example that reproduces the error, it would be good to post it.

In general you can sum exponential expressions in JuMP, at least this works:

```julia
using JuMP, Ipopt

####Me being creative with missing variables
numSteps = 50
minStep_int = 1
maxStep_int = 2
min_fl = 1
max_fl = 1
utz_fl = 0
ts_arr=ones(1,numSteps)
####
model = Model(Ipopt.Optimizer)

exp_var = @variable(model, exp, lower_bound = 0.0, upper_bound = 1000, start = rand(0:25))
multi_var = @variable(model, multi, lower_bound = 0.0, upper_bound = 1000, start = rand(0:25))
add_var = @variable(model, add, lower_bound = -1000, upper_bound = 1000, start = rand(-25:25))

scaledTs_var = @variable(model, tSteps[1:numSteps])

@NLconstraint(model, def[i = 1:numSteps], scaledTs_var[i] == multi_var * ts_arr[i]^exp_var + add_var)

@constraint(model, minVal, scaledTs_var[minStep_int] == min_fl)
@constraint(model, maxVal, scaledTs_var[maxStep_int] == max_fl)

# @objective(model, Min, (sum(scaledTs_var)- utz_fl)^2)  
# @objective(model, Min, (sum(map(i → multi_var * ts_arr[i]^exp_var + add_var,1:numSteps))- utz_fl)^2)

@NLobjective(model, Min, (sum(multi_var * ts_arr[i]^exp_var + add_var for i=1:numSteps)- utz_fl)^2)

```
