Convex.jl
Convex.jl copied to clipboard
Problem with complex variables
Hi, it is the first time I write an issue so forgive me if I do not respect some kind of etiquette. I was trying to solve an optimization problem coming from quantum information theory in Convex.jl since it supports complex numbers, however, I ran into some issues.
If I just try to run the code listed on the official documentation, i.e. I run the following code
using Convex
A = [ 0.47213595 0.11469794+0.48586827im; 0.11469794-0.48586827im 0.52786405]
B = ComplexVariable(2, 2)
ρ = kron(A, B)
constraints = [partialtrace(ρ, 1, [2; 2]) == [1 0; 0 0]
trace(ρ) == 1
ρ in :SDP]
p = satisfy(constraints)
I get this error message:
MethodError: no method matching .<=(::Int64, ::Complex{Float64})
Closest candidates are:
.<=(::Real, ::Real) at operators.jl:160
.<=(::Any, ::AbstractArray{T,N}) at broadcast.jl:370
.<=(::AbstractArray{T,N}, ::Any) at broadcast.jl:370
in Convex.Constant(::Complex{Float64}, ::Bool) at /home/francesco/.julia/v0.5/Convex/src/constant.jl:25
in kron(::Array{Complex{Float64},2}, ::Convex.Variable) at /home/francesco/.julia/v0.5/Convex/src/atoms/affine/kron.jl:9
Apparently, he error is due to kron()
.
Another similar error I get comes from running this minimal example:
using Convex
x=ComplexVariable()
a=x*(1.0+0.0im)
which throws:
MethodError: no method matching .<=(::Int64, ::Complex{Float64})
Closest candidates are:
.<=(::Real, ::Real) at operators.jl:160
.<=(::Any, ::AbstractArray{T,N}) at broadcast.jl:370
.<=(::AbstractArray{T,N}, ::Any) at broadcast.jl:370
in Convex.Constant(::Complex{Float64}, ::Bool) at /home/francesco/.julia/v0.5/Convex/src/constant.jl:25
in *(::Convex.Variable, ::Complex{Float64}) at /home/francesco/.julia/v0.5/Convex/src/atoms/affine/multiply_divide.jl:105
Interestingly, there is no error if the imaginary part is not zero, i.e. with a=x*(1.0+1.0im)
.
Can someone tell me what is happening here?
Intuitively I would say it is a bug; this renders my code unusable since sometimes complex numbers with zero imaginary part come out...
By the way, thank you for this nice piece of software.
P.S. For completeness, this is the output of versioninfo()
on my system (Ubuntu 16.04.02):
Julia Version 0.5.2
Commit f4c6c9d4bb (2017-05-06 16:34 UTC)
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
WORD_SIZE: 64
BLAS: libopenblas (NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY Haswell)
LAPACK: liblapack.so.3
LIBM: libopenlibm
LLVM: libLLVM-3.7.1 (ORCJIT, broadwell)
This works for me without error on the current master branch and on the
most recent tagged version. Running Pkg.update()
should fix any errors.
On Fri, Jul 14, 2017 at 6:43 AM, falbarelli [email protected] wrote:
Hi, it is the first time I write an issue so forgive me if I do not respect some kind of etiquette. I was trying to write a problem from quantum information theory in Convex.jl since it supports complex numbers, however, I ran into some problems.
If I just try to run the code listed on the official documentation https://convexjl.readthedocs.io/en/latest/complex-domain_optimization.html#optimizing-over-quantum-states, i.e. I run the following code
using Convex
A = [ 0.47213595 0.11469794+0.48586827im; 0.11469794-0.48586827im 0.52786405] B = ComplexVariable(2, 2) ρ = kron(A, B) constraints = [partialtrace(ρ, 1, [2; 2]) == [1 0; 0 0] trace(ρ) == 1 ρ in :SDP] p = satisfy(constraints)
I get this error message:
MethodError: no method matching .<=(::Int64, ::Complex{Float64}) Closest candidates are: .<=(::Real, ::Real) at operators.jl:160 .<=(::Any, ::AbstractArray{T,N}) at broadcast.jl:370 .<=(::AbstractArray{T,N}, ::Any) at broadcast.jl:370
in Convex.Constant(::Complex{Float64}, ::Bool) at /home/francesco/.julia/v0.5/Convex/src/constant.jl:25 in kron(::Array{Complex{Float64},2}, ::Convex.Variable) at /home/francesco/.julia/v0.5/Convex/src/atoms/affine/kron.jl:9
Apparently, he error is due to kron().
Another similar error I get comes from running this minimal example:
using Convex
x=ComplexVariable()
a=x*(1.0+0.0im)
which throws:
MethodError: no method matching .<=(::Int64, ::Complex{Float64}) Closest candidates are: .<=(::Real, ::Real) at operators.jl:160 .<=(::Any, ::AbstractArray{T,N}) at broadcast.jl:370 .<=(::AbstractArray{T,N}, ::Any) at broadcast.jl:370
in Convex.Constant(::Complex{Float64}, ::Bool) at /home/francesco/.julia/v0.5/Convex/src/constant.jl:25 in *(::Convex.Variable, ::Complex{Float64}) at /home/francesco/.julia/v0.5/Convex/src/atoms/affine/multiply_divide.jl:105
Interestingly, there is no error if the imaginary part is not zero, i.e. with a=x*(1.0+1.0im). Can someone tell me what is happening here? Intuitively I would say it is a bug; this renders my code unusable since sometimes complex numbers with zero imaginary part come out...
By the way, thank you for this nice piece of software.
P.S. For completeness, this is the output of versioninfo() on my system (Ubuntu 16.04.02):
Julia Version 0.5.2 Commit f4c6c9d4bb (2017-05-06 16:34 UTC) Platform Info: OS: Linux (x86_64-linux-gnu) CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz WORD_SIZE: 64 BLAS: libopenblas (NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY Haswell) LAPACK: liblapack.so.3 LIBM: libopenlibm LLVM: libLLVM-3.7.1 (ORCJIT, broadwell)
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/JuliaOpt/Convex.jl/issues/204, or mute the thread https://github.com/notifications/unsubscribe-auth/AAyp9GSgOurY0_lOlIyys8aWCGq4qZrSks5sN3CNgaJpZM4OYRTm .
-- Madeleine Udell Assistant Professor, Operations Research and Information Engineering Cornell University https://people.orie.cornell.edu/mru8/ (415) 729-4115
@madeleineudell thank you for the reply. I am sorry but I just updated everything and the problem persists I also tried on a different Windows machine with both Julia 0.5.2 and 0.6 but the problem still appears...(I just tried the minimal example of adding a complex number to the variable). I don't know what is happening...
@falbarelli thanks for the note! We have had this error before, the master branch has a fix to it. Please switch to master branch.
Pkg.checkout("Convex")
This should work. Let us know if the problem persists, happy to help :)
Note that Convex.jl 0.6.0 is still not in METADATA: https://github.com/JuliaLang/METADATA.jl/pull/9919
@Ayush-iitkgp thank you for answering! I tried what you said:
julia> Pkg.checkout("Convex")
INFO: Checking out Convex master...
INFO: Pulling Convex latest master...
INFO: No packages to install, update or remove
but the problem when giving x+(1.0+0.0im)
persists :(
@mlubin so the solution is just pulling from git for the moment?
No, Pkg.checkout
is equivalent to pulling from git.
@falbarelli the problem is because of the return type of isreal
Julia in-built function.
julia > z = 1+0.0im
julia> isreal(z)
true
Any complex number with an imaginary part as zero is a special case. We actually did solve a similar problem in kron atom by putting a if condition here.
But I am not sure if we should do it. Why would someone want to write a real number x as x+0.0im? @madeleineudell @mlubin any views?
@Ayush-iitkgp thank you for the explanation! Well in my code it happened by chance that some of the imaginary components were null, e.g. I did not directly write the number but it was the result of previous operations on complex numbers, akin to
julia> (0.5+1.0im)+(0.5-1.0im)
1.0 + 0.0im
I'm sure that there are plenty of cases where a number could be complex, but turns out to be real in a particular instance.
Anyway thank you again, I could fix my code by taking real()
when appropriate :)
I just ran into this problem about zero imaginary components giving errors, and I'd like to second @falbarelli's comment that
I'm sure that there are plenty of cases where a number could be complex, but turns out to be real in a particular instance.
I have a matrix-valued parameter which for some instances of the problem happens to have no imaginary components, but was constructed by modifying a matrix of complex zeros, so it ends up with complex type. I can just check myself if this parameter is real via isreal
and then convert it to real if it is. So I guess it's not such a big problem, but it does seem like it would be nice to not run into it.
Closing because this appears to be fixed:
julia> using Convex
julia> A = [ 0.47213595 0.11469794+0.48586827im; 0.11469794-0.48586827im 0.52786405]
2×2 Matrix{ComplexF64}:
0.472136+0.0im 0.114698+0.485868im
0.114698-0.485868im 0.527864+0.0im
julia> B = ComplexVariable(2, 2)
Variable
size: (2, 2)
sign: complex
vexity: affine
id: 389…219
julia> ρ = kron(A, B)
reshape (affine; complex)
└─ * (affine; complex)
├─ 16×16 Matrix{Bool}
└─ reshape (affine; complex)
└─ hcat (affine; complex)
├─ …
└─ …
julia> constraints = [partialtrace(ρ, 1, [2; 2]) == [1 0; 0 0]
tr(ρ) == 1
ρ in :SDP]
3-element Vector{Constraint}:
== constraint (affine)
├─ + (affine; complex)
│ ├─ * (affine; complex)
│ │ ├─ * (affine; complex)
│ │ │ ├─ …
│ │ │ └─ …
│ │ └─ 4×2 Matrix{Float64}
│ └─ * (affine; complex)
│ ├─ * (affine; complex)
│ │ ├─ …
│ │ └─ …
│ └─ 4×2 Matrix{Float64}
└─ 2×2 Matrix{Int64}
== constraint (affine)
├─ sum (affine; complex)
│ └─ diag (affine; complex)
│ └─ reshape (affine; complex)
│ └─ …
└─ [1;;]
sdp constraint (affine)
└─ reshape (affine; real)
└─ * (affine; real)
├─ 64×64 Matrix{Bool}
└─ reshape (affine; real)
└─ …
julia> p = satisfy(constraints)
satisfy
└─ nothing
subject to
├─ == constraint (affine)
│ ├─ + (affine; complex)
│ │ ├─ * (affine; complex)
│ │ │ ├─ …
│ │ │ └─ …
│ │ └─ * (affine; complex)
│ │ ├─ …
│ │ └─ …
│ └─ 2×2 Matrix{Int64}
├─ == constraint (affine)
│ ├─ sum (affine; complex)
│ │ └─ diag (affine; complex)
│ │ └─ …
│ └─ [1;;]
└─ sdp constraint (affine)
└─ reshape (affine; real)
└─ * (affine; real)
├─ …
└─ …
status: `solve!` not called yet