MiniZinc Array Declaration - minizinc

How can I declare an array in MiniZinc, similar to the below Java code where the size of second dimension of the 2D array is not same for all?
int numV=5
int[] numActs=new int[numV];
double[][] min=new double[numV][];
for(int i=0;i<numV;i++){
for(int j=0;j<numActs[i];j++){
min[i][j]=<some value>;
}
}

Short answer: MiniZinc don't support "jagged" arrays, i.e. rows with unequal length (and no columns with unequal length) . All rows must have the same length (as do columns), and must be declared with the length in flattening time.
What you can do is to define the data matrix (here called "m") with maximum row length * maximum column length, and fill out the shorter rows with some dummy values, e.g. 0:
Example: Rows with unequal lengths:
[1,2,3,4]
[5,6],
[7,8,9],
[10]
[11,12,13]
The corresponding MiniZinc declaration would be:
int: rows = 5;
int: cols = 4;
array[1..rows,1..cols] of int: m =
array2d(1..rows,1..cols,
[
1,2,3,4,
5,6,0,0,
7,8,9,0,
10,0,0,0,
11,12,13,0,
]);
You will have to handle these dummy values, either by ignoring the dummy values in your model, or use a length array which contains the length of each row, e.g.
array[1..rows] of int: lengths = [4,2,3,1,3];

Related

How to make cell array same length after padding zeros

This is data matrix having 2*159 cells
In the data matrix so many columns ( 2 vectors) having different length . I want to pad zeros which have the minimum length. Number of zeros should be
[max(length(Vector 1))-min(length(Vector 2))]
Now I want add zeros in the cell which have minimum length. and want to make length equal in each column if column have same length than no problem.
n = max(max(cellfun(#(x)size(x,2),data)))
cellfun(#(x)[x, zeros(1,n-numel(x))], data, 'uni', 0)
The above was finding one single max value to pad the cells to. I realise now that you actually want this max calculated on a per column basis:
n = max(cellfun(#(x)size(x,2),data))
cellfun(#(x,n)[x, zeros(1,n-numel(x))], data, repmat(num2cell(n),2,1), 'uni', 0)
At this point it might be more intuitive to just use a loop
for col = 1:size(data,2)
n = max(size(data{1,col},2),size(data{2,col},2));
for row = 1:2
x = data{row,col};
data{row,col} = [x, zeros(1,n-numel(x))];
end
end

How to find mean of struct datatype in MATLAB?

I want to find the eccentricity of an image.
img = imread('47.jpg');
ecc=regionprops(img,'Eccentricity');
ecc =
255x1 struct array with fields:
Eccentricity
ecc(255)
ans =
Eccentricity: 0.2851
ecc(1)
ans =
Eccentricity: 0.4740
=========================
ecc is a variable of struct datatype. It will hold values of all the 255 objects. However, I want to find only one eccentricity and considering the mean of all these values.
Is there a way to find mean of struct value?
I tried for loop. calculating sum and dividing by total no. of objects. But MATLAB does not permit addition on struct data varible.
=======================================
img = imread('47.jpg');
ecc=regionprops(img,'Eccentricity');
numObj = numel(ecc);
sum=0;
index=1;
for k = 1: numObj
temp=ecc(index);
**sum=temp+sum;**
index=k+1;
end
imgEcc = sum/numObj;
**??? Undefined function or method 'plus' for input arguments of type 'struct'.**
===========================================
Please provide your inputs.
Scalar Data in Field
Within your loop, you must refer to the field name to access the data:
for k = 1: numObj
temp=ecc.Eccentricity(index);
sum=temp+sum;
index=k+1;
end
imgEcc = sum/numObj;
A more efficient method is to pull all of the eccentricities from the struct array using the fact that ecc.Eccentricity is itself a comma-separated list of values:
Eccentricities = [ecc.Eccentricity];
This is just like [ecc(1).Eccentricity, ecc(2).Eccentricity,...] by how Matlab handles struct arrays.
Since the eccentricities are now in a double array, you can use mean:
EccentricityBar = mean(Eccentricities);
Array Data in Field
If the data in the struct array is not scalar, the semantics of the value extraction depend on the shape of data in the field.
Regardless of whether the field data is a row vector (1xN), a column vector (Nx1), or a matrix (MxN), the matrix formed by wrapping the field reference in square braces is always made from comma-separated concatenation.
In other words, if we have a struct array foo with field bar, the following two lines are equivalent:
baz1 = [foo(1:3).bar];
baz2 = [foo(1).bar,foo(2).bar,foo(3).bar];
To access certain elements of the baz array requires knowing the shape of the data in foo(k).bar.
If the data was a row vector of length N, the original columns from the struct array can be extracted using subscripts and the the stride N:
col1 = baz(1:N:end);
col2 = baz(2:N:end);
...
col# = baz(#:N:end);
If the data was a column vector of length N, the original rows from the struct array are the rows of baz:
row1 = baz(1,:);
row2 = baz(2,:);
...
row# = baz(#,:);
And for matrix data, combinations of the above two methods are where to look.
For example, if you had a struct array data with the field Centroid that had the x and y centroid locations in a 1x2 array, we could extract the values like
centroids = [data.Centroid];
xbar = centroids(1:2:end);
ybar = centroids(2:2:end);
whereas, if the centroid locations were a 2x1 array, we would extract like
centroids = [data.Centroid];
xbar = centroids(1,:);
ybar = centroids(2,:);

How to create an empty array in a matrix

How to create an empty array in matlab that accepts elements from a matrix when you do not know the no.of elements it is going to contain ?
Use the [] operator. Example:
x = [];
If you wanna be specific in the type of the empty matrix, use the empty property. Examples:
emptyDoubleMatrix = double.empty; % Same as emptyDoubleMatrix = [];
emptySingleMatrix = single.empty;
emptyUnsignedInt8Matrix = uint8.empty;
This works for empty matrices of classes as well. Example:
emptyFunctionHandleMatrix = function_handle.empty;
You can use the empty matrix/vector notation, [], and Matlab will set up a placeholder for it.
x = []
Now if you want to append a scalar, say num, to it, you cannot index it because it is empty.
However, you can either:
Use array concatenation to concatenate itself with another scalar:
x = [x num]
Use the end+1 notation, to address the first available location:
x(end+1) = num
Both of the above two notations also work when you want to append a row or a column vector to an existing row vector or column vectors. But when you are concatenating vectors/matrices, remember to be consistent with the dimensions.

How can I find the maximum value and its index in array in MATLAB?

Suppose I have an array, a = [2 5 4 7]. What is the function returning the maximum value and its index?
For example, in my case that function should return 7 as the maximum value and 4 as the index.
The function is max. To obtain the first maximum value you should do
[val, idx] = max(a);
val is the maximum value and idx is its index.
For a matrix you can use this:
[M,I] = max(A(:))
I is the index of A(:) containing the largest element.
Now, use the ind2sub function to extract the row and column indices of A corresponding to the largest element.
[I_row, I_col] = ind2sub(size(A),I)
source: https://www.mathworks.com/help/matlab/ref/max.html
In case of a 2D array (matrix), you can use:
[val, idx] = max(A, [], 2);
The idx part will contain the column number of containing the max element of each row.
You can use max() to get the max value. The max function can also return the index of the maximum value in the vector. To get this, assign the result of the call to max to a two element vector instead of just a single variable.
e.g.
z is your array,
>> [x, y] = max(z)
x =
7
y =
4
Here, 7 is the largest number at the 4th position(index).
3D case
Modifying Mohsen's answer for 3D array:
[M,I] = max (A(:));
[ind1, ind2, ind3] = ind2sub(size(A),I)
This will return the maximum value in a matrix
max(M1(:))
This will return the row and the column of that value
[x,y]=ind2sub(size(M1),max(M1(:)))
For minimum just swap the word max with min and that's all.
For example:
max_a = max(a)
a.index(max_a)

read text files containing binary data as a single matrix in matlab

I have a text file which contains binary data in the following manner:
00000000000000000000000000000000001011111111111111111111111111111111111111111111111111111111110000000000000000000000000000000
00000000000000000000000000000000000000011111111111111111111111111111111111111111111111000111100000000000000000000000000000000
00000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111100000000000000000000000000000000
00000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000
00000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111100000000000000000000000000000000
00000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111100000000000000000000000000000000
00000000000000000000000000000000000000011111111111111111111111111111111111111111111111000111110000000000000000000000000000000
00000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111110000000000000000000000000000000
00000000000000000000000000000000000000000000111111111111111111111111111111111111110000000011100000000000000000000000000000000
00000000000000000000000000000000000000011111111111111111111111111111111111111111111111100111110000000000000000000000000000000
00000000000000000000000000000000000111111111111111111111111111111111111111111111111111110111110000000000000000000000000000000
00000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000
00000000000000000000000000000000000000001111111111111111111111111111111111111111111111000011100000000000000000000000000000000
00000000000000000000000000000000000000001111111111111111111111111111111111111111111111000011100000000000000000000000000000000
00000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111000000000000000000000000000000000
00000000000000000000000000000000000000011111111111111111111111111111111111111111111110000011100000000000000000000000000000000
00000000000000000000000000000000000000000000011111111111111111111111111111111111100000000011100000000000000000000000000000000
00000000000000000000000000000000000000111111111111111111111111111111111111111111111111110111100000000000000000000000000000000
Please note that each 1 or 0 is independent i.e the values are not decimal. I need to find the column wise sum of the file. There are 125 columns in all and there are 840946 rows.
I have tried textread, fscanf and a few other matlab commands, but the result is that they all read each row in decimal format and create a 840946x1 array. I want to create a 840946x125 matrix to compute a column wise sum.
You can use textread to do it. Just read strings and later process them with sscanf, one digit at a time
A = textread('data.txt', '%s');
ncols = size(A, 1);
nrows = size(A{1}, 2);
A = reshape(sscanf([A{:}], '%1d'), nrows, ncols);
Note that now A is transposed, i.e. you have 125 rows.
The column-wise sum is then computed simply by
colsum = sum(A);
Here's a slightly hack-ish approach:
A = textread('data.txt', '%s');
colsum = sum(cat(1,A{:})-'0')
Breakdown:
textread will read each line of 0's and 1's as a single string. A will therefore be a cell-string, with each element equal to a string of length 125.
cat(1,A{:}) will concatenate the cell string into a "normal" Matlab character array of size 840946-by-125.
Subtracting the ASCII-value '0' from any character array consisting of 0's and 1's will return their numeric representation. For example, 'a'-0 = 97, the ASCII-value for lower-case 'a'.
sum will finally sum over the columns of this array.