Convex.jl icon indicating copy to clipboard operation
Convex.jl copied to clipboard

Issue multiplying expressions with matrices

Open baggepinnen opened this issue 8 years ago • 1 comments

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

baggepinnen avatar Jan 25 '16 08:01 baggepinnen

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.

madeleineudell avatar Jan 26 '16 18:01 madeleineudell

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.

odow avatar Apr 18 '24 02:04 odow