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

Problem with solving NL problem #266

Closed
Ph0non opened this issue Sep 18, 2014 · 12 comments
Closed

Problem with solving NL problem #266

Ph0non opened this issue Sep 18, 2014 · 12 comments

Comments

@Ph0non
Copy link

Ph0non commented Sep 18, 2014

I have a big set of non-linear constraints for a problem and difficulties to add them right to JuMP. In an earlier version I use SymPy and save the constraints as string and parse them for JuMP. Now i try to add them natively to JuMP through @addNLConstraint.

The general form of a constraint for the problem is nominator .* x[i] / denominator .* x[i].
More precisely

sum{f[i, fma] .* x[i] .*a[:,fma,1], i=1:12} / sum{effizienz_arr[:,1] .* x[i], i=1:12} >= 1

I know that for multiplication it's neccessary o multiply coefficient by variable and not variable by coeefficient. But aside form this point there are different problems. JuMP accepts this Constraint but solving returns Unrecognized function .*. Some trying returns always Unrecognized function ....

f[:,fma] is an 12x10 array
x[i] goes from i=1 to 12
a[:,fma,1] is an 6x10 array
effizienz_arr[:,1] is an 12 element array

I appreciate every hint to get this set of constraint right into JuMP for solving.

@mlubin
Copy link
Member

mlubin commented Sep 18, 2014

Vectorized syntax like this isn't currently supported within @addNLConstraint. You should be able to get this working if you rewrite it using scalar operations.

@Ph0non
Copy link
Author

Ph0non commented Sep 18, 2014

Vectorized syntax would be very nice. So i have about 300 constraints with a lot of different indices.

Another example

@addNLConstraint(m, sum{x[i]*f[i,fma], i=1:length(Xvar)} >= 1)

ERROR: `convert` has no method matching convert(::Type{Float64}, ::Array{Float64,2})

You might have used a 2d row vector where a 1d column vector was required.
Note the difference between 1d column vector [1,2,3] and 2d row vector [1 2 3].
You can convert to a column vector with the vec() function.

But if i use

@addNLConstraint(m, sum{x[i]*vec(f[i,fma]), i=1:length(Xvar)} >= 1)

JuMP returns

ERROR: Unrecognized function vec

@mlubin
Copy link
Member

mlubin commented Sep 19, 2014

What is the type of f[i,fma]? Is it a matrix?

@Ph0non
Copy link
Author

Ph0non commented Sep 19, 2014

julia> f[:,fma]
12x10 Array{Float64,2}

julia> f[1,fma]
1x10 Array{Float64,2}:
 1.0  10.0  11.1111  33.3333  0.166667  0.142857  0.5  0.5  0.333333  1.66667

julia> vec(f[1,fma])
10-element Array{Float64,1}:
  1.0     
 10.0     
 11.1111  
 33.3333  
  0.166667
  0.142857
  0.5     
  0.5     
  0.333333
  1.66667 

@mlubin
Copy link
Member

mlubin commented Sep 19, 2014

Yes, that isn't supported (and it's not clear what precisely it should mean).

@Ph0non
Copy link
Author

Ph0non commented Sep 19, 2014

"(and it's not clear what precisely it should mean)"

Do you mean the function vec() or what i want to do?

@mlubin
Copy link
Member

mlubin commented Sep 19, 2014

I mean, what is the set of constraints that you would like to add, stated in terms of scalars?

@Ph0non
Copy link
Author

Ph0non commented Sep 19, 2014

Afte a lot of senseless writing i give SymPy another chance. I try it but can't give you without much more effort a set of constraints in terms of scalars with the matrices i use.

But with SymPy i can give you e.g. the a constraint (values are truncated, my laptop with julia has no internet access at the time of writing this):

julia> Y1[1,2,1]
PyObject (3.07*x[10] + 0.06*x[11] + 2.45*[x12] + 1.22*x[1] + 0.61*x[2] + 0.25*x[3]
 + 0.0006*x[4] + 0.0004*x[5] + 0.20*x[6] + 0.24*x[7] + 0.20*x[8] + 3.07*x[9]/(1*x[1]
 + 0.97*x[2] + 0.34*x[3])

This must be bigger than 1 and smaller than a predefined value. And so on for 287 more terms. All with lower and upper bound.

I can workaround with jprint and parse the strings to constraints manuelly, but this seems not to be a nice solution. Are there other ways the add this PyObject as a constraint to JuMP?

Edit: I try

@addNLConstraint(m, convert(Expr, Y1[1,2,1]) >= 1)
ERROR: Unrecognized function convert
@addNLConstraint(m, eval(convert(Expr, Y1[1,2,1])) >= 1)
ERROR: Unrecognized function eval

@mlubin
Copy link
Member

mlubin commented Sep 22, 2014

Hmm, it shouldn't be necessary to use a symbolic manipulation package like SymPy to generate the scalar constraints. If you could provide at least a mathematical expression for the constraints that you would like to add, then perhaps we can help with translating them into JuMP's syntax.

@Ph0non
Copy link
Author

Ph0non commented Sep 22, 2014

Thanks,
the matrix formula for the terms needed for the constraints:

for i=1:size(tday, 1)
     Y1[:,:,1] = X * f[:,fma] .* a[:,fma,i] .* C[:,1,i] ./ (X * effizienz_arr)[1]
     Y2[:,:,1] = X * f[:,fmb] .* a[:,fmb,i] .* C[:,2,i] ./ (X * effizienz_arr)[2]
end

In my example is size(tday,1) = 3.
X is a row vector with the variables (12).
f is a 12x11 array, but i need not the full array, so f[:,fma] is 12x10 and f[:,fmb] is 12x6.
a is a 6x11x3 array. a[:,fma,1] is so 6x10 and a[:fmb,1] is 6x6.
C is a 6x2x3 array. C[:,1,1] so a 6-element row vector and C[:,2,1] too.
effizienz_arr is a 12x2 array.

Constant size is only 11 (respect 10 or 6) in f and a. The 2 in effizienz_arr is fixed too. All other sizes are dependent from problem.

All constraints must be greater equal than 1 und also smaller than some predefined upper bound (e.g. 1.8)

Edit: Abbreviate effizienz_arr with e I get full scalar terms like this: http://bit.ly/XKb3A6

Edit2: Got the scalar expressions :) Maybe there are some tips for better style.

for l=1:size(tday,1)
     for j=1:size(a,1)
          for k=1 in fma
               @addNLConstraint(m, C[j,1,l] * a[j,k,l] * sum{f[i,k] * x[i], i=1:length(Xvar)} / sum{effizienz_arr[i,1] * x[i], i=1:length(Xvar)} >= 1)
               @addNLConstraint(m, C[j,1,l] * a[j,k,l] * sum{f[i,k] * x[i], i=1:length(Xvar)} / sum{effizienz_arr[i,1] * x[i], i=1:length(Xvar)} <= ub)
          end
          for k in fmb
               @addNLConstraint(m, C[j,2,l] * a[j,k,l] * sum{f[i,k] * x[i], i=1:length(Xvar)} / sum{effizienz_arr[i,2] * x[i], i=1:length(Xvar)} >= 1)
               @addNLConstraint(m, C[j,2,l] * a[j,k,l] * sum{f[i,k] * x[i], i=1:length(Xvar)} / sum{effizienz_arr[i,2] * x[i], i=1:length(Xvar)} <= ub)
          end
     end
end

Edit3: In above equation must be an error. I have an excel sheet with some additional calculations (for sharing), where i didn't get the right results (values of the terms for the constraints).

Edit4: Error found and corrected in Edit2. for k=1:length(fma) -> for k in fma and so for fmb

runtime from 90s down to 2s 🎉

@Ph0non Ph0non closed this as completed Sep 23, 2014
@Ph0non
Copy link
Author

Ph0non commented Sep 24, 2014

@mlubin After some sleep i can frame my thoughts better. You have asked what the matrix calculations mean respectively what i want to do.

I have a lot of constraint with the same comparison and rhs. So i thought it would be nice if every element in an array could represent the lhs of a set of constraints. If X is an array of variables than is Y1 (Y2) an array of lhs of constraints.

for i=1:size(tday, 1)
     Y1[:,:,1] = X * f[:,fma] .* a[:,fma,i] .* C[:,1,i] ./ (X * effizienz_arr)[1]
     Y2[:,:,1] = X * f[:,fmb] .* a[:,fmb,i] .* C[:,2,i] ./ (X * effizienz_arr)[2]
end

So for a lot of constraints with the same comparison operator and rhs i could use something like (only idea) @addNLConstraint(m, Y1 .<= 1).

I hope the idea behind my question is now slightly clearer.

@mlubin
Copy link
Member

mlubin commented Sep 25, 2014

Yes, this is technically possible but likely won't be implemented in the short term.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants