Convex.jl
Convex.jl copied to clipboard
Issue multiplying expressions with matrices
The following code produce an error when multiplying a Matrix{Float64} with a vector with MultiplyAtoms
m = Variable(3)
g = randn(3)
F = Array(typeof(m[1]*g[1]),3)
for i = 1:3
F[i] = m[i]*g[i]
end
randn(3,3)*F
With output
julia> m = Variable(3)
Variable of
size: (3, 1)
sign: Convex.NoSign()
vexity: Convex.AffineVexity()
julia> g = randn(3)
3-element Array{Float64,1}:
0.513403
0.0335255
1.66436
julia> F = Array(typeof(m[1]*g[1]),3)
3-element Array{Convex.MultiplyAtom,1}:
#undef
#undef
#undef
julia> for i = 1:3
F[i] = m[i]*g[i]
end
julia> randn(3,3)*F
ERROR: MethodError: `zero` has no method matching zero(::Convex.AdditionAtom)
in generic_matvecmul! at linalg/matmul.jl:406
in * at linalg/matmul.jl:82
julia> versioninfo()
Julia Version 0.4.2
Commit bb73f34* (2015-12-06 21:47 UTC)
Platform Info:
System: Linux (x86_64-redhat-linux)
CPU: Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
WORD_SIZE: 64
BLAS: libopenblas (DYNAMIC_ARCH NO_AFFINITY Haswell)
LAPACK: libopenblasp.so.0
LIBM: libopenlibm
LLVM: libLLVM-3.3
In the current implementation of Convex, a length-n vector of atoms is not the same as an atom of length n. There are good reasons to change this behavior: see #117 and the conversation on #118. I'm not going to be able to work on this for a while yet; if you'd like to take a gander at it, I'd welcome a PR.
This is because of a fairly deep design decision in Convex that I don't think we'll be resolving anytime soon. It would likely require a substantial rewrite.
The issue is that a vector of expressions is not the same of as an expression representing a vector.
The solution is to use vcat(F...)
to get a single expression that represents a vector.
julia> using Convex
julia> x = Variable(3)
Variable
size: (3, 1)
sign: real
vexity: affine
id: 801…507
julia> F = [x[i] for i in 1:3]
3-element Vector{Convex.IndexAtom}:
index (affine; real)
└─ 3-element real variable (id: 801…507)
index (affine; real)
└─ 3-element real variable (id: 801…507)
index (affine; real)
└─ 3-element real variable (id: 801…507)
julia> A = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> A * F
ERROR: MethodError: no method matching zero(::Convex.AdditionAtom)
Closest candidates are:
zero(::Type{Union{}}, Any...)
@ Base number.jl:310
zero(::Type{Pkg.Resolve.FieldValue})
@ Pkg ~/.julia/juliaup/julia-1.10.2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Pkg/src/Resolve/fieldvalues.jl:38
zero(::Type{Missing})
@ Base missing.jl:104
...
Stacktrace:
[1] _generic_matvecmul!(C::Vector{…}, tA::Char, A::Matrix{…}, B::Vector{…}, _add::LinearAlgebra.MulAddMul{…})
@ LinearAlgebra ~/.julia/juliaup/julia-1.10.2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/matmul.jl:743
[2] generic_matvecmul!
@ ~/.julia/juliaup/julia-1.10.2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/matmul.jl:687 [inlined]
[3] mul!
@ ~/.julia/juliaup/julia-1.10.2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/matmul.jl:66 [inlined]
[4] mul!
@ ~/.julia/juliaup/julia-1.10.2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/matmul.jl:237 [inlined]
[5] *(A::Matrix{Int64}, x::Vector{Convex.IndexAtom})
@ LinearAlgebra ~/.julia/juliaup/julia-1.10.2+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/matmul.jl:57
[6] top-level scope
@ REPL[47]:1
Some type information was truncated. Use `show(err)` to see complete types.
julia> A * vcat(F...)
* (affine; real)
├─ 2×3 Matrix{Int64}
└─ reshape (affine; real)
└─ * (affine; real)
├─ 3×3 Matrix{Bool}
└─ reshape (affine; real)
└─ …
Closing as won't-fix.