Rational{Int64} variables in JuMP?

I’ve been trying to make an array of rationals using the @variable macro in JuMP, but I can’t seem to find out how to constrain the array to only rational values.

Does JuMP allow you to build variables with Rational type?
If so, how?
And if not, is there an alternative?

No. JuMP only supports Float64 variables (although you an constrain them to take binary or integer values).

By “variable with Rational type”, do you mean “variable x that should only take rational values” or “I want to pass data to the solver in Rational type”?

For the former, it is neither supported by JuMP nor by solvers in general.
The only exception are a handful of LP solvers, e.g., SoPlex (also see here) that can return exact solutions (using Rational arithmetic) to linear programming and quadratic programming problems. That functionality, however, is not available from Julia.
As @odow already hinted at, the only way to effectively enforce that a variable x takes rational values is through the use of integer variables. Either declare x as integer and divide it by a constant, or introduce two integer variables p, q and add the (non-linear and non-convex) constraint x = p / q.

For the latter, MathOptInterface.jl and Convex.jl both support arbitrary data types when building a model.

1 Like

Just to add in the particular case of doing stuff like going from hreps to vreps of a polyhedron, CDDLib can solve the problem exactly and is wrapped (https://github.com/JuliaPolyhedra/CDDLib.jl) and can be used via Polyhedra.jl. I just mention it since it’s the only case I know of that you can do easily from Julia.

Convex can use arbitrary numeric types in theory, but I wouldn’t be surprised if something goes wrong with rationals since it’s not tested and they aren’t very robust (eg with SDPs sqrt(2) scalings are used in the MOI codebase). Using Bigfloats is tested on the Convex side though.

1 Like

Do you know what’s the best solver to use when working with nonlinear constraints and integer variables?

Try: https://github.com/lanl-ansi/Juniper.jl

A better question to ask is why you require rational variables. Mixed-integer nonlinear programs are notoriously difficult to solve.

If you can use a common demoninator (e.g., 1000), then the problem is easy. Having an arbitrary denominator is going to be very difficult.

2 Likes

Thanks, unfortunately, the solution to the system I am solving must be presented as an exact rational fraction.

Technically Float64s are rational numbers, too :wink:

In case you are looking for “nice” rational numbers (with small denominators etc), you can try solving using floating point to get solution, from which you learn which constraints bind, then just solve the resulting simplified linear system using rationals.

1 Like