What is the use of minizinc fix function? - minizinc

i see that fix documentation says:
http://www.minizinc.org/doc-lib/doc-builtins-reflect.html#Ifunction-dd-T-cl-fix-po-var-opt-dd-T-cl-x-pc
function array [$U] of $T: fix(array [$U] of var opt $T: x)
Check if the value of every element of the array x is fixedat this point in evaluation. If all are fixed, return an array of their values, otherwise abort.
I am thinking it can be used to coerce a var to a par.
Here is the code.
array [1..num] of var int: value ;
%% generate random numbers from 0..num-1, this should fix the value of the var "value" or so i think
constraint forall(i in index_set(value))(let {int:temp_value=discrete_distribution([1|i in index_set(value)]); } in value[i]=trace(show(temp_value)++"\n", temp_value));
%%% this i was expecting to work, as "value" elements are fixed above
array [1..num] of int:value__ =[ trace(show(fix(value[i])), fix(value[i])) | i in index_set(value)] ;
But i get:
MiniZinc: evaluation error:
with i = 1
in call 'trace'
in call 'fix'
expression is not fixed
My questions are:
1) I think i should expect this error as minizinc is not sequential execution language?
2) Examples of fix in user guide is only where output statement is used. Is it the only place to use fix?
3) How would i coerce a var to a par?
By the way I am trying this var to par conversion because i am having problem with array generator expression. Here is the code
int:num__=200;
int:seed=134;
int: two_m=2097184;
%% prepare weights for generating numbers form 1..(two_m div 64), basically same weight
array [1..(two_m div 64)] of int: value_6_wt= [seed+1 | i in 1..(two_m div 64)] ;
%% generate numbers. this dose not work gives out
%% in variable declaration for 'value6'
%% parameter value out of range
array [1..num__] of int : value6 = [ discrete_distribution(value_6_wt) | j in 1..num__];

In the MiniZinc language the difference between a parameter and a variable is only the fact that a parameter must have a value at compile time. Within the compiler we turn as many variables into parameters as we can. This saves the solver from having to do some work. When we know that a variable has been turned into a parameter, then we can use the fix function to convince the type system that we really can use this variable as a parameter and see its value.
The problem here however is that fix is defined to abort when the variable is not fixed to one value. If no testing is done, this requires some (magic/)knowledge about the compilation process. In your case it seems that the second array is evaluated before the optimisation stage, in which all aliasing is resolved. This is the reason why it does not work. (This is indeed one of the things that is a consequence of a declarative language)
Although fix might only be used in the output statements in the examples (where it's guaranteed to work), it is used in many locations in the MiniZinc libraries. If we for example look at the library that is used for MIP solvers, there are many constraints that can be encoded more efficiently if one of the arguments is a parameter. Therefore, you will often see that the a constraint in this library first tests its arguments with is_fixed, and then use a better encoding if this returns true.
The output statement and when is_fixed returns true will both give the guarantee that a variable is fixed and ensure that the compilation doesn't abort. There is no other way to coerce a variable to a parameter, but unless you are dealing with dependant predicate definitions, you can just trust the MiniZinc compiler to ensure that the resulting FlatZinc will contain a parameter instead of a variable.

Related

kdb - checking dictionary variables for data vs. lambdas

All,
I have numerous nested dictionaries that I've been building and updating on the fly which can be combination of variables and lambdas functions. My initial inputs are constants and incremental data varies but are mostly derivatives using lambdas and function references.
I keep running a type issues as I pass constants and lambdas into my functions and my functions break. The solution at present is to simply wrap all my constants and data as simple f(x)s but I'd like to handle that inside my functions instead of wrapping everything.
In my example below, I'd like to add a conditional or something to QAQC the variable so I can handle it inside each function.
.inv.1.startDate: 2022.10.10 is a constant then my function breaks at sd: d[`startDate][] (which make sense as its not a function) but will work if .inv.1.startDate: {2022.10.10}
I tried a conditional below but it fails as not all dictionary values are f(x) either.
sd: ?[(type d[`startDate]=100h;d[`startDate][];d[`startDate])] ; which doesn't seem to work either.
Example of incremental references to render an array of series of dates
.inv.1.startDate:2022.10.10; //<---- works as f(x) but not when a constant
.inv.1.duration: 155;
.inv.1.iDate:{dateArray[.inv;1]};
.inv.2.startDate: {last (.inv.1.iDate[])};
.inv.2.duration: 250;
.inv.2.iDate:{dateArray[.inv;2]};
.inv.3.startDate: {last (.inv.2.iDate[])};
.inv.3.duration: 95;
.inv.3.iDate:{dateArray[.inv;3]};
dateArray:{[seg;segNum];
d: seg[`$string segNum];
sd: d[`startDate][]; //this can be a constant or a f(x) depending on when its called)
days: d[`duration]; // this could be a constant or a f(x) as well
result: sd+ til days
};
//attempt to emply a conditional but fails due to data type
sd: ?[(type d[`startDate]=100h;d[`startDate][];d[`startDate])] ;
FWIW- this is an expansion upon
kdb - nested functions within nested dictionaries
It looks like you are using ? in cases where $ is more applicable https://code.kx.com/q/ref/cond/
Also there is an order of evaluation issue with:
type d[`startDate]=100h
https://code.kx.com/q4m3/4_Operators/#412-left-of-right-evaluation
What you want is:
(type d[`startDate])=100h
Or more cleanly:
100h = type d[`startDate]
An alternative is to wrap your processing in a try-catch:
sd:{#[x;`;x]}d`startDate;
but as I mentioned in an earlier comment, personally I think it would be cleaner to have the constants in a lambda, e.g. .inv.1.startDate:{2022.10.10}

When subclassing "double" with new properties in MATLAB, is there an easy way to access the data value?

Say I have a class subclassing double, and I want to add a string (Similar to the 'extendDouble' in the documentation). Is there an easy way to access the actual numeric value without the extra properties, particular for reassigning? Or if I want to change the value, will I have to recreate the value as a new member of the class with the new value and the same string?
e.g.
classdef myDouble < double
properties
string
end
methods
function obj = myDouble(s)
% Construct object (simplified)
obj.string = s;
end
end
end
----------
x = myDouble(2,'string')
x =
2 string
x = 3
x =
3 string
Short answer: NO. There is no easy way to access a single member of a class when the class contains more than one member. You'll always have to let MATLAB know which part of the class you want to manipulate.
You have multiple questions in your post but let's tackle the most interesting one first:
% you'd like to instanciate a new class this way (fine)
x = myDouble(2,'string')
x =
2 string
% then you'd like to easily refer to the only numeric part of your class
% for assignment => This can NEVER work in MATLAB.
x = 3
x =
3 string
This can never work in MATLAB because of how the interpreter works. Consider the following statements:
% direct assignment
(1) dummy = 3
% indexed assignments
(2) dummy(1) = 3
(3) dummy{1} = 3
(4) dummy.somefieldname = 3
You would like the simplicity of the first statement for assignment, but this is the one we cannot achieve. The statement 2, 3 and 4 are all possible with some fiddling with subasgn and subsref.
The main difference between (1) and [2,3,4] is this:
Direct assignment:
In MATLAB, when you execute a direct assignment to a simple variable name (without indexing with () or {} or a field name) like dummy=3, MATLAB does not check the type of dummy beforehand, in fact it does not even check whether the variable dummy exists at all. No, with this kind of assignment, MATLAB goes the quickest way, it immediately create a new variable dummy and assign it the type and value accordingly. If a variable dummy existed before, too bad for it, that one is lost forever (and a lot of MATLAB users have had their fingers bitten once or twice by this behavior actually as it is an easy mistake to overwrite a variable and MATLAB will not raise any warning or complaint)
Indexed assignments:
In all the other cases, something different happens. When you execute dummy(1)=3, you are not telling MATLAB "create a new dummy variable with that value", you are telling MATLAB, "find the existing dummy variable, find the existing subindex I am telling you, then assign the value to that specific subindex". MATLAB will happlily go on, if it finds everything it does the sub-assignment, or it might complains/error about any kind of misassignment (wrong index, type mismatch, indices length mismatch...).
To find the subindex, MATLAB will call the subassgn method of dummy. If dummy is a built-in class, the subassgn method is also built in and usually under the hood, if dummy is a custom class, then you can write your own subassgn and have full control on how MATLAB will treat the assignment. You can check for the type of the input and decide to apply to this field or another if it's more suitable. You can even do some range check and reject the assignment altogether if it is not suitable, or just assign a default value. You have full control, MATLAB will not force you to anything in your own subassgn.
The problem is, to trigger MATLAB to relinquish control and give the hand to your own subassgn, you have to use an indexed assignment (like [2,3 or 4] above). You cannot do that with type (1) assignment.
Other considerations: You also ask if you can change the numeric part of the class without creating a new object. The answer to that is no as well. This is because of the way value classes work in matlab. There could be a long explanation of what happens under the hood, but the best example is from the MATLAB example you referenced yourself. If we look at the class definition of ExtendDouble, then observe the custom subassgn method which will perform the change of numeric value, what happens there is:
obj = ExtendDouble(b,obj.DataString);
So even Mathworks, to change the numeric value of their extended double class, have to recreate a brand new one (with a new numeric value b, and transfering the old string value obj.DataString).

`alldifferent` method in MiniZinc

The following is the constraint I tried to implement in MiniZinc
constraint forall (t in trucks)
(all_different(c in customers where sequence[t,c] !=0) (sequence[t,c]));
that is, I want every row element to be different for the sequence matrix when the sequence value doesn't equal to 0.
and got the error
MiniZinc: type error: no function or predicate with this signature found: all_different(array[int] of var opt int)'.
As indicated by some other threads I've added include "alldifferent.mzn"; command, still showing that error.
This is part of assignment, sorry for not able to push all my code here, please let me know if there is any extra information needed.
To clearly understand what you are doing, you can write your expression in a different way:
all_different([sequence[t,c] | c in customers where sequence[c,t] != 0])
Note that this uses array comprehensions. These are great to express a lot of things, but if sequence is an array of variables then the number of variables in this comprehension is unknown. This is a big problem for many solvers. And is thus not supported by many of them.
It is at least impossible with the all_different predicate.
Your problem however is a well known one, thus a different predicate is available. You can express the same constraint in the following way:
for(t in trucks) (
alldifferent_except_0([sequence[c,t] | c in customers])
)

Cannot assign Maple function by directly using expression, only by referencing output

Why does this does not work for assigning a function:
F(t) := Matrix(matrixDE(A, t)[1])
While using a label to reference the output works:
Matrix(matrixDE(A, t)[1]) (1)
F1(t) := (1)
matrixDE(A, t)[1] (2)
F2(t) := Matrix((2))
It seems the indexing operation [1] is what poses the problem, but I don't understand the mechanic behind this.
I found this question but it did not make me any wiser...
Edit:
I ended up getting my desired effect using eval and :
F(x) := eval(Matrix(matrixDE(A, t)[1]), t = x)
The price to pay being that the argument of Fis named x instead of t.
The problem has nothing to with the indexing. The problem is exactly what you said in your title: You cannot (properly) assign a Maple function by directly using an (unevalauted) expression; rather, you must reference the output (or evaluation).
More specifically, it depends on the desired order of these two operations: evaluation of a parameterized expression and substitution of values for the parameter. If you want to first evaluate the expression with a symbolic parameter (your t in this case), then the command to use is unapply:
F:= unapply(Matrix(matrixDE(A, t)[1]), t);

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.