Support for pow() with decision variables in MiniZinc - minizinc

I am trying to build a model with a decision variable that takes the range 0..10 with the constraint
that it must be divisible by 4.The output must be the one that minimizes the value (x-7)^2. Investigating I see that Gecode already supports it.
I have tried to build the model as follows but I get an error using the built-in pow()
% Decision variable
var 0..10: x;
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
int: obj = pow(x-7, 2);
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
I get the following error:
MiniZinc: type error: initialisation value for `obj' has invalid type-inst: expected `int', actual `var int'
I think it occurs because is considering the variable as a decision variable instead of just an integer parameter.

#hankank's solution is correct. Using var int: obj = pow(x-7, 2);
Variables (e.g., var int) in MiniZinc are decision variables and other names (which you might call variables in Python) are referred to as parameters (e.g., par int or int). These are two distinct types for a good reason: any calculation with only parameter is guaranteed to be able to be executed during MiniZinc compilation, while any calculation that uses a variable will generally have to be decided by a solver.
Note, that using pow actually might also bring problems for linear solver (i.e., MIP solvers). In this case the calculation can still be made linear because the transformation is using a constant, but the expression pow(x,y) where both arguments are variables could not be decided by a linear solver.

To move the pow() call from solution time to compilation time, you could use a pre-calculated array:
% Decision variable
var 0..10: x;
set of int: DomainX = 0..10;
array[DomainX] of int: xa = array1d(DomainX, [pow(i-7, 2) | i in DomainX]);
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
var int: obj = xa[x];
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
As commented by hakank, variable obj must be of type var int, as it depends on a decision variable.

Related

Assign a single element of a nettype struct

The usual assignment style to a Systemverilog net defined by a typedef struct, like
typedef struct {
real V;
real I;
real R;
} SVAstruct;
// resolution function ommitted
nettype SVAstruct SVAnet with res_SVA;
is
inout SVAnet P;
assign P = '{Vout,0,0};
So the assignments are done simultaneously for all elements of the net structure. Assignments like
P.R = 100;
give an error. Is there any method to do individual assignments?
You cannot do that. Once you create a nettype with a particular data type, each driver needs all fields of type in order to execute its resolution function.
Imagine if you wanted a signal to represent the force on an physical object. A force is a vector quantity that has both magnitude and direction. If each driver on that signal represents a force vector, there is no way to drive a direction without knowing what the magnitude is.
You can create a variable with the same type as a net and then you can make individual assignments to fields of that variable.
inout SVAnet P;
...
SVAstruct S
assign P = S;
...
S.R = 100;

Confused about behaviour of remainder operator in Swift

I am trying to calculate two random numbers constrained to a particular range using arc4random and the % operator.
I am not able to figure out why the compiler is complaining when calculating (x1,y1) when almost the same thing is done for x2,y2 except for using an int literal directly.
Any ideas?
The code sample is:
import Darwin
let w1:Int = 223
// error: Could not find an overload for '%' that accepts the supplied arguments
let (x1,y1) =
(
arc4random() % w1,
arc4random() % 345
)
let (x2,y2) =
(
arc4random() % 223,
arc4random() % 345
)
That's due to Swift's enforcement of type safety.
arc4random() returns a UInt32, while you've declared w as an Int, so a compiler error is thrown. That'd also happen if you had tried to sum or divide w and the result of calling arc4random(), so the behaviour is not exclusive to the remainder operator.
You have a few options, depending on how you intend to use the resulting value of the operation.
You can declare w1 as an UInt32 in the first place:
var w1: UInt32 = 223
Or, you can cast it to an UInt32 before performing the remainder operation:
arc4random() % UInt32(w1)
Finally, you can initialize an Int from the result of the arc4random() call and use it with the Int version of w1
Int(arc4random()) % w1
Note that this behaviour does not apply to literals.
From the Apple provided iBook:
The rules for combining numeric constants and variables are different
from the rules for numeric literals. The literal value 3 can be added
directly to the literal value 0.14159, because number literals do not
have an explicit type in and of themselves. Their type is inferred
only at the point that they are evaluated by the compiler.
That's why you don't see the same problem occur when doing arc4random() % 345.
You need to use the same type for both variables, to wit:
let w1:UInt32 = 223
Should solve the problem
The error is because you are trying to use an Int and a UInt32

Why does MATLAB throw a "too many output arguments" error when I overload subsref (subscripted reference)?

As a toy example, I have a class that simply wraps a vector or matrix in an object and includes a timestamp of when it was created. I'm trying to overload subsref so that
() referencing works exactly as it does with the standard vector and matrix types
{} referencing works in exactly the same way as () referencing (nothing to do with cells in other words)
. referencing allows me to access the private properties of the object and other fields that aren't technically properties.
Code:
classdef TimeStampValue
properties (Access = private)
time;
values;
end
methods
%% Constructor
function x = TimeStampValue(values)
x.time = now();
x.values = values;
end
%% Subscripted reference
function x = subsref(B, S)
switch S.type
case '()'
v = builtin('subsref', B.values, S);
x = TimeStampValue(v);
case '{}'
S.type = '()';
v = builtin('subsref', B.values, S);
x = TimeStampValue(v);
case '.'
switch S.subs
case 'time'
x = B.time;
case 'values'
x = B.values;
case 'datestr'
x = datestr(B.time);
end
end
end
function disp(x)
fprintf('\t%d\n', x.time)
disp(x.values)
end
end
end
However brace {} referencing doesn't work. I run this code
clear all
x = TimeStampValue(magic(3));
x{1:2}
and I get this error:
Error using TimeStampValue/subsref
Too many output arguments.
Error in main (line 3)
x{1:2}
MException.last gives me this info:
identifier: 'MATLAB:maxlhs'
message: 'Too many output arguments.'
cause: {0x1 cell}
stack: [1x1 struct]
which isn't helpful because the only thing in the exception stack is the file containing three lines of code that I ran above.
I placed a breakpoint on the first line of the switch statement in subsref but MATLAB never reaches it.
Whats the deal here? Both () and . referencing work as you would expect, so why doesn't {} referencing work?
When overloading the curly braces {} to return a different number of output arguments than usual, it is also necessary to overload numel to return the intended number (1, in this case). UPDATE: As of R2015b, the new function numArgumentsFromSubscript was created to be overloaded instead of numel. The issue remains the same, but this function should be overloaded instead of numel as I describe in the original answer below. See also the page "Modify nargout and nargin for Indexing Methods". Excerpt:
When a class overloads numArgumentsFromSubscript, MATLAB calls this method instead of numel to compute the number of arguments expected for subsref nargout and subsasgn nargin.
If classes do not overload numArgumentsFromSubscript, MATLAB calls numel to compute the values of nargout or nargin.
More explanation of the underlying issue (need to specify number of output arguments) follows.
Original answer (use numArgumentsFromSubscript instead of numel for R2015b+)
To handle the possibility of a comma separated list of output arguments when indexing with curly braces, MATLAB calls numel to determine the number of output arguments from the size of the input indexes (according to this MathWorks answer). If the number of output arguments in the definition of overloaded subsref is inconsistent with (i.e. less than) the number provided by numel, you get the "Too many output arguments" error. As stated by MathWorks:
Therefore, to allow curly brace indexing into your object while returning a number of arguments INCONSISTENT with the size of the input, you will need to overload the NUMEL function inside your class directory.
Since x{1:2} normally provides two outputs (X{1},X{2}), the definition function x = subsref(B, S) is incompatible for this input. The solution is to include in the class a simple numel method to overload the builtin function, as follows:
function n = numel(varargin)
n = 1;
end
Now the {} indexing works as intended, mimicking ():
>> clear all % needed to reset the class definition
>> x = TimeStampValue(magic(3));
>> x(1:2)
ans =
7.355996e+05
8 3
>> x{1:2}
ans =
7.355996e+05
8 3
However, overloading curly braces in this manner is apparently a "specific type of code that we [MathWorks] did not expect customers to be writing". MathWorks recommends:
If you are designing your class to output only one argument, it is not recommended that you use curly brace indexing that requires you to overload NUMEL. Instead, it is recommended you use smooth brace () indexing.
UPDATE: Interestingly, the R2015b release notes state:
Before MATLAB release R2015b, MATLAB incorrectly computed the number of arguments expected for outputs from subsref and inputs to subsasgn for some indexing expressions that return or assign to a comma-separated list.
With release R2015b, MATLAB correctly computes the values of nargout and nargin according to the number of arguments required by the indexing expression.
So perhaps this is now fixed?
An alternative solution that comes to mind is to change function x = subsref(B, S) to function varargout = subsref(B, S) and adding varargout=cell(1,numel(B)); varargout{1} = x;. As Amro noted in comments, pre-allocating the cell is necessary to avoid an error about an unassigned argument.
I just ran into the same problem. What's even worse, is that the number of output arguments is enforced to be equal to what numel() returns not only for the curly braces {}, but also for the dot . operation.
This means that if numel() is overridden to return the usual prod(size(obj)), it becomes impossible to access any properties of the underlying object (such as x.time in the above example), as subsref() is then expected to return multiple outputs.
But if numel() just returns 1 instead, it does not match prod(size(obj)), which is what most code working with numeric values or based on reshape() expects. In fact, the MATLAB editor's balloon help immediately suggests that 'NUMEL(x) is usually faster than PROD(SIZE(x))', which suggest that they are equivalent, but apparently are not.
A possible solution would be to make numel() return prod(size(obj)) and write explicit getter/setter functions for all these properties, e.g.,
x.get_time()
in the example above. This seems to work, because method calls apparently get resolved before subsref() gets called. But then if one of the properties is a matrix it cannot be directly indexed any more because Matlab doesn't understand chained indexing, i.e., instead of writing
x.matrix(1,:)
one would have to write
m = x.get_matrix();
m(1,:)
which is ugly to say the least.
This is starting to get a bit frustrating. I still hope I've just overlooked something obvious, I can't believe that this is how it's supposed to work.
This solution seems to work in 2014b (but not entirely certain why)
classdef TestClass < handle
methods
function n = numel(~,varargin)
n = 1;
end
function varargout = subsref(input,S)
varargout = builtin('subsref',input,S);
end
function out = twoOutputs(~)
out = {}; out{1} = 2; out{2} = 3;
end
end
end
Then via the command window
>> testClass = TestClass();
>> [a,b] = testClass.twoOutouts()
a =
2
b =
3
I am working on a class to handle polynomials and polynomial matrices. I was having the same dificulty because I want different behaviors for the '.' indexing in the cases of scalar polynomials and polynomial matrices.
In my case I want P.coef to return a vector of coefficients if P is a scalar polynomial. If P is a polynomial matrix, P.coef must return a cell array of the same size of P, in which the cell {i,j} contains the coefficient vector of the polynomial P(i,j).
The problem appeared when P.coef was used with a matrix. My desired behavior returns only one object as an answer, but Matlab is expecting the function to return numel(P) objects.
I found a very simple solution. When declaring subsref, I used one mandatory output and a varargout:
function [R,varargout] = subsref(P,S)
The body of the function defines R as needed, according to my design. And at the very end of the function I added:
varargout(1:nargout-1) = cell(1,nargout-1);
To just return empty matrices as the extra outputs that Matlab wants.
This should create no problem if the function is always called with a single output argument, e.g., as in R = P.coef. If the function is called without assigning, the user will see numel(P)-1 empty matrices, which is really not a big deal. Anyway, the user is warned about this in the function help.

fminsearch with vector inputs

I want to minimize this function:
function [GCV2]=GCV(y,x,k)
[n, p]=size(x);
A=(x'*x+k*eye(p));
A=A\x';
A=x*A;
I_mat=eye(n);
num2=(I_mat-A);
num2=num2*y;
num2=norm(num2);
num2=num2^2;
num2=num2/n;
%(norm((I_mat-A)*y)^2)/n;
den2=(I_mat-A);
den2=trace(den2);
den2=den2/n;
den2=den2^2;
GCV2=num2/den2;
end
The x and y values are 13-by-4) and 13-by-1 arrays, respectively, and these values are already defined in the Matlab workspace. I want to optimize on the k value so that the function value GCV is minimized.
The parameter being optimized as well as the output are scalar so fminsearch should be appropriate.
But I can't get it to run?
I've tried several methods, the latest being:
k_min = fminsearch(#GCV,(x;y;0));
??? k_min = fminsearch(#GCV,(x;y;0));
|
Error: Unbalanced or unexpected parenthesis or bracket.
What am I doing wrong?
Looks like you're learning about anonymous functions. fminsearch minimizes a single variable (which may be a vector). Your objective function must therefore have only one input. You have a function, GCV, that takes three inputs. Two are static and are defined in the workspace outside of the minimization, while k is the one to be minimized. To create a function with one input from GCV, you can use any anonymous function, taking care to specify which variables are parameters:
x = ...
y = ...
k0 = 0;
k_min = fminsearch(#(k)GCV(y,x,k),k0);
The second input to fminsearch is the starting parameter (i.e. k0), so specify a starting value of k. Then you can define an anonymous helper function and optimize on that:
>> % define x,y
>> GCVk = #(k) GCV(y,x,k);
>> k0 = 0;
>> k_min = fminsearch(GCVk,k0)
There is probably another way to do this, but this is one of the listed ways of passing additional parameters for the optimizer.
And since there are no bonus points for being first, how about humor. Let's have an example:
>> x=1; y=1;
>> GCVk = #(k) x+y+k; k0=0;
>> k_min = fminsearch(GCVk,k0)
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
Current function value: -316912650057057490000000000.000000
k_min =
-3.1691e+26
Found it - the lowest number (minus 2) in the world! Profit?

How to write a very long sum in a fitness function for global optimisation in Matlab

I a struggling writing a fully parametrised fitness function for the global optimisation toolbox in matlab.
Approach:
[x fvall,exitflag,output]=ga(fitnessfcn,nvars,A,b,Aeq,beq,lb,ub)
I have a fitness function that I call with
fitnessfcn=#fitnessTest;
hence, the function is stated in a separate file.
Problem:
My issue is now that my optimisation is a simple but super long sum like
cost=f1*x1+f2x2+...fnxn
n should be parameterised (384 at the moment). In all matlab help files, the objective function is always short and neat like
y = 100 * (x(1)^2 - x(2)) ^2 + (1 - x(1))^2;
I have tried several approaches "writing" the objective function intelligently, but then, I cannot call the function correctly:
if I write the fitness function manually (for fi=1)
function y = simple_fitness(x)
y = x(1)+ x(2)+ x(3)+ x(4)+ x(5)+ x(6)+ x(7)+ x(8);
the global optimisation works
But if I use my automated approach:
n = 8; %# number of function handles
parameters = 1:1:n;
store = cell(2,3);
for i=1:n
store{1,i} = sprintf('x(%i)',parameters(i));
store{2,i} = '+'; %# operator
end
%# combine such that we get
%# sin(t)+sin(t/2)+sin(t/4)
funStr = [store{1:end-1}];%# ignore last operator
endFunction=';';
%functionHandle = str2func(funStr)
y=strcat(funStr,endFunction)
matlab does not recognise the function properly:
error:
Subscripted assignment dimension mismatch.
Error in fcnvectorizer (line 14)
y(i,:) = feval(fun,(pop(i,:)));
thanks! I cannot write the objective function by hand as I will have several hundred variables.
You can use the sum(x) directly using function handle, instead of writing all indexes, do: fitnessfcn = #(x) sum(x).