Skip to content
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

Extend setvalue to JuMPArrays #540

Merged
merged 1 commit into from
Aug 26, 2015

Conversation

anriseth
Copy link
Contributor

This commit enables us to run

@defVar(m, x[1:n])
setValue(x, x0)

for an array of numbers, x0.

Hope I put the code in the right place?

@anriseth anriseth force-pushed the anriseth-setvalue-vector branch 3 times, most recently from 3c0b286 to 4a863b1 Compare August 19, 2015 23:44
@@ -346,6 +346,10 @@ function setValue(v::Variable, val::Number)
end
end

setValue(set::Array{Variable}, val::Array) = map(setValue, set, val)

setValue(set::JuMPArray{Variable}, val::Array) = setValue(set.innerArray, val)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method only really makes sense for OneIndexedArray. Otherwise you could do:

@defVar(m, x[[:a,:b,:c], 1:2])
setValue(x, [1,2,3,4,5,6])

which doesn't make too much sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your example gives me the error

ERROR: `setValue` has no method matching setValue(::JuMPDict{Variable,2}, ::Array{Int64,1})

in v0.3.12. Maybe there have been some changes in v0.4?

It seems like my restriction to JuMPArrays means this does not work with variables that use symbols in indices.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see the method was for JuMPArray, try this:

@defVar(m, x[5:7, 1:2])
setValue(x, [1,2,3,4,5,6])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine?

julia> @defVar(m, x[5:7, 1:2])
x[i,j] free for all i in {5,6,7}, j in {1,2}

julia> setValue(x, [1,2,3,4,5,6])
ERROR: dimensions must match
 in promote_shape at operators.jl:191
 in map at abstractarray.jl:1352
 in setValue at /home/asbjorn/.julia/v0.3/JuMP/src/JuMP.jl:267

@mlubin
Copy link
Member

mlubin commented Aug 20, 2015

I should test before posting code. This code works without error:

julia> @defVar(m, x[4:5,3:4])
x[i,j] free for all i in {4,5}, j in {3,4}

julia> setValue(x, [1 2; 3 4])
2x2 Array{Nothing,2}:
 nothing  nothing
 nothing  nothing

I would argue that it's misleading to accept this as input if the variable x doesn't use one-based indexing. Hence OneIndexedArray.

Also returning an array of nothing is a bit strange. Anyway these should be small fixes, otherwise I like the syntax.

x0 = [1:3]
@defVar(m, x[1:3])
setValue(x,x0)
@fact getValue(x).innerArray --> x0
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see from the build logs that getValue(x) returns an Array for that version of Julia+JuMP.

It runs fine on my setup, but maybe it's too outdated?
Julia 0.3.12-pre+3, JuMP 0.9.3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, on JuMP master getValue returns a julia Array when possible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also be good to add a test for the error case with mismatching dimensions.

@anriseth anriseth force-pushed the anriseth-setvalue-vector branch 2 times, most recently from accec91 to 8296505 Compare August 20, 2015 22:40
@anriseth
Copy link
Contributor Author

Ah, I understand what you mean by restricting it to OneIndexedArray now ...

map() returns Nothing: are you happy with adding an empty return-line at the end of the function instead?

Added dimension mismatch test as well.

@mlubin
Copy link
Member

mlubin commented Aug 25, 2015

  1. OneIndexedArray no longer exists as of [RFC] Remove OneIndexedArray #548 (sorry for the churn). Only need to worry about Array{Variable} now.
  2. To avoid allocating an extra array of nothings, I think it makes sense to implement setValue as first checking that the sizes match and then just have an explicit loop over eachindex of the arrays. @joehuchette?

@joehuchette
Copy link
Contributor

Yes, a loop like

for I in eachindex(x)
    setValue(set[I], val[I])
end
nothing

should do the trick.

@anriseth anriseth force-pushed the anriseth-setvalue-vector branch from 8296505 to 49a7990 Compare August 26, 2015 08:38
@anriseth
Copy link
Contributor Author

  1. I changed the setValue(OneIndexedArray, ...) back to JuMPArray. Do you want to keep this, or remove it entirely?
  2. Makes sense. I guess promote_shape isn't exactly what we're looking for, but the allocation of a shape tuple doesn't make much of a difference.

@mlubin
Copy link
Member

mlubin commented Aug 26, 2015

I changed the setValue(OneIndexedArray, ...) back to JuMPArray. Do you want to keep this, or remove it entirely?

I'd rather remove this entirely. JuMPArray objects aren't indexed in the same way as julia arrays.

promote_shape seems to be reasonable here.

Note travis is failing on 0.4:

 Failure :: (line:-1) :: wrong exception was thrown
    Expression: setValue(y,[1:6])
      Expected: ErrorException
      Occurred: DimensionMismatch

May need to special-case that test for 0.3 and 0.4.

@anriseth anriseth force-pushed the anriseth-setvalue-vector branch from 49a7990 to c72f31c Compare August 26, 2015 14:23
@anriseth
Copy link
Contributor Author

I removed the JuMPArray call and added a 0.4 case.

m = Model()
@defVar(m, x[1:3])
x0 = [1:3]
setValue(x.innerArray, x0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be setValue(x, x0)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed setValue(::JuMPArray, ...) as you wanted, so it is no longer possible to run setValue(x, x0).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I see from the test logs that your Julia/JuMP version is not happy with calling .innerArray. Whilst my setup is not happy with setValue(x, x0) ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this behavior changed in #548 about 16 hours ago :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're running with JuMP master, setValue(x, x0) will work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah, ok - I should learn to rebase on upstream master more often.

@joehuchette
Copy link
Contributor

Looks good to me! Thanks. We can merge after CI passes.

@anriseth anriseth force-pushed the anriseth-setvalue-vector branch from c72f31c to 6e05fd9 Compare August 26, 2015 14:37
mlubin added a commit that referenced this pull request Aug 26, 2015
@mlubin mlubin merged commit 1e6cb38 into jump-dev:master Aug 26, 2015
@mlubin
Copy link
Member

mlubin commented Aug 26, 2015

Thanks!

@anriseth anriseth deleted the anriseth-setvalue-vector branch August 26, 2015 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants