What are these `float_div` and `float_times` constraints in the FlatZinc file? - minizinc

I just tried to run mzn2fzn over the following MiniZinc file:
var float: x1;
var float: y1;
var float: x2;
var float: y2;
constraint (x1 / y1) = 6.0;
constraint x2 * y2 <= 5.0;
solve satisfy;
This is the resulting FlatZinc file:
var -1.7976931348623157e+308..5.0: FLOAT____00001 :: is_defined_var :: var_is_introduced;
var float: x1;
var float: x2;
var float: y1;
var float: y2;
constraint float_div(x1, y1, 6.0);
constraint float_times(x2, y2, FLOAT____00001) :: defines_var(FLOAT____00001);
solve satisfy;
The version of mzn2fzn is as follows:
~$ mzn2fzn --version
G12 MiniZinc to FlatZinc converter, version 1.6.0
Copyright (C) 2006-2012 The University of Melbourne and NICTA
I have the following questions:
what is the float_div constraint, which does not seem to be mentioned by the FlatZinc 1.6 Standard?
what is the float_times constraint, which does not seem to be mentioned by the FlatZinc 1.6 Standard?
Does any FlatZinc solver actually support them?
N.B. I actually found trace of these functions in the docs for FlatZinc 2.2.0, however, I don't understand why these are generated by the version 1.6 of mzn2fzn when its documentation does not seem to mention either of them.

It seems to be oversight in the documentation of FlatZinc 1.6 that the constraints float_div and float_times are not documented. These constraints are necessary parts of the FlatZinc built-ins to be understood by solvers with support for floating point variables. They cannot be rewritten into other constraints that are among the FlatZinc builtins and that's why the compiler will use them. I would note that int_div and int_times are documented within the documentation of the old version of FlatZinc and the meaning of the constraints can be extrapolated from these constraints. (I'm also under the impression that their meaning has not changed in the conversion to FlatZinc 2.2.0)
Gecode, the CP solver shipped with MiniZinc, has support for these constraints.

Related

How to obtain an exact infinite-precision representation of rational numbers via a non-standard FlatZinc extension?

By default mzn2fzn automatically computes the result of a floating point division within a MiniZinc model, and stores it as a constant float value in the resulting FlatZinc model.
Example:
The file test.mzn
var float: x;
constraint 1.0 / 1000000000000000000000000000000000.0 <= x;
constraint x <= 2.0 / 1000000000000000000000000000000000.0;
solve satisfy;
translated with
mzn2fzn test.mzn
becomes equal to
var 1e-33..2e-33: x;
solve satisfy;
What we would like to obtain***, instead, is a FlatZinc file along the following lines:
var float: x;
var float: lb;
var float: ub;
constraint float_div(1.0, 1000000000000000000000000000000000.0, lb);
constraint float_div(2.0, 1000000000000000000000000000000000.0, ub);
solve satisfy;
where float_div() is a newly introduced, non-standard, FlatZinc constraint.
Is it possible to generate such an encoding of the original problem by using a variant of the std directory of constraints, or does this encoding require a more significant change of the source code of the mzn2fzn tool? In the latter case, could we have some guidance?
***: we have some formulas for which the finite-precision floating-point representation is unsuitable, because it changes a SAT result into UNSAT.
Currently there is no way of generating FlatZinc with infinite precision. Although the idea has been discussed a few times, it would require much of MiniZinc to be rewritten or appended using a library that could provide these infinite precise types. Libraries like these, such as the Boost interval library, seem to be lacking in options and do currently not compile for all machine targets on which MiniZinc is distributed. There seem to be various interesting cases for infinite precise types, but within the implementation of the MiniZinc compiler we are still looking for finding a decent way of implementing them.
Although infinite precision is not on the table. The MiniZinc compiler does intend to be correct according to the floating point standards. Feel free to report any problems that might occur to the MiniZinc Issue Tracker.

Absolute value of variable in CPLEX api for matlab

I am trying to solve a model on Matlab by using CPLEX. When the objective is
Maximize x1 + 2 x2 + 3 x3 + x4
Introducing cplex.Model.obj = [ 1; 2; 3; 1]; is enough.
What shall I do when the objective is
Maximize abs(x1) + 2 x2 + 3 x3 + x4
The short answer is that the CPLEX MATLAB API does not support an absolute value function "out of the box". So, as suggested in the comments, if you want to use the MATLAB API, you'll have to formulate it yourself. However, the C++, Java, and .NET Concert APIs do support abs (e.g., for the Java API see here). It is also supported in the docplex modeling API (see here).
The documentation for the CPLEX MATLAB API for version 12.8 (currently, the latest release) is here. I'm not sure if it will help make the documentation easier to use, but for me it is far easier to navigate if you click on the "Table of contents" link in the upper-left corner. This will allow you to expand the documentation tree and hop around easier. It is definitely worth looking at the examples that are shipped with CPLEX.

Need help on BDDs graphs

I am reimplementing (for fun, a bit of work and a severe case of NIH) a ROBDD library. I would like to have a few "reference" graphs built by other libraries to compare results [*]
E.g., given the variable order x1 < y1 < x2 < y2, what would be the graph obtained for
(x1 <=> y1) /\ not (x2 <=> y2) /\ (x2 <=> y2) [**]
I am assuming standard operators. Also, if it helps, I assume /\ is left-associative.
Any other smallish example will be welcome.
Thanks
Marco
[*] I know! I should download libraries, install them and use them, but I am lazy.
[**] The example is taken from a the Moeller and Oestergard's example that is floating around the net.
I am the author of BDD Scout - a tool for visualisation of BDDs. It works on MS Windows and GNU/Linux. It can show you a ROBDD with complemented edges for any Boolean function you entered. It supports also ROBDDs without complemented edges and 0-sup-BDDs (aka ZDDs introduced by Minato). It also allows you to reorder variables. You can download it from http://biddy.meolic.com/ . Your formula is equal to zero but, for example, below is a graph produced for Boolean function:
F = (x1*y1+!x1*!y1) * !(x2*y2+!x2*!y2)
EDIT: Please find below two PNG files generated with BDD Scout for Boolean function from Moeller and Oestergard's Bachelor's Thesis (page 9). Unfortunately, BDD Scout does not support <=> and thus the function must be specified as:
F = !( (!(x1^y1) * (x2^y2)) ^ !(x2^y2) )

not equal constraint for an array of var float decision variables in minizinc

I have a model that needs to constrain each element of a var float array to be alldifferent
I tried to use the global alldifferent global constraint but I get the following error:
MiniZinc: type error: no function or predicate with this signature found: `alldifferent(array[int] of var float)'
So I replaced the alldifferent constraint with the following comprehension:
constraint forall (i,j in 1..nVERTICIES where i<j) (X[i] != X[j]);
but now I get the following error when I use the Geocode solver:
Error: Registry: Constraint float_lin_ne not found
and the following error when I use the G12 MIP solver:
flatzinc: error: the built-in operation `float_lin_ne/3' is not supported by the MIP solver backend.
Is there a different way I can encode this constraint?
For your first problem: acording to the official documentation, MiniZinc does not support alldifferent float. Only ints are supported.
For your second problem and third problem: Your solvers does not seam to support floats. Maybe you are not using the letest solvers and/or latest MiniZinc?
Another better solution is to convert your float problem into a integer problem. Just map your floating point range to a integer range instead.
As some of the other responses have mentioned there's not (to my knowledge) an alldifferent for floats.
Your expression of this global constraint as a series of binary inequalities is a valid approach however the issue you are encountering is a reflection of the difficulty of determining whether two floats are different (which is a broader issue that isn't just limited to CP modelling).
One solution you could do is to compare the absolute difference between your variables and enforce that this must be greater than some configurable value.
int: nVERTICES = 10;
float: epsilon = 0.001; % the minimum floats need to be apart to be considered not equal.
array[1..nVERTICES] of var -10.0..10.0: X;
constraint forall (i, j in 1..nVERTICES where i < j) (abs(X[i] - X[j]) >= epsilon);
solve satisfy;
output [ show(X) ];
Notice also that I've set a domain on X rather than just declaring it as a float. I was experiencing as an Gecode: Float::linear: Number out of limits until I switched to specifying the domain explicitly.

Function returns different answers with same arguments

I'm transitioning from MATLAB to Fortran and encountering all sorts of weird behaviors I'd never expect from MATLAB. Here's one that's got me puzzled:
Program pruebanormal
double precision :: g01eaf, x, y
character :: T*1
integer :: Iffail
Iffail = 0
T = 'L'
x = 0.0
y = g01eaf('L',0.0,Iffail)
write(*,*) 'y = ',y
end program pruebanormal
I have this fairly simple program in which I'm trying to find the pdf at x=0 of a standard N(0,1) variable (should be 0.5). g01eaf() is the NAG library function that does this for me. I'm using gfortran to compile.
Leaving the rest of the program unchanged, depending on how I write the arguments in g01eaf(), I get different answers:
a) g01eaf(T,x,Iffail)
b) g01eaf(T,0.0,Iffail)
c) g01eaf(T,x,0)
Now, under MATLAB, I would get the same (correct) answer either way: y = 0.500000. Under Fortran, however, I get:
a) y = 0.500000
b) y = 1.000000
c) Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0xB766C163
#1 0xB766C800
#2 0xB77763FF
#3 0x804982E in g01eafn_
ViolaciĆ³n de segmento (`core' generado)
I have no words for the answer in (b) and no clue what (c) even means.
The very quick answer for the "wrong result" is that in
y = g01eaf('L',0.0,Iffail)
you are passing a different type of real variable than in
double precision x
x = 0.0 ! x is still double precision.
y = g01eaf('L',x,Iffail)
The function g01eaf probably expects double precision: you should very carefully read NAG's documentation.
y = g01eaf('L', 0d0, Iffail)
Now to elaborate.
You don't want these problems to come about too often. You want to ensure an interface is available for the function call to g01eaf. Your compiler would then complain about passing a real of default kind to the function.
Assuming you have an up-to-date version of the library, you want to do something like
use nag_library, only : g01eaf, nag_wp
implicit none
integer Iffail
real(kind=nag_wp) y
y = g01eaf('L', 0._nag_wp, Iffail)
end
Again, see the documentation. Both for the library, and for meaning of modules, etc.
For older versions, one should still have a module available, but it may be called something different, and nag_wp may not be defined (meaning you must carefully choose kinds).
The module will also lead to a complaint that Iffail requires to be able to be set, so must be a variable, not 0. This explains (c).