jump-dev / JuMP.jl

Modeling language for Mathematical Optimization (linear, mixed-integer, conic, semidefinite, nonlinear)
http://jump.dev/JuMP.jl/
Other
2.24k stars 396 forks source link

ERROR: no method matching isless #1242

Closed YDHsieh closed 6 years ago

YDHsieh commented 6 years ago

when I run the code below, I got an error

part of the Code:

    @NLexpression(mpc, af[i=1:T] , atan((z[5,i]+l*z[6,i])/z[4,i])-u[i]  ) 
    @NLexpression(mpc, ar[i=1:T] , atan((z[5,i]-l*z[6,i])/z[4,i]) )
    @NLexpression(mpc, acr[i=1:T], tan( asin((Fz^2-u[2,i]^2)^0.5/(mu*Fz))/C) /B )
    @NLexpression(mpc, Frymax[i=1:T], ((mu*Fz)^2-(u[2,i])^2)^0.5 )
    @NLexpression(mpc, Ffy[i=1:T] , mu*Fz*sin(C*atan(B*af[i])) )
    @NLexpression(mpc, Fry[i=1:T] , mu*Fz*sin(C*atan(B*ar[i])) )

    # Link state and control across the horizon    2017 drift cornering model
     for t = 1:T
        @addNLConstraint(mpc, z[1,t+1] == z[1,t] + dt*z[4,t]*cos(z[3,t])-dt*z[5,t]*sin(z[3,t]))
        @addNLConstraint(mpc, z[2,t+1] == z[2,t] + dt*z[4,t]*sin(z[3,t])+dt*z[5,t]*cos(z[3,t]))
        @addNLConstraint(mpc, z[3,t+1] == z[3,t] + dt*z[6] )
        @addNLConstraint(mpc, z[4,t+1] == z[4,t] + dt*(u[2,t]-Ffy[t]*sin(u[1,t])+M*z[5,t]*z[6,t])/M )
        @addNLConstraint(mpc, z[5,t+1] == z[5,t] + dt*(Fry[t]+Ffy[t]*cos(u[1,t])-M*z[4,t]*z[6,t])/M )
        @addNLConstraint(mpc, z[6,t+1] == z[6,t] + dt*(l*Ffy[t]*cos(u[1,t])-l*Fry[t])/Iz)

        if ar[t] > acr[t]
          @addNLConstraint(mpc, Fry[t] == -Frymax[t]*sign(ar[t]))
        end

        if z[4,t] == 0
          return af[t]=ar[t]=0
        end

     end

Then the error is:

ERROR: LoadError: MethodError: no method matching isless(::JuMP.NonlinearExpression, ::JuMP.NonlinearExpression)

After testing, I guess the problem may be

        if ar[t] > acr[t]
          @addNLConstraint(mpc, Fry[t] == -Frymax[t]*sign(ar[t]))
        end

NLexpression can't be compared with each other?? in this format?

How to deal with this problem? Please help, thanks

blegat commented 6 years ago

Which version of JuMP are you using (i.e. what is the output of Pkg.status("JuMP")) ? @addNLConstraint has been deprecated in favor of @NLconstraint. What are the types of ar[t] and acr[t] ? If they are NonlinearExpression, ar[t] > acr[t] doesn't make sense, what do you mean by this condition ?

YDHsieh commented 6 years ago

-JuMP 0.18.1
is the output of Pkg.status("JuMP") it will automatically change from @addNLConstraint to @NLconstraint , so won't cause any problem

ar[t] and acr[t] are both rad, and these two are correlated with state z or input u So,ar and acr should be NLexpression right?

Then at the same time I need to compare these two, how?

blegat commented 6 years ago

it will automatically change from @addnlconstraint to @nlconstraint , so won't cause any problem

No I just wanted to check that you were using the latest version.

What do you mean by rad ? What is eltype(ar) ? Why do you want to compare them and what does it mean for a nonlinear expression to be larger than another one ?

YDHsieh commented 6 years ago

ar and acr are angles(in rad). When the angle ar > act, the maximum force will be Fry[t] == -Frymax[t]*sign(ar[t]).

Then, why I set ar and acr to NLexpression because those are correlated with state z and input u. It's also the only reason why I set ar and acr in NLexpression, or I misunderstanding the nonlinear expression??

However I'm not with my computer so I can't try eltype(ar) now.

blegat commented 6 years ago

If I understand correctly, if the value of the decision variables are such that the value of ar[t] is larger than the value of acr[t], you want that Fry[t] == -Frymax[t]*sign(ar[t]). You can model that with ConditionalJuMP but I'm not sure it supports nonlinear expressions. cc @rdeits

mlubin commented 6 years ago

I misunderstanding the nonlinear expression??

Apparently so. JuMP passes a concrete problem with a fixed set of constraints to the solver. You cannot change the set of constraints based on the value of a decision variable. ifelse and integer variables could be useful, but this sounds like a challenging problem to model.

YDHsieh commented 6 years ago

If I understand correctly, if the value of the decision variables are such that the value of ar[t] is larger than the value of acr[t], you want that Fry[t] == -Frymax[t]*sign(ar[t]). You can model that with ConditionalJuMP but I'm not sure it supports nonlinear expressions.

Yes! That's what I want!

I try to use ConditionalJuMP, and got the same error: ERROR: LoadError: MethodError: no method matching isless(::JuMP.NonlinearExpression, ::JuMP.NonlinearExpression) It seems that it does not support nonlinear expressions.

Fy(ar) = mu Fz sin(C atan(Bar)) : |ar| <= acr = -Frymax*sign(ar) : |ar| > acr

The equation above is what I want to write in code.However ar, acr, Frymax, Fry are all NLexpression. How can I do??

rdeits commented 6 years ago

Sorry, there's currently no nonlinear constraint support in ConditionalJuMP. It may be possible to do that when I rewrite it for the exciting new JuMP API, but I can't make any promises.

blegat commented 6 years ago

Have you tried defining it as a user-defined function in which you have an if-else statement ?

mlubin commented 6 years ago

Have you tried defining it as a user-defined function in which you have an if-else statement ?

No need for that, ifelse works.

YDHsieh commented 6 years ago

No need for that, ifelse works.

What you mean "ifelse works"? Isn't it what I wrote: if ar[t] > acr[t]

@addNLConstraint(mpc, Fry[t] == -Frymax[t]*sign(ar[t]))

end `

or should be another format?

blegat commented 6 years ago

I think @mlubin means that the ifelse need to be inside the macro

mlubin commented 6 years ago

I mean that you may call ifelse() inside the macro:

help?> ifelse
search: ifelse

  ifelse(condition::Bool, x, y)

  Return x if condition is true, otherwise return y. This differs from ? or if in that it is an
  ordinary function, so all the arguments are evaluated first. In some cases, using ifelse instead of
  an if statement can eliminate the branch in generated code and provide higher performance in tight
  loops.

  julia> ifelse(1 > 2, 1, 2)
  2
YDHsieh commented 6 years ago

Thanks for help that I can use ifelse() inside the macro to solve my problem.

then, I encountered another problem

for i=1:T @addNLConstraint(mpc , Fry[i] == ifelse(af[i] <= acr[i], muFzsin(Catan(Baf[i])), -Frymax[i]*sign(af[i]) )) end

The error: ERROR: LoadError: Unrecognized function "sign" used in nonlinear expression.

I tried to find the solution but I only found that abs() will cause the same problem in nonlinear expression.

YDHsieh commented 6 years ago

I think ifelse() can replace sign() with additional constraint. so it's won't be a big problem for me,now.

Thanks a lot!

astuhlmacher commented 6 years ago

how can ifelse() replace sign() of a JuMP.variable? If we want the equivalent of sign(afi[i]) in the NLconstraint, how would that be done? Currently I have

signs = ifelse(afi[i]>=0,1,-1); @NLconstraint(m, Fry[i] == signs*....)

But I get the error:

LoadError: MethodError: no method matching isless(::JuMP.Variable, ::Int64) Closest candidates are: isless(::AbstractFloat, ::Real) at operators.jl:98 isless(::ForwardDiff.Dual{Tx,V,N} where N where V<:Real, ::Integer) where Tx at C:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\JuliaPro-0.6.4.1\pkgs-0.6.4.1\v 0.6\ForwardDiff\src\dual.jl:104 isless(::ForwardDiff.Dual{Tx,V,N} where N where V<:Real, ::Real) where Tx at C:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\JuliaPro-0.6.4.1\pkgs-0.6.4.1\v0.6 \ForwardDiff\src\dual.jl:104

odow commented 6 years ago

Hi @astuhlmacher , uou need to use the ifelse inside the JuMP @NLconstraint macro:

@NLconstraint(m, Fry[i] == ifelse(afi[i] >= 0, 1, -1) * ...)

The JuMP documentation contains a section on syntax that you may want to read.

In the future, please post questions like this in the Discourse forum. More people read those questions, and so it will be of more help to people with similar issues in the future.

Good luck using JuMP!