When solving a convex quadratic optimization problem with semidefinite constraints in Mosek, the objective_value function appears to be returning an objective value that is off by a constant.
Minimal working example: when I run the following block of code in Julia 1.9.1/JuMP 1.16.0/Mosek.jl 10.1.3
using JuMP, Mosek, MosekTools, Random
Random.seed!(12345)
a=rand(10)
@show a
m=Model(Mosek.Optimizer)
@variable(m, Y[1:10, 1:10], PSD)
@objective(m, Min, sum((Y[i,i]-a[i])^2 for i=1:10))
@constraint(m, sum(Y[i,i] for i=1:10)==1.0)
optimize!(m)
@show objective_value(m)
@show objective_value(m)-sum(a[i]^2 for i=1:10)
@show sum((value.(Y)[i,i]-a[i])^2 for i=1:10)
I get the following output:
a = [0.7918054038647908, 0.1595789996994108, 0.33419142747606, 0.8113922657011057, 0.7966292033537833, 0.9178138221831842, 0.31132682723725014, 0.7529056805990061, 0.6338479453532103, 0.8999510969166794]
Problem
Name :
Objective sense : minimize
Type : CONIC (conic optimization problem)
Constraints : 1
Affine conic cons. : 1 (12 rows)
Disjunctive cons. : 0
Cones : 0
Scalar variables : 1
Matrix variables : 1 (scalarized: 55)
Integer variables : 0
Optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Eliminator started.
Freed constraints in eliminator : 0
Eliminator terminated.
Eliminator - tries : 1 time : 0.00
Lin. dep. - tries : 1 time : 0.00
Lin. dep. - primal attempts : 1 successes : 1
Lin. dep. - dual attempts : 0 successes : 0
Lin. dep. - primal deps. : 0 dual deps. : 0
Presolve terminated. Time: 0.00
Optimizer - threads : 12
Optimizer - solved problem : the primal
Optimizer - Constraints : 12
Optimizer - Cones : 2
Optimizer - Scalar variables : 14 conic : 14
Optimizer - Semi-definite variables: 1 scalarized : 55
Factor - setup time : 0.00
Factor - dense det. time : 0.00 GP order time : 0.00
Factor - nonzeros before factor : 78 after factor : 78
Factor - dense dim. : 0 flops : 2.03e+03
ITE PFEAS DFEAS GFEAS PRSTATUS POBJ DOBJ MU TIME
0 9.0e+00 1.0e+00 1.7e+00 0.00e+00 0.000000000e+00 -7.071067812e-01 1.0e+00 0.00
1 3.3e+00 3.6e-01 6.9e-01 -4.16e-01 1.056923953e+00 1.164658325e+00 3.6e-01 0.00
2 1.4e+00 1.6e-01 5.5e-02 1.32e+00 2.582687886e+00 2.298362008e+00 1.6e-01 0.00
3 2.4e-01 2.6e-02 3.1e-03 1.57e+00 3.201035910e+00 3.169139781e+00 2.6e-02 0.00
4 6.0e-02 6.6e-03 5.0e-04 1.16e+00 3.247189070e+00 3.240395108e+00 6.6e-03 0.00
5 1.5e-02 1.6e-03 6.5e-05 1.06e+00 3.260054465e+00 3.258530273e+00 1.6e-03 0.00
6 2.3e-03 2.5e-04 4.4e-06 1.01e+00 3.262749573e+00 3.262535332e+00 2.5e-04 0.00
7 3.0e-04 3.3e-05 2.2e-07 1.00e+00 3.263244710e+00 3.263217304e+00 3.3e-05 0.00
8 2.8e-06 3.1e-07 2.0e-10 1.00e+00 3.263311335e+00 3.263311078e+00 3.1e-07 0.00
9 1.1e-07 1.2e-08 1.6e-12 1.00e+00 3.263311979e+00 3.263311969e+00 1.2e-08 0.00
10 1.1e-08 1.2e-09 5.0e-14 1.00e+00 3.263312005e+00 3.263312004e+00 1.2e-09 0.00
Optimizer terminated. Time: 0.01
objective_value(m) = 4.774929425505085
objective_value(m) - sum((a[i] ^ 2 for i = 1:10)) = 0.0
sum(((value.(Y)[i, i] - a[i]) ^ 2 for i = 1:10)) = 3.2633120002611253
This is quite strange because I would expect the third to last and last lines to match.
Does anyone know what’s going on? Thanks!