 # Getting INVALID_MODEL error while solving RMSE

I’m attempting to minimize an RMSE where the optimized coefficients alpha and beta give a forecasted value (xnext) from the original value (x_k). Initially it did not let me add the square root in the objective function, so I tried using sqrt(msd(xnext, x_k)) as my objective function but since xnext is computed dynamically, it gives me an error. Now, with the square root in the objective function, it give me an INVALID_MODEL error. Any ideas or suggestion will be greatly appreciated. The problem formulation is below and the julia code follows My code is below

bn = 33
#x_k = EstimatedVoltage;
x_k = [0.996296998; 0.99494058; 0.974948068; 0.969848525; 0.964424502; 0.947913184; 0.944859396; 0.935953084; 0.929733301; 0.920502051; 0.92148015; 0.918334107; 0.917047839; 0.913723332; 0.914563694; 0.914004943; 0.908324472; 0.909002883; 0.991995169; 0.983359984; 0.991156028; 0.98713166; 0.977664579; 0.968545981; 0.965580768; 0.945010536; 0.937951627; 0.925111218; 0.916413078; 0.91718043; 0.909069676; 0.909483012; 0.911058107]

``````# Initialize a JuMP Optimization Model
fcst = Model(with_optimizer(Ipopt.Optimizer, print_level=0))

# Defining variables
@variable(fcst, 0.001 <= alpha[i in 1:bn] <= 0.99)
@variable(fcst, 0.001 <= beta[i in 1:bn] <= 0.99)
@variable(fcst, a_k[i in 1:bn] )
@variable(fcst, b_k[i in 1:bn])
@variable(fcst, xnext[i in 1:bn])
@variable(fcst, Error[i in 1:bn])

# Objective function
@NLobjective(fcst, Min, sqrt(sum(xnext[i]-x_k[i] for i in 1:bn)^2/bn))
#@objective(fcst, Min, sum(xnext[i]-x_k[i] for i in 1:bn)^2/bn)
#@objective(fcst, Min, sqrt(msd(x_k,x_k)))
``````

bn = 33
for i in 1:bn

``````if i == 1
apast = x_k[1,1]
bpast = x_k[1,1] - x_k[2,1]
@constraint(fcst, a_k[i] ==  apast )
@constraint(fcst, b_k[i] ==  bpast)
@constraint(fcst, xnext[i] ==  a_k[i] + b_k[i])

else
apast = a_k[i-1]
bpast = b_k[i-1]
@constraint(fcst, a_k[i] ==  alpha[i]*x_k[i] + (1 - alpha[i]*(apast + bpast)))
@constraint(fcst, b_k[i] ==  beta[i]*(a_k[i] - apast) + (1 - beta[i]*bpast))
@constraint(fcst, xnext[i] ==  a_k[i] + b_k[i])
@constraint(fcst, beta[i] <= 0.99*alpha[i])
end
``````

end
# Solve the optimization problem
JuMP.optimize!(fcst)
Alpha = JuMP.value.(alpha)
Beta = JuMP.value.(beta)
Xnext = JuMP.value.(xnext)
Level = JuMP.value.(a_k)
Trend = JuMP.value.(b_k)

``````# Check that the solver terminated without an error
println("The solver termination status is \$(termination_status(fcst))")

# Check the value of the objective function
RMSE = objective_value(fcst)``````

It means Ipopt is evaluating a function outside of its domain.
Here, make sure it is only evaluating the square root with a positive input; see https://github.com/jump-dev/ipopt.jl#invalid_model-error
For instance,

``````using JuMP, Ipopt
model = Model(Ipopt.Optimizer)
@variable(model, x <= 2)
@NLobjective(model, Max, sqrt(x - 1))
optimize!(model)
@show termination_status(model)
@show raw_status(model)
``````

gives

``````termination_status(model) = MathOptInterface.INVALID_MODEL
raw_status(model) = "Invalid_Number_Detected"
``````

but

``````using JuMP, Ipopt
model = Model(Ipopt.Optimizer)
@variable(model, x <= 2, start = 1.1)
@NLobjective(model, Max, sqrt(x - 1))
optimize!(model)
@show termination_status(model)
@show raw_status(model)
``````

gives

``````termination_status(model) = MathOptInterface.LOCALLY_SOLVED
raw_status(model) = "Solve_Succeeded"
``````

Tip: always query `raw_status` when you wonder why a solver gives you a given status.

1 Like

Another trick you can use in some situations (like this one), is to omit the `sqrt` function entirely. Given that `sqrt` is a monotone function the arg min of `min:sqrt((x-c)^2)` and `min:(x-c)^2` will be the same. By omitting the `sqrt` function during the optimization, you avoid the issue of an undefined derivative at 0.0.

1 Like

Thank for your response. Yes, I can do that. It’ll slightly alter my coefficients and I’ll have to take the square root outside the objective function to get my RMSE but that should be okay.

Is there a better way to define my objective function because if I write it down like below it takes the sum before squaring?

@NLobjective(fcst, Min, sqrt(sum(xnext[i]-x_k[i] for i in 1:bn)^2/bn))

I want to square the values before taking the sum. So, I decided to write the objective function like below
@NLobjective(fcst, Min, (sum((xnext[i] - x_k[i] for i in 1:3).*(xnext[i]-x_k[i] for i in 1:3)))/bn)

However, the above objective function gives me the following error “LoadError: sum() can appear in nonlinear expressions only if the argument is a generator statement, for example, sum(x[i] for i in 1:N)”. How can I get rid of this error?

Thanks again

Thanks for the tip

``````@NLobjective(fcst, Min, sum((xnext[i] - x_k[i])^2 for i in 1:bn) / bn)
``````

should work.

1 Like

Yes, it does work. The placement of the for loop and parenthesis makes a huge difference

@NLobjective(fcst, Min, sum((xnext[i] - x_k[i])^2 for i in 1:bn) / bn)… this works
@NLobjective(fcst, Min, sum((xnext[i] - x_k[i] for i in 1:3)^2)/bn)…this does not work

With the right placement of the for loop, I was able to define the RMSE objective function with the square root included as shown below

@NLobjective(fcst, Min, sqrt(sum((xnext[i]-x_k[i])^2 for i in 1:bn)/bn))…this works
@NLobjective(fcst, Min, sqrt(sum((xnext[i]-x_k[i] for i in 1:bn)^2/bn))…this does not work