jump-dev / Convex.jl

A Julia package for disciplined convex programming
https://jump.dev/Convex.jl/stable/
Other
566 stars 121 forks source link

linear matrix combination #66

Open ericproffitt opened 9 years ago

ericproffitt commented 9 years ago

I would like to form a linear matrix combination of the form x1A1 + ... + xnAn, by doing:

dot([A1, ..., An], Variable(n))

However when I try to do this I get the error: ERROR: isless has no method matching isless(::Array{Float64,2}, ::Int64)

madeleineudell commented 9 years ago

Interesting, thanks for the bug report. As an immediate workaround, of course you can use

x = Variable(length(A)) B = zeros(size(A[1])) for i=1:10 B += A[i] * x[i] end

where A = [A1, ..., An]

Meanwhile, we'll look into the problem.

On Sun, Feb 15, 2015 at 10:44 PM, esproff notifications@github.com wrote:

I would like to form a linear matrix combination of the form x1A1 + ... + xnAn, by doing:

dot([A1, ..., An], Variable(n))

However when I try to do this I get the error: ERROR: isless has no method matching isless(::Array{Float64,2}, ::Int64)

— Reply to this email directly or view it on GitHub https://github.com/JuliaOpt/Convex.jl/issues/66.

Madeleine Udell PhD Candidate in Computational and Mathematical Engineering Stanford University www.stanford.edu/~udell

madeleineudell commented 9 years ago

ok, the problem is that

x = [rand(2,2) for i=1:3] x .>= 0

is an error, ie, .>= doesn't propagate into nested arrays as one might expect.

i'm running Julia 3.1 still. does anyone here know

  1. should this behavior be considered a bug?
  2. if so, is this fixed in later versions of julia?

On Sun, Feb 15, 2015 at 11:02 PM, Madeleine Udell <madeleine.udell@gmail.com

wrote:

Interesting, thanks for the bug report. As an immediate workaround, of course you can use

x = Variable(length(A)) B = zeros(size(A[1])) for i=1:10 B += A[i] * x[i] end

where A = [A1, ..., An]

Meanwhile, we'll look into the problem.

On Sun, Feb 15, 2015 at 10:44 PM, esproff notifications@github.com wrote:

I would like to form a linear matrix combination of the form x1A1 + ... + xnAn, by doing:

dot([A1, ..., An], Variable(n))

However when I try to do this I get the error: ERROR: isless has no method matching isless(::Array{Float64,2}, ::Int64)

— Reply to this email directly or view it on GitHub https://github.com/JuliaOpt/Convex.jl/issues/66.

Madeleine Udell PhD Candidate in Computational and Mathematical Engineering Stanford University www.stanford.edu/~udell

Madeleine Udell PhD Candidate in Computational and Mathematical Engineering Stanford University www.stanford.edu/~udell

ericproffitt commented 9 years ago

I'm running 0.3.5 and I get the error. I'm not an authority but I would not consider that to be a bug, strictly speaking.

IainNZ commented 9 years ago

@madeleineudell, what is your expected behaviour for

x = [rand(2,2) for i=1:3]
x .>= 0

? Is it to do an element wise comparison with 0 to the nested arrays?

madeleineudell commented 9 years ago

yes, i suppose it's not clear whether .>= should recurse by calling .>= elementwise, or >= elementwise.

more generally, Convex.jl is not designed to play well with constants that are not either numbers, vectors, or (abstract) 2D arrays. i think this is a bigger issue than just this atom. for example, we're certainly not prepared to answer the question of what, eg, multiplication by [rand(2,2) for i=1:3] would mean...

i'd say that until we think it through (or possibly always), the right approach is simply to throw a more useful error when someone tries to call a Convex.jl atom on an argument that is not a number, vector, (abstract) 2D array, or AbstractExpr (the internal type used by Convex.jl).

On Mon, Feb 16, 2015 at 7:23 AM, Iain Dunning notifications@github.com wrote:

@madeleineudell https://github.com/madeleineudell, what is your expected behaviour for

x = [rand(2,2) for i=1:3] x .>= 0

? Is it to do an element wise comparison with 0 to the nested arrays?

— Reply to this email directly or view it on GitHub https://github.com/JuliaOpt/Convex.jl/issues/66#issuecomment-74524069.

Madeleine Udell PhD Candidate in Computational and Mathematical Engineering Stanford University www.stanford.edu/~udell

madeleineudell commented 9 years ago

Thinking about the problem of constructing a linear combination of matrices again, I do think it's worthwhile to have a function specialized for this, because some constructions result in problems that are much smaller.

I'm not sure what the best name would be, though. SDPdot? sum_o_matrices? I'm open to suggestions.

function SDPdot(A::Array{Array{Float64,2},1},y)
    m = length(A)
    length(y) == m || error("dimension mismatch. size(A) is $(size(A)) and y is $(size(y))")
    n1, n2 = size(A[1])
    all([(n1, n2 == size(A[i])) for i=1:m]) || error("dimension mismatch. elements of A must all be same size")
    bigA = zeros(n1*n2, m)
    for i=1:m
        bigA[:,i] = vec(A[i])
    end
    return reshape(bigA*y, n1, n2)
end

function SDPdot(A::Array{Float64,2}, y)
    m,n = size(A)
    if length(y) == n
        m,n = n,m
    end
    length(y) == m || error("dimension mismatch. size(A) is $(size(A)) and y is $(size(y))")
    bigA = zeros(n^2, m)
    for i=1:m
        bigA[:,i] = vec(A[i,:]'*A[i,:])
    end
    return reshape(bigA*y, n, n)
end
ericproffitt commented 9 years ago

The 5th line of the first function needs parentheses around the n1, n2 (at least in Julia 3.9), other than that it looks good.

Also I think the name SDPdot is solid, succinct and to the point.