-
Notifications
You must be signed in to change notification settings - Fork 2
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
Add support for complex interface #23
Comments
I would be interested in adding proper complex support through MOI. I would be very helpful if you could give me some pointers on what needs to be done. |
Thanks for offering your help. There are two things to add which I think could be added independently in order to divide and conquer:
For 1), you have to modify MOI.Utilities.@product_of_sets(
ComplexCones,
MOI.Zeros,
)
MOI.Utilities.@struct_of_constraints_by_function_types(
ComplexOrReal,
MOI.VectorAffineFunction{Complex{Float64}},
MOI.VectorAffineFunction{Float64},
)
const OptimizerCache = MOI.Utilities.GenericModel{
Float64,
MOI.Utilities.ObjectiveContainer{Float64},
MOI.Utilities.VariablesContainer{Float64},
ComplexOrReal{Float64}{
MOI.Utilities.MatrixOfConstraints{
Float64,
MOI.Utilities.MutableSparseMatrixCSC{
Float64,
Int,
MOI.Utilities.OneBasedIndexing,
},
Vector{Float64},
ComplexCones{Float64},
},
MOI.Utilities.MatrixOfConstraints{
Float64,
MOI.Utilities.MutableSparseMatrixCSC{
Float64,
Int,
MOI.Utilities.OneBasedIndexing,
},
Vector{Float64},
Cones{Float64},
},
},
} You should add function MOI.supports_constraint(::Optimizer, ::Type{MOI.VectorAffineFunction{Complex{Float64}}}, ::Type{MOI.Zeros}})
return true
end Then, replace Line 148 in b69a1a6
by Ac = MOI.Utilities.constraints(
src.constraints,
MOI.VectorAffineFunction{Float64},
MOI.Zeros,
) and then you can get the complex one with Ac_complex = MOI.Utilities.constraints(
src.constraints,
MOI.VectorAffineFunction{Complex{Float64}},
MOI.Zeros,
) Then you can combine the two matrices and update |
Once 1) is done, for 2), I would define a bridge from MOI.Utilities.@product_of_sets(
ComplexCones,
MOI.Zeros,
) into MOI.Utilities.@product_of_sets(
ComplexCones,
MOI.Zeros,
ScaledPSDCone
) and modify function MOI.supports_constraint(::Optimizer, ::Type{MOI.VectorAffineFunction{Complex{Float64}}}, ::Type{MOI.Zeros}})
return true
end into function MOI.supports_constraint(::Optimizer, ::Type{MOI.VectorAffineFunction{Complex{Float64}}}, ::Type{<:Union{MOI.Zeros,ScaledPSDCone}}})
return true
end and then modify I would start with a PR for 1) that we merge before attacking 2). Let us know if you encounter any issue |
Thanks a lot for the detailed pointers. I'm afraid I didn't understand everything. Isn't 1) just allowing complex numbers in the equality constraints? But what is the benefit of doing that directly in SeDuMi? What SeDuMi will do is just split the constraint into real and imaginary parts, which is what JuMP is already doing. As for 2), isn't the ScaledPSDCone in MOI defined only for real symmetric matrices? Also, why would I want the version scaled by sqrt(2), since SeDuMi wants the non-scaled version as input? |
Not sure what SeDuMi does internally but if it just reformulates that might not be too interesting, you can just do 2) if you're only interested in that.
is the same as
That's what I remember from when I wrote the SeDuMi wrapper. All Matlab SDP solver (SDPT3, SeDuMi, CDCS, SDPNAL, ...) are quite different in the way they want the matrix to be inputed so it was a bit of trial and error until the MOI tests pass and I don't remember which one wanted what exactly. I'm quite confident that scaling by |
Ok, I see, SeDuMi does definitely want the matrix in square form as input. I also know that internally it will discard the upper triangular and re-scale the lower triangular. I would assume that doing that on the input would wreak havoc, but I guess it will become obvious why it works as I start tinkering. Thanks again! |
Yes, we want to do everything as bridge so that it works well with MatrixOfConstraints and we can just take the matrix as is |
I got stuck. I'm trying to promote the VectorAffineTerm to complex variables, but MOI instead insists in mapping them back to reals. Any ideas? Specifically I'm trying to do |
|
That works, thanks. I thought that was equivalent to |
I'm stuck again. I can't convince MOI that SeDuMi now does support function MOI.supports_constraint(
::Optimizer,
::Type{MOI.VectorAffineFunction{ComplexF64}},
::Type{ScaledPSDCone}
)
return true
end I suppose I need something like the boilerplate you wrote for |
Could you show me the code and the syntax error ? Maybe it's easier if you open a PR with your current code and show the error in the comment of the PR. I added you write access so that you can create a branch on the upstream remote directly so that I can modify it as well |
Well the syntax errors are caused by your code alone, you can literally paste that into |
Thanks for giving me write access, but accepting it requires me to enable two-factor authentication, which I refuse. I can do a regular PR instead if you want. |
Any reason? This is a standard security policy for all repositories in jump-dev. Note that you don't have to use a phone number as the 2FA. See https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication |
Because 2FA is a huge pain in the ass, I'd rather keep using just the password to login. |
From our perspective, 2FA is to minimize the risk of someone's account being compromised and used to push malicious code to one of the repo's in JuMP-dev. But also, the 2FA is pretty minimal. I stay logged into my account on my computer, so the only time I ever need to validate is performing an admin permission, like moving a repository, or changing secrets. You don't need to validate every time you open a PR or commit, so it shouldn't impact your day-to-day workflow. |
It is out of the question, I'm not going to mess up my github account, specially not in order to contribute to somebody else's project. Moreover, the idea that someone would be interested in pushing malicious code to jump-dev repositories strikes me as paranoid. Such a commit would be instantly reverted and never become part of a release. And if you think my account is insecure you're welcome to try and hack it. |
It's fine if you push to your fork and create a PR, forget about it ;)
Since you could fix some, I'd rather start from your branch than from my untested code |
I've already submitted a PR. And I did check the box "Allow edits by maintainers", so you have write access to it. |
Yes, I missed that thanks, I'm going to check next week |
Just pushed to your branch, it seems to go through, you should have what you need in |
Awesome, thanks, indeed the data now gets to where it needs to be. |
See jump-dev/JuMP.jl#3257 (comment) for a good MWE to use. I won't have time to take a look this week though
The text was updated successfully, but these errors were encountered: