find and match multiple values in the same row in array in matlab - matlab

I have a data set consists of the following (which are head values for a finite difference groundwater flow model consists of 200 row, 200 column, and 5 layers)
, "id", "k", "i", "j", "f", "Active"
1, 1, 1, 1, 1, 313, 0
2, 2, 1, 1, 2, 315.2.0, 0
3, 3, 1, 1, 3, 301.24, 0
4, 4, 1, 1, 4, 306.05, 0
5, 5, 1, 1, 5, -999.0, 0
6, 6, 1, 1, 6, -999.0, 0
7, 7, 1, 1, 7, 310.57, 0
8, 8, 1, 1, 8, -999.0, 0
9, 9, 1, 1, 9, -999.0, 0
.
.
.
200000, 200000, 5, 200, 200, -999.0, 0
let us assume that I need to find the row that has a specific i,j,k
for example I want to find the row which has i=100, j=50, k=3 to store the value f for multiple i,j,k
I've tried to use find but it finds only the location for a specific item
I know it can be done using for & if but it will be time demanding
Is there a fast way to do so using matlab?

Lets suppose your text file has the following data
"id", "k", "i", "j", "f", "Active"
1, 1, 1, 1, 313, 0
2, 1, 1, 2, 315.2.0, 0
3, 1, 1, 3, 301.24, 0
4, 1, 1, 4, 306.05, 0
5, 1, 1, 5, -999.0, 0
6, 1, 1, 6, -999.0, 0
7, 1, 1, 7, 310.57, 0
8, 1, 1, 8, -999.0, 0
9, 1, 1, 9, -999.0, 0
First read the file through
>> fileID = fopen('testfileaccess.txt');
>> C = textscan(fileID,'%s %s %s %s %s %s','Delimiter',',')
You will get 6 cells representing each column
C =
Columns 1 through 5
{10x1 cell} {10x1 cell} {10x1 cell} {10x1 cell} {10x1 cell}
Column 6
{10x1 cell}
>> Matrix= [str2double(C{2}).';str2double(C{3}).';str2double(C{4}).';].'
the above code will result the i j and k in a matrix with each row representing each variable
Matrix =
NaN NaN NaN
1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
1 1 6
1 1 7
1 1 8
1 1 9
then if you want to find for example k = 1 , i = 1 and j = 8 you use find()
find(Matrix(:,1) == 1 & Matrix(:,2) == 1 & Matrix(:,3) == 8)
and there you have it
ans =
8
8th row

row = jcount*kcount*(i-1) + kcount*(j-1) + k
In your case:
row = 200*5*(i-1) + 5*(j-1) + k

Related

how do I concatenate the results of a concatenated array?

I have two matrices (dfs):
A = [1 2 3 4
5 6 7 8
9 10 11 12]
and B = [1, 2, 3]
and I want matrix C to be repeating each row in A, B times. for example, first row, 1,2,3,4 needs to be repeated once, second row: 5,6,7,8 twice and last row three times:
C = [1 2 3 4
5 6 7 8
5 6 7 8
9 10 11 12
9 10 11 12
9 10 11 12]
my code
for i in range(0,2401):
g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True)
partially does this, except only gives me the 3 times last row part, I need to concatenate each concatenation.
below gives me what I want but its not clean, i.e. indices are not ignored and messy.
result = []
for i in range(0,2401):
g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True)
result.append(g)
If you write your matrices like:
A = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
B = [1, 2, 3]
C = []
You can iterate through B and add to C like:
for i in range(len(B)):
index = 0
while index < B[i]:
C.append(A[i])
index += 1
Which has an output:
[[1, 2, 3, 4],
[5, 6, 7, 8],
[5, 6, 7, 8],
[9, 10, 11, 12],
[9, 10, 11, 12],
[9, 10, 11, 12]]
I hope this helps!

Getting the matrix value given a vector of indices along each axis

I have a Matlab matrix M with size: [70 5 3 2 10 9 5 3 21];
I have a vector with a coordinates that I want to read of that matrix: [5, 1, 1, 2, 3, 4, 1, 2, 1];
MWE example of what I am trying to get:
M = rand(70 5 3 2 10 9 5 3 21);
coordinates = [5, 1, 1, 2, 3, 4, 1, 2, 1];
% Output desired:
M(5, 1, 1, 2, 3, 4, 1, 2, 1)
%Current attempt:
M(coordinates)
Clearly M(coordinates) <> M(5, 1, 1, 2, 3, 4, 1, 2, 1). Is there a way of doing this?
It's a bit awkward, but you can convert the array to a cell array, and then to a comma-separated list:
M = rand(70, 5, 3, 2, 10, 9, 5, 3, 21);
coordinates = [5, 1, 1, 2, 3, 4, 1, 2, 1];
coords_cell = num2cell(coordinates);
result = M(coords_cell{:});

Minimum of two multidimensional matrices, with which matrix 'won' (contained the minimum)

I have two matrices (size 4x4) and I want to find the minimum between the two. For example:
A = [ 3, 2, 4, 5;
1, 2, 0, 6;
9, 8, 5, 4;
0, 1, 0, 3 ];
B = [ 1, 1, 6, 8;
0, 4, 6, 3;
5, 6, 7, 1;
0, 2, 3, 4 ];
Now, if I did a min(A,B) in Octave, it gives me
[ 1, 1, 4, 5;
0, 2, 0, 3;
5, 6, 5, 1;
0, 1, 0, 3 ]
Is there a way to get the matrix that 'won', by which I mean which matrix contained the minimum, in each element-wise comparison?
Like, for the first element of both matrices, matrix B won and so on.
I don't want to loop through the matrices.
You can compare A and B to find out in which matrix the minimum occurred.
With A > B, you will get a matrix containing False if the entry from A was chosen, and True if the entry from B was chosen. By adding 1 to it, you will get 1 if A was chosen and 2 if B was chosen.
>> 1 + (A > B)
ans =
2 2 1 1
2 1 1 2
2 2 1 2
1 1 1 1
Alternatively, you can concatenate A and B to form a 3-dimensional array with dimensions [4, 4, 2], where C(:, :, 1) = A and where C(:, :, 2) = B. Then you can call min on this matrix C along the third axis. When calling min on one matrix, you can get the index of the "winner" directly as a second return value:
>> C = cat(3, A, B);
>> [res, idx] = min(C, [], 3)
res =
1 1 4 5
0 2 0 3
5 6 5 1
0 1 0 3
idx =
2 2 1 1
2 1 1 2
2 2 1 2
1 1 1 1

Expanding each element in a (2-by-2) matrix to a (3-by-2) block

I want to expand each element in a (2-by-2) matrix to a (3-by-2) block, using Python 3 --- with professional and elegant codes. Since I don't know the python codes, I will just describe the following in maths
X = # X is an 2-by-2 matrix.
1, 2
3, 4
d = (3,2) # d is the shape that each element in X should be expanded to.
Y = # Y is the result
1, 1, 2, 2
1, 1, 2, 2
1, 1, 2, 2
3, 3, 4, 4
3, 3, 4, 4
3, 3, 4, 4
Not that every element in X is now an 3-by-2 block in Y. The position of the block in Y is the same as the position of the element in X.
Here is the MATLAB code
X = [1,2;3,4];
d = [3,2]
[row, column] = size(X);
a = num2cell(X);
b = cell(row, column);
[b{:}] = deal(ones(d));
Y = cell2mat(cellfun(#times,a,b,'UniformOutput',false));
I appreciate your help. Thanks in advance.
If you are okay with using NumPy module with Python, you can use numpy.kron -
np.kron(X,np.ones((3,2),dtype=int))
Sample run -
In [15]: import numpy as np
In [16]: X = np.arange(4).reshape(2,2)+1 # Create input array
In [17]: X
Out[17]:
array([[1, 2],
[3, 4]])
In [18]: np.kron(X,np.ones((3,2),dtype=int))
Out[18]:
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4],
[3, 3, 4, 4]])
In fact, this is a direct translation of how one would achieved the desired result in MATLAB in an elegant and professional way as well, as shown below -
>> X = [1,2;3 4]
X =
1 2
3 4
>> kron(X,ones(3,2))
ans =
1 1 2 2
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
3 3 4 4
Another way to do it with ndarray.repeat:
>>> X = np.arange(4).reshape(2,2)+1
>>> X.repeat(3, axis=0).repeat(2, axis=1)
array([[1, 1, 2, 2],
[1, 1, 2, 2],
[1, 1, 2, 2],
[3, 3, 4, 4],
[3, 3, 4, 4],
[3, 3, 4, 4]])

Evaluate optimal replacement algorithm for 5 frames

Question:
Consider the following page reference string:
1, 2, 3, 4, 2, 1, 5, 6, 2, 1, 2, 3, 7, 6, 3, 2, 1, 2, 3, 6.
How many page faults would occur for the optimal page replacement algorithms, assuming five frames? Remember all frames are initially empty, so your first unique pages will all cost one fault each.
I am not quite sure what would happen:
1 -> 1
2 -> 1, 2
3 -> 1, 2, 3
4 -> 1, 2, 3, 4,
2 -> What happens here??
1
...etc (with the rest of the reference string)
There will be 7 page faults in total.
1 -> 1
2 -> 1, 2
3 -> 1, 2, 3
4 -> 1, 2, 3, 4
2 -> 1, 2, 3, 4 (This is a hit 2 is already in the memory)
1 -> 1, 2, 3, 4
5 -> 1, 2, 3, 4, 5 (This is a miss but we have 5 frames.)
6 -> 1, 2, 3, 6, 5 (4 will be replaced as it is not required in future)
...