How to initialise a variable with a specific domain of numbers in MiniZinc? - minizinc

In MiniZinc, we initialise a domain of values using for example:
var 2..6: X;
However, if the values required are only [2, 4, 6] excluding 3 and 5, how does one initialise such a domain for the variable?

Use the set notation {...} to enumerate the valid domain, i.e. curly braces, not brackets.
var {2,4,6}: x;
Note: 2..6 is the same as (or rather a shorthand of) {2,3,4,5,6}.
This is discussed a little more in the MiniZinc Tutorial.

Related

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).

dot indexing not supported while using struct gets a different error

Ppl
I am trying to loop over a set of variables of a class and assigning a different value for each.
what I am saying is this
there is a calss def called T
I am accessing certain variables in T using dot indexing
classdef T
properties
wheels = 2.3;
now I am trying to do this
wheelV=[ 1 2 3];
for i=1:5
T.Wheels = wheelV(i);
end
However this will lead to the error "unable to assign value cause dot indexing is not supported for this variable type" Now I can use a struct in this means
T.wheels=struct('r',wheelV(i));
But this wont work as the variable T.Wheels will be used in another class where it needs to be multiplied and hence I get a different error that you can't multiply.
is there a way to index this T.Wheels without having to declare it as a struct.
Using Widnows 10, 64x
Matlab R2021b

What is the difference between curly braces and paranthesis

I have a couple of line of code which compares some values in two different matrices and even if it is true it doesn't enter the if part.
for i = 1:ux
for j = 1:SIR
if ShelfInfo{SIR, 2} == uniquexy(ux, 1) && uniquexy{ux, 2} == ShelfInfo{SIR, 3}
shelf = ShelfInfo{j,5};
shelves = [shelves; shelf];
1
end
end
end
This code is work but it doesn't enter the if part. I believe it is because of the braces. When I changed everything with curly braces I am receiving this error Brace indexing is not supported for variables of this type. When I am changing this braces with parentheses I am receiving this error Undefined operator '==' for input arguments of type 'table'.
I can't find what to do can you help me with it?
()-indexing subsets an array by elements, and works on any type of array.
{}-indexing subsets a cell array, and extracts the cells' contained values. Basically, it "reaches into" the cells and pulls out their contents. It only works on cell arrays, or objects that have overloaded subsref() to provide this behavior.
I'm guessing you're accidentally applying {}-indexing to your uniquexy in one of your references there, when both of them should be ()-indexing:
... uniquexy(ux, 1) && uniquexy{ux, 2} ...
Besides the indexing problem (which depends on the data type of your matrices and would be handy to give as a part of a minimal working example), in your if-statement you do not loop over your array elements. I assume you would want to use indices i and j, instead of SIR and ux (they indicate a fixed position in your arrays). So why do you need the if-statement inside two for-loops then?
May be check these links on accessing array elements depending on array types:
Basic array indexing
Cell vs. structure arrays
Tables

What is the use of minizinc fix function?

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.

What #{hash{$key}} mean in Perl?

Could someone tell me that what #{hash{$key}} means? and whether I was it right when I wrote #{hash{$key}}[$i]=$list[$i+1]?
#{hash{$key}}
is a weird way to write
#hash{$key}
This is called a hash slice. It allows you to fetch multiple values from a hash in one go. For example,
say for #hash{'a', 'b'};
means
say for $hash{a}, $hash{b};
So it's rather silly to use
#hash{$key}
instead of
$hash{$key}
#{hash{$key}}[$i]=$list[$i+1]; doesn't compile, so no, it wasn't correct to use it.
As ikegami explains, #{hash{$key}} is a hash slice (of only one element).
It is likely that you want this instead: #{$hash{$key}}. If each element of your hash is an array reference, this syntax would allow you to access the array.
For example, suppose your hash contained arrays, like this:
my %hash = (
foo => [1, 2, 3, 4, 5],
bar => [qw/baz sproing blargh/]
);
#{$hash{foo}} would be (1, 2, 3, 4, 5)
If that is the case, then this syntax would work:
${$hash{$key}}[$i]=$list[$i+1]
Note that you are only accessing an element of the array, not the whole array. Thus you use ${$hash{$key}} instead of #{$hash{$key}}.
Another way of doing the same thing is this:
$hash{$key}->[$i]=$list[$i+1]
The -> syntax for dereferencing is often preferable to ${...}, because it is cleaner, especially when you have a complex data structure.