MiniZinc type error: all_different(array[int] of var int) not found - minizinc

I've created a model for a labeling problem I'm solving. Everything works great except that the 'all_different' predicate can't be found. The error arises in 'Constraints' (2) and (3), producing the following error log:
MiniZinc: type error: no function or predicate with this signature found: `all_different(array[int] of var int)'
I've tried both 'all_different' and 'alldifferent', and the key signature 'array[int] of var int' matches the documentation for 'all_different'. I have no other issues after commenting out the to constraints.
Any idea what could be wrong?
I'm using MiniZincIDE Version 0.9.8.
%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameter Definitions %
%%%%%%%%%%%%%%%%%%%%%%%%%
% Number of Solutions for Region
int: num_sols;
% Number of Adjacent Coordinates.
int: num_adj;
% Center Coordinate Name
string: center_name;
% Adjacent Coordinate Names.
array[1..num_adj] of string: adj_names;
% Center Coordinate Torsion Angles.
array[1..6] of float: center_tors;
% Adjacent Coordinate Torsion Angles.
array[1..num_adj,1..6] of float: adj_tors;
% Distances Between Solutions of Center and Adjacent Coordinates.
% [adj_coord,sol_num of adj_coord,sol_num of center_coord]
array[1..num_adj,1..num_sols,1..num_sols] of float: dists;
%%%%%%%%%%%%%%%%%%%%%%
% Decision Variables %
%%%%%%%%%%%%%%%%%%%%%%
%%% Symmetry Breaking %%%
% Layer Assignment for First Center Coordinate.
% array[1..num_sols] of int: center_layers = [i | i in 1..num_sols]
% Center Coordinate Layers
array[1..num_sols] of var int: center_layers;
% Center Coordinate Solution Assigned To Layers.
% (Inverse array of center_layers above)
array[1..num_sols] of var int: layers_center;
% Adjacent Coordinate Layers
% [adj_coord,sol_num] = layer_num
array[1..num_adj,1..num_sols] of var int: adj_layers;
% Adjacent Coorinate Solution Assigned To Layers.
% (Inverse array of layer_num above)
% [layer_num,adj_coord] = sol_num
array[1..num_sols,1..num_adj,] of var int: layers_adj;
% Distances Solutions Of the Same Layer.
% [layer_1,layer_2,..layer_3]
array[1..num_sols] of var float: layers_dists;
%%%%%%%%%%%%%%%%%%%%%%%
% Variable Assignment %
%%%%%%%%%%%%%%%%%%%%%%%
% (1) Match adj_layers and layers_adj
constraint forall(i in 1..num_adj, j in 1..num_sols)
(layers_adj[adj_layers[i,j],i] = j);
% (2) Match center_layers and layers_center
constraint forall(i in 1..num_sols)
(layers_center[center_layers[i]] = i);
% (3) For Each Layer, Sum The Distances Between Center Coordinate Solution and
% Adjacent Coordinates
constraint forall(i in 1..num_sols)
(layers_dists[i] = sum(j in 1..num_adj)
(dists[j, layers_adj[i,j], layers_center[i]])
);
%%%%%%%%%%%%%%%
% Constraints %
%%%%%%%%%%%%%%%
% (1) All Layers Must Be Within Layer Range
constraint forall(i in 1..num_sols)
(center_layers[i] <= num_sols /\ center_layers[i] >= 1);
constraint forall(i in 1..num_adj,j in 1..num_sols)
(adj_layers[i,j] <= num_sols /\ adj_layers[i,j] >= 1);
% (2) The Center Coordinate Solutions Must Have Unique Layers.
constraint all_different(center_layers);
% (3) For Each Adjacent Coordinate, The Solutions Must Have Unique Layers.
constraint forall(i in 1..num_adj) (all_different(row(adj_layers,i)));
%%%%%%%%%%%%%%%%%%%%%%
% Objective Function %
%%%%%%%%%%%%%%%%%%%%%%
solve minimize sum(layers_dists);

Add this to your model:
include "globals.mzn";
This includes the definitions for global constraints, such as all_different.
A tip: If possible you should avoid using "var int". Try instead to define appropriate domains for the decision variables. This will often speed up the model since the solvers don't have to deal will irrelevant domains.

Related

Implementing infinity like boundary condition for 1D diffusion equation solved with implicit finite difference method

I am using following MATLAB code for implementing 1D diffusion equation along a rod with implicit finite difference method. `
xsize = 10; % Model size, m
xnum = 10; % Number of nodes
xstp = xsize/(xnum-1); % Grid step
tnum = 504; % number of timesteps
kappa = 833.33; % Thermal diffusivity, m^2/s
dt = 300; % Timestep
x = 0:xstp:xsize; %Creating vector for nodal point positions
tlbc = sin(linspace(0.1,2.9,tnum)); % left boundary condition
%Define initial temperature profile
tback = 0; % background temperature, K
for i=1:1:xnum
% Background profile
t0imp(i) = tback; % profile for implicit solving
end
% Time cycle
timesum=0; % Elapsed time
for t=1:1:tnum
% Matrix of coefficients initialization for implicit solving
L = sparse(xnum,xnum);
% Vector of right part initialization for implicit solving
R = zeros(xnum,1);
% Implicit solving of 1D temperature equation: dT/dt=kappa*d2T/dx2
% Composing matrix of coefficients L()
% and vector (column) of right parts R()
% First point: T=tback
L(1,1) = 1;
R(1,1) = tlbc(t);
% Intermediate points
for i=2:1:xnum-1
% dT/dt=kappa*d2T/dx2
% Tnew(i)/dt-kappa*(Tnew(i-1)-2*Tnew(i)+Tnew(i+1))/dx^2=Told(i)/dt
L(i,i-1) = -kappa/xstp^2;
L(i,i) = 1/dt+2*kappa/xstp^2;
L(i,i+1) = -kappa/xstp^2;
R(i,1) = t0imp(i)/dt;
end
% Last point:T=tback
L(xnum,xnum) = 1;
R(xnum,1) = tback;
% Obtaining solution for implicit temperature profile
t1imp = L\R;
end `
I want to change right boundary condition to infinite boundary condition so that presence of boundary at 10 m has no effect on heat flow and temperature flows in 10 m domain as if there was no boundary at 10 m.
If you have localized phenomenon that is far away from the boundary then I suggest you use a non-uniform grid for your x-space discretization. The mesh should have more points in the region of interest. You can then choose a large xsize but keep the number of mesh points reasonable.
Non-uniform grids are trickier to implement (not that bad for 1-d) but fortunately Matlab has pdepe that solves non-uniform equations of the type
\begin{equation}
c\left(x , t,u, \frac{\partial u}{\partial x} \right) \frac{\partial u}{\partial t} = x^{-m} \frac{\partial}{\partial t} \left( x^m f\left(x , t,u, \frac{\partial u}{\partial x} \right)\right) + S\left(x , t,u, \frac{\partial u}{\partial x} \right)
\end{equation}
with user defined meshes. You can read more about pdepe here
https://www.mathworks.com/help/matlab/ref/pdepe.html
They also solve the equation you are interested in.

trying to implement knnclassify in matlab for fisheriris dataset

I am trying to implement knnclassify in matlab for fisheriris data set and try to get the confusion matrix for it. Below is the code for matlab implementation of knnclassify.
I am unable to understand how to incorporate the fisheriris datase in this code.
and how to calculate the confusion matrix.
function classifications = knnclassify(train_points, train_labels, test_points, k);
%-------------------------------------------
% K nearest neighbour (KNN) classification
% code by Jaakko Peltonen 2008
%-------------------------------------------
% Classifies test points based on majority vote of their k nearest
% neighbours in train points. 'Nearest' is determined from squared
% Euclidean distance. In case the majority voting results in a tie,
% gives equal portions to each class in the tie.
%
% Inputs:
%---------
% train_points: matrix, the i:th row has the features of the i:th
% training point.
%
% train_labels: two possible formats.
% Format 1: a column vector where the i:th element is an integer
% value indicating the label of the i:th training
% point. The labels should start from zero.
%
% Format 2: a matrix where the i:th row has the class memberships
% of the i:th training point. Each class membership is
% a value from 0 to 1, where 1 means the point fully
% belongs to that class.
%
% test_points: feature matrix for test points. Same format as
% train_points. You can give an empty matrix: then the method
% computes leave-one-out classification error based only on
% the training points.
%
% Outputs:
%---------
% classifications: matrix, the i:th row has the predicted class
% memberships of the i:th test point. Each class
% membership if a value from 0 to 1, where 1 means
% the test point is predicted to fully belong to
% that class.
%
nDim = size(test_points,2);
nTrainPoints = size(train_points,1);
% if the training labels were provided in format 1,
% convert them to format 2.
if size(train_labels,2)==1,
nClasses = max(train_labels)+1;
train_labels2 = zeros(nTrainPoints,nClasses);
for i=1:nTrainPoints,
train_labels2(i,train_labels(i)+1) = 1;
end;
train_labels = train_labels2;
end;
nClasses = size(train_labels,2);
% if test_points is empty, perform leave-one-out classification
if isempty(test_points),
test_points = train_points;
leave_one_out = 1;
else
leave_one_out = 0;
end;
nTestPoints = size(test_points,1);
%
% Perform the KNN classification. For leave-one-out classification,
% this code assumes that k < nTrainPoints.
%
classifications = zeros(nTestPoints, nClasses);
for i=1:nTestPoints,
% find squared Euclidean distances to all training points
difference = train_points(:,1:nDim) - repmat(test_points(i,:),[nTrainPoints 1]);
distances = sum(difference.^2,2);
% in leave-one-out classification, make sure the point being
% classified is not chosen among the k neighbors.
if leave_one_out == 1,
distances(i) = inf;
end;
% collect the 'votes' of the k closest points
[sorted_distances, indices] = sort(distances);
classamounts = zeros(1, nClasses);
for j=1:k,
classamounts = classamounts + train_labels(indices(j),:);
end;
% choose the class by majority vote
indices = find(classamounts == max(classamounts));
if (length(indices) == 1),
% there is a single winner
classifications(i,indices(1)) = 1;
else
% there was a tie between two or more classes
classifications(i,indices) = 1/length(indices);
end;
end;
Answer for the first question:
You first need to fix small bug in the function:
Change
difference = train_points(:,1:nDim) - repmat...
to
difference = train_points - repmat...
Than the script to run this classifier on fisheriris:
clear
data=load('fisheriris');
[~,~,ci]=unique(data.species);
data.labels=ci-1; % start from 0
portion_to_test=40/100;
n=size(data.species,1);% #samples
test_idx=randperm(n,round(n*portion_to_test));
train_idx=setdiff(1:n,test_idx);
train_meas=data.meas(train_idx,:);
train_labels=data.labels(train_idx);
test_meas=data.meas(test_idx,:);
test_labels=data.labels(test_idx);
result=knnclassify(train_meas,train_labels,test_meas,1);
[~,mi]=max(result,[],2);
result_labels=mi-1; % start from 0;
error=sum(result_labels~=test_labels)/length(test_labels)

Matlab Random Number with Condition [duplicate]

This question already has answers here:
Random numbers that add to 100: Matlab
(4 answers)
Closed 7 years ago.
I am looking how to pick 10 positive non-zero elements in 1x10 array randomly whose sum is 1
Example :
A=[0.0973 0.1071 0.0983 0.0933 0.1110 0.0942 0.1062 0.0970 0.0981 0.0974]
Note: If we sum the elements in above matrix it will be 1. I need matlab to generate a matrix like this randomly
Try using Roger's fex submission: http://www.mathworks.com/matlabcentral/fileexchange/9700-random-vectors-with-fixed-sum
Here is a copy of the content of the file (in case the link dies).
All the credit obviously goes to the original poster Roger Stafford:
function [x,v] = randfixedsum(n,m,s,a,b)
% [x,v] = randfixedsum(n,m,s,a,b)
%
% This generates an n by m array x, each of whose m columns
% contains n random values lying in the interval [a,b], but
% subject to the condition that their sum be equal to s. The
% scalar value s must accordingly satisfy n*a <= s <= n*b. The
% distribution of values is uniform in the sense that it has the
% conditional probability distribution of a uniform distribution
% over the whole n-cube, given that the sum of the x's is s.
%
% The scalar v, if requested, returns with the total
% n-1 dimensional volume (content) of the subset satisfying
% this condition. Consequently if v, considered as a function
% of s and divided by sqrt(n), is integrated with respect to s
% from s = a to s = b, the result would necessarily be the
% n-dimensional volume of the whole cube, namely (b-a)^n.
%
% This algorithm does no "rejecting" on the sets of x's it
% obtains. It is designed to generate only those that satisfy all
% the above conditions and to do so with a uniform distribution.
% It accomplishes this by decomposing the space of all possible x
% sets (columns) into n-1 dimensional simplexes. (Line segments,
% triangles, and tetrahedra, are one-, two-, and three-dimensional
% examples of simplexes, respectively.) It makes use of three
% different sets of 'rand' variables, one to locate values
% uniformly within each type of simplex, another to randomly
% select representatives of each different type of simplex in
% proportion to their volume, and a third to perform random
% permutations to provide an even distribution of simplex choices
% among like types. For example, with n equal to 3 and s set at,
% say, 40% of the way from a towards b, there will be 2 different
% types of simplex, in this case triangles, each with its own
% area, and 6 different versions of each from permutations, for
% a total of 12 triangles, and these all fit together to form a
% particular planar non-regular hexagon in 3 dimensions, with v
% returned set equal to the hexagon's area.
%
% Roger Stafford - Jan. 19, 2006
% Check the arguments.
if (m~=round(m))|(n~=round(n))|(m<0)|(n<1)
error('n must be a whole number and m a non-negative integer.')
elseif (s<n*a)|(s>n*b)|(a>=b)
error('Inequalities n*a <= s <= n*b and a < b must hold.')
end
% Rescale to a unit cube: 0 <= x(i) <= 1
s = (s-n*a)/(b-a);
% Construct the transition probability table, t.
% t(i,j) will be utilized only in the region where j <= i + 1.
k = max(min(floor(s),n-1),0); % Must have 0 <= k <= n-1
s = max(min(s,k+1),k); % Must have k <= s <= k+1
s1 = s - [k:-1:k-n+1]; % s1 & s2 will never be negative
s2 = [k+n:-1:k+1] - s;
w = zeros(n,n+1); w(1,2) = realmax; % Scale for full 'double' range
t = zeros(n-1,n);
tiny = 2^(-1074); % The smallest positive matlab 'double' no.
for i = 2:n
tmp1 = w(i-1,2:i+1).*s1(1:i)/i;
tmp2 = w(i-1,1:i).*s2(n-i+1:n)/i;
w(i,2:i+1) = tmp1 + tmp2;
tmp3 = w(i,2:i+1) + tiny; % In case tmp1 & tmp2 are both 0,
tmp4 = (s2(n-i+1:n) > s1(1:i)); % then t is 0 on left & 1 on right
t(i-1,1:i) = (tmp2./tmp3).*tmp4 + (1-tmp1./tmp3).*(~tmp4);
end
% Derive the polytope volume v from the appropriate
% element in the bottom row of w.
v = n^(3/2)*(w(n,k+2)/realmax)*(b-a)^(n-1);
% Now compute the matrix x.
x = zeros(n,m);
if m == 0, return, end % If m is zero, quit with x = []
rt = rand(n-1,m); % For random selection of simplex type
rs = rand(n-1,m); % For random location within a simplex
s = repmat(s,1,m);
j = repmat(k+1,1,m); % For indexing in the t table
sm = zeros(1,m); pr = ones(1,m); % Start with sum zero & product 1
for i = n-1:-1:1 % Work backwards in the t table
e = (rt(n-i,:)<=t(i,j)); % Use rt to choose a transition
sx = rs(n-i,:).^(1/i); % Use rs to compute next simplex coord.
sm = sm + (1-sx).*pr.*s/(i+1); % Update sum
pr = sx.*pr; % Update product
x(n-i,:) = sm + pr.*e; % Calculate x using simplex coords.
s = s - e; j = j - e; % Transition adjustment
end
x(n,:) = sm + pr.*s; % Compute the last x
% Randomly permute the order in the columns of x and rescale.
rp = rand(n,m); % Use rp to carry out a matrix 'randperm'
[ig,p] = sort(rp); % The values placed in ig are ignored
x = (b-a)*x(p+repmat([0:n:n*(m-1)],n,1))+a; % Permute & rescale x
return

Planar Data Fit - Estimate Z given X and Y

I'm attempting to create a fit plane in order to predict a Z value given an X and Y. I've used the following code (Best fit plane for 3D data), but the predicted Z values are dramatically incorrect, and frankly don't make a ton of sense. The plane is populated with known X, Y, Z values. The final line then estimates a Z value for every original X and Y that in no way correspond to the actual Z values. The estimated Z values are included bellow, while the actual Z values (see code) stick between 30 and 40 in general.
ESTIMATED VALUES (way off):
ZHat = 129.6104 \ -45.8558 \ 157.4270 \ 79.9675 \ 185.5349 \ 56.1384 \ -6.7733 \ 29.1776 \ -4.7795 \ 59.1381 \ -0.7739 \ 95.5122 \ 38.3086 \ 2.0756 \ -58.7012 \ 76.5445 \ -111.0525 \ -44.5676 \ 29.8922 \ 38.1766
CODE:
X = [34.5,32.8,35.4,33.4,33.2,36.1,35.8,35.3,37.6,34.1,31.8,36,34.8,33.7,36,33,33.8,30.6,34.6,29.3];
Y = [33.5,35.9,33.2,34.1,32.5,34.8,35.7,35.1,35.9,34.5,35.1,34.2,34.9,35.3,36.5,34.1,37,35.6,35,34.2];
Z = [41,39,34,35,30,46,41,43,31,42,31,39,24,32,35,26,29,34,39,34];
% First, remove NaNs. All the NaN (if any) will be in the same places,
% so we need do only one test. Testing each of X,Y,Z leads to confusion
% and leads to the expectation that the NaNs are NOT in the same places
% with some potential.
k = isfinite(X);
if all(k(:))
% in this case there were no nans, so reshape the arrays into vectors
% While X(k) would convert an array into a column vector anyway in
% this case, it seems far more sane to do the reshape explicitly,
% rather than let X(k) do it implicitly. Again, a source of ambiguity
% removed.
X = X(:);
Y = Y(:);
Z = Z(:);
else
X = X(k);
Y = Y(k);
Z = Z(k);
end
% Combine X,Y,Z into one array
XYZ = [X,Y,Z];
% column means. This will allow us to do the fit properly with no
% constant term needed. It is necessary to do it this way, as
% otherwise the fit would not be properly scale independent
cm = mean(XYZ,1);
% subtract off the column means
XYZ0 = bsxfun(#minus,XYZ,cm);
% The "regression" as a planar fit is now accomplished by SVD.
% This presumes errors in all three variables. In fact, it makes
% presumptions that the noise variance is the same for all the
% variables. Be very careful, as this fact is built into the model.
% If your goal is merely to fit z(x,y), where x and y were known
% and only z had errors in it, then this is the wrong way
% to do the fit.
[U,S,V] = svd(XYZ0,0);
% The singular values are ordered in decreasing order for svd.
% The vector corresponding to the zero singular value tells us
% the direction of the normal vector to the plane. Note that if
% your data actually fell on a straight line, this will be a problem
% as then there are two vectors normal to your data, so no plane fit.
% LOOK at the values on the diagonal of S. If the last one is NOT
% essentially small compared to the others, then you have a problem
% here. (If it is numerically zero, then the points fell exactly in
% a plane, with no noise.)
diag(S);
% Assuming that S(3,3) was small compared to S(1,1), AND that S(2,2)
% is significantly larger than S(3,3), then we are ok to proceed.
% See that if the second and third singular values are roughly equal,
% this would indicate a points on a line, not a plane.
% You do need to check these numbers, as they will be indicative of a
% potential problem.
% Finally, the magnitude of S(3,3) would be a measure of the noise
% in your regression. It is a measure of the deviations from your
% fitted plane.
% The normal vector is given by the third singular vector, so the
% third (well, last in general) column of V. I'll call the normal
% vector P to be consistent with the question notation.
P = V(:,3);
% The equation of the plane for ANY point on the plane [x,y,z]
% is given by
%
% dot(P,[x,y,z] - cm) == 0
%
% Essentially this means we subtract off the column mean from our
% point, and then take the dot product with the normal vector. That
% must yield zero for a point on the plane. We can also think of it
% in a different way, that if a point were to lie OFF the plane,
% then this dot product would see some projection along the normal
% vector.
%
% So if your goal is now to predict Z, as a function of X and Y,
% we simply expand that dot product.
%
% dot(P,[x,y,z]) - dot(P,cm) = 0
%
% P(1)*X + P(2)*Y + P(3)*Z - dot(P,cm) = 0
%
% or simply (assuming P(3), the coefficient of Z) is not zero...
ZHat = (dot(P,cm) - P(1)*X - P(2)*Y)/P(3)

plot 3D line, matlab

My question is pretty standard but can't find a solution of that.
I have points=[x,y,z] and want to plot best fit line.
I am using function given below (and Thanx Smith)
% LS3DLINE.M Least-squares line in 3 dimensions.
%
% Version 1.0
% Last amended I M Smith 27 May 2002.
% Created I M Smith 08 Mar 2002
% ---------------------------------------------------------------------
% Input
% X Array [x y z] where x = vector of x-coordinates,
% y = vector of y-coordinates and z = vector of
% z-coordinates.
% Dimension: m x 3.
%
% Output
% x0 Centroid of the data = point on the best-fit line.
% Dimension: 3 x 1.
%
% a Direction cosines of the best-fit line.
% Dimension: 3 x 1.
%
% <Optional...
% d Residuals.
% Dimension: m x 1.
%
% normd Norm of residual errors.
% Dimension: 1 x 1.
% ...>
%
% [x0, a <, d, normd >] = ls3dline(X)
I have a.
So equation may be
points*a+dist=0
where dist is min. distance from origon.
Now my question is how to plot best filt line in 3D.
It helps to actually read the content of the function, which uses Singular Value Decomposition.
% calculate centroid
x0 = mean(X)';
% form matrix A of translated points
A = [(X(:, 1) - x0(1)) (X(:, 2) - x0(2)) (X(:, 3) - x0(3))];
% calculate the SVD of A
[U, S, V] = svd(A, 0);
% find the largest singular value in S and extract from V the
% corresponding right singular vector
[s, i] = max(diag(S));
a = V(:, i);
The best orthogonal fitting line is
P = x0 + a.*t
as the parameter t varies. This is the direction of maximum variation which means that variation in the orthogonal direction is minimum. The sum of the squares of the points' orthogonal distances to this line is minimized.
This is distinct from linear regression which minimizes the y variation from the line of regression. That regression assumes that all errors are in the y coordinates, whereas orthogonal fitting assumes the errors in both the x and y coordinates are of equal expected magnitudes.
[Credit: Roger Stafford , http://www.mathworks.com/matlabcentral/newsreader/view_thread/294030]
Then you only need to create some t and plot it:
for t=0:100,
P(t,:) = x0 + a.*t;
end
scatter3(P(:,1),P(:,2),P(:,3));
You may want to use plot3() instead, in which case you need only a pair of points. Since a line is infinite by definition, it is up to you to determine where it should begin and end (depends on application).