-
Notifications
You must be signed in to change notification settings - Fork 1
support complex PSD cone #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Sorry about the delay. Now the basic solving is working. Two problems remain: I can't figure out how to get extraction of dual variables to work, and the MOI tests are failing. The test failures seem to be due to MOI assuming that the raw solution returned by the solver is always real. This is not the case with SeDuMi, so if I understood it correctly the fix should be done there. |
|
I'm not in a position to competently review this because I don't have MATLAB to test. |
|
I've made some progress in returning the dual variables; at least now the algorithm is in place, the remaining issue is calling it correctly. As you can see in lines 253-254, it works correctly if I manually switch between asking for the dual variables for the real and complex cones, but not both at the same time. Also, I'm confused about the purpose of the function |
|
@blegat can you help me here? |
|
Thanks for the reminder, I'll take a look |
|
Maybe it's easier to instead add a bridge from |
Co-authored-by: Benoît Legat <[email protected]>
|
@araujoms Can you try removing |
|
I tried, got a bunch of errors. Why, though? Is this to get the MOI tests to pass? Solving was working correctly before, the part that was missing was recovering dual variables. What I did is removing everything related to function MOI.get(::Optimizer, ::MOI.Bridges.ListOfNonstandardBridges)
return Type[
ScaledPSDConeBridge{Float64},
MOI.Bridges.Constraint.HermitianToComplexSymmetricBridge{Float64},
]
end |
I prefer keeping simple bridges that do just one transformation rather than complicated bridges that mixes several ones. Especially when you need to figure out what's the adjoint of the inverse of the adjoint of the combination of several transformations. Here one of the two transformations I'm mentioning is the bridge from the MOI set to the SeDuMi set which is solver-specific and the other transformation is the one of jump-dev/MathOptInterface.jl#2724. |
|
I have implemented the adjoint, can you try now ? |
|
Sure. Same error as before: ERROR: MethodError: no method matching promote_operation(::typeof(*), ::Type{Float64}, ::Type{Float64}, ::Type{MathOptInterface.ScalarAffineFunction{ComplexF64}})
The function `promote_operation` exists, but no method is defined for this combination of argument types.I don't understand how is your new bridge supposed to work, though. |
|
Yes but then |
|
Ok I fixed that error on the MOI PR. I suspect we may still need to fix |
|
Now it doesn't produce any errors, but it doesn't use SeDuMi's complex PSD cone, but the real one: * Supported objective: MOI.ScalarAffineFunction{Float64}
* Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Zeros
* Unsupported constraint: MOI.VectorOfVariables-in-MOI.HermitianPositiveSemidefiniteConeTriangle
| bridged by:
| MOIB.Constraint.HermitianToSymmetricPSDBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.VectorOfVariables}
| may introduce:
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | bridged by:
| | SeDuMi.ScaledPSDConeBridge{Float64, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-SeDuMi.ScaledPSDConeIn order for struct ScaledPSDConeBridge{T,G} <: MOI.Bridges.Constraint.SetMapBridge{
T,
ScaledPSDCone,
MOI.PositiveSemidefiniteConeTriangle,
MOI.VectorAffineFunction{T},
G,
}
constraint::MOI.ConstraintIndex{MOI.VectorAffineFunction{T},ScaledPSDCone}
endIs |
src/MOI_wrapper.jl
Outdated
| function MOI.get(::Optimizer, ::MOI.Bridges.ListOfNonstandardBridges) | ||
| return Type[ScaledPSDConeBridge{Float64}] | ||
| return Type[ | ||
| ScaledPSDConeBridge{Float64}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may need to add ScaledPSDConeBridge{Complex{Float64}} here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No luck, still get the same error as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you push your work in progress that gets this error as a commit to this branch ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
MOI doesn't care what the internal type is. You just need to make sure that the return types from |
|
p.s., I've asked MATLAB for a license, because it's virtually impossible for me to review this PR without CI. |
Co-authored-by: Oscar Dowson <[email protected]>
|
That was it! MOI tests pass now. I only had to do the analogous change to querying the slack variables. |
|
Awesome, the PR is still blocked by
|
|
Just tested with MOI 1.40, everything works fine. |
| # of the sets just listed above. | ||
|
|
||
| const ComplexAff = MOI.VectorAffineFunction{Complex{Float64}} | ||
| const RealAff = MOI.VectorAffineFunction{Float64} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove these lines and use MOI.VectorAffineFunction{Float64} and MOI.VectorAffineFunction{ComplexF64} everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doesn't even compile if I do that. In any case this is Benoît's code, not mine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a comment above explaining why they are needed
Co-authored-by: Oscar Dowson <[email protected]>
This reverts commit b33c75d.
|
Tests are passing shell> git log HEAD^..HEAD
commit 637db910cc5a28f8d8fed0655cc184c86210ee2d (HEAD -> complex, araujoms/complex)
Author: Benoît Legat <[email protected]>
Date: Tue May 6 08:47:27 2025 +0200
Fix format
julia> versioninfo()
Julia Version 1.10.2
Commit bd47eca2c8a (2024-03-01 10:14 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 36 × Intel(R) Xeon(R) W-2295 CPU @ 3.00GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-15.0.7 (ORCJIT, cascadelake)
Threads: 1 default, 0 interactive, 1 GC (on 36 virtual cores)
Environment:
JULIA_EDITOR = code
JULIA_NUM_THREADS =
julia> include("test/runtests.jl");
Precompiling SeDuMi
1 dependency successfully precompiled in 2 seconds. 39 already precompiled.
Test Summary: | Pass Total Time
Linear Programming example | 7 7 2.1s
Test Summary: | Pass Total Time
Semidefinite Programming example | 10 10 0.6s
>> SeDuMi 1.3.7 by AdvOL, 2005-2008 and Jos F. Sturm, 1998-2003.
Alg = 2: xz-corrector, Adaptive Step-Differentiation, theta = 0.250, beta = 0.500
eqs m = 1, order n = 3, dim = 9, blocks = 2
nnz(A) = 1 + 0, nnz(ADA) = 1, nnz(L) = 1
it : b*y gap delta rate t/tP* t/tD* feas cg cg prec
0 : 8.33E+00 0.000
1 : 5.15E-01 1.60E+00 0.000 0.1923 0.9000 0.9000 1.46 1 1 7.6E-01
2 : 9.95E-01 4.27E-02 0.000 0.0267 0.9900 0.9900 0.95 1 1 1.9E-02
3 : 1.00E+00 4.38E-07 0.000 0.0000 1.0000 1.0000 1.00 1 1 1.6E-07
4 : 1.00E+00 4.54E-14 0.000 0.0000 1.0000 1.0000 1.00 1 1 1.6E-14
iter seconds digits c*x b*y
4 0.1 14.1 1.0000000000e+00 1.0000000000e+00
|Ax-b| = 5.4e-15, [Ay-c]_+ = 0.0E+00, |x|= 1.0e+00, |y|= 1.0e+00
Detailed timing (sec)
Pre IPM Post
3.634E-02 5.408E-02 2.404E-03
Max-norms: ||b||=1, ||c|| = 1,
Cholesky |add|=0, |skip| = 0, ||L.L|| = 1.
Test Summary: | Pass Total Time
test_complex | 4 4 3.5s
Test Summary: | Pass Total Time
test_complex_bridges | 4 4 3.5s
Test Summary: | Pass Total Time
test_options | 1 1 0.0s
>> Warning: Rank deficient, rank = 1, tol = 4.615110e-14.
> In sedumi (line 272)
>> Warning: Rank deficient, rank = 1, tol = 4.615110e-14.
> In sedumi (line 272)
Test Summary: | Pass Total Time
test_runtests | 4070 4070 5m05.0s
Test Summary: | Pass Total Time
test_solver_name | 1 1 0.0s |
|
@araujoms Thanks a lot !! |
|
Thank you! That was quite an odyssey. |
This adds the Hermitian bridge, which seems to do its job, but then the code dies when it reaches
optimize!with the error "MathOptInterface.VectorAffineFunction{ComplexF64}-in-SeDuMi.ScaledPSDConeconstraint is not supported by the model."I suppose I need to edit
OptimizerCacheto tell MOI that this is actually supported, but I don't know how.Closes #23