Matrix multiplication resulting in different values in MATLAB and NUMPY(?) [duplicate] - matlab

This question already has answers here:
Matrix multiplication problems - Numpy vs Matlab?
(2 answers)
Closed 7 years ago.
Here's the matrix
>> x = [2 7 5 9 2; 8 3 1 6 10; 4 7 3 10 1; 6 7 10 1 8;2 8 2 5 9]
Matlab gives me
>> mtimes(x',x)
ans =
124 124 94 122 154
124 220 145 198 179
94 145 139 101 121
122 198 101 243 141
154 179 121 141 250
However, the same operation(on same data) in python(numpy) produces different result. I'm unable to understand why?
import numpy as np
a = [[2, 7, 5, 9, 2],[8,3,1,6,10],[4,7,3,10,1],[6,7,10,1,8],[2,8,2,5,9]]
x = np.array(a)
print 'A : ',type(x),'\n',x,'\n\n'
# print np.transpose(A)
X = np.multiply(np.transpose(x),x)
print "A'*A",type(X),'\n',X
produces
A : <type 'numpy.ndarray'>
[[ 2 7 5 9 2]
[ 8 3 1 6 10]
[ 4 7 3 10 1]
[ 6 7 10 1 8]
[ 2 8 2 5 9]]
A'*A <type 'numpy.ndarray'>
[[ 4 56 20 54 4]
[ 56 9 7 42 80]
[ 20 7 9 100 2]
[ 54 42 100 1 40]
[ 4 80 2 40 81]]

Numpy documentation states that the operator you apply performs element-wise multiplication.
However, mtimes in MATLAB does matrix multiplication.
To verify, MATLAB syntax for element-wise multiplication produces the same result you see in numpy:
disp(x.'.*x)
4 56 20 54 4
56 9 7 42 80
20 7 9 100 2
54 42 100 1 40
4 80 2 40 81

Related

Extracting multiple matrix from a single matrix in MATLAB [duplicate]

This question already has answers here:
split a matrix according to a column with matlab.
(3 answers)
Closed 4 years ago.
I have a matrix(type double) similar to the following example:
X = [ 23 3 5 1;
21 45 8 1;
65 56 7 1;
71 42 4 2;
45 91 5 2;
34 6 1 3;
87 37 8 3;
23 3 5 3]
Based on the element of the fourth column I want to get 3 matrix from the above matrix like the following example;
A=[ 23 3 5 1;
21 45 8 1;
65 56 7 1; ]
B =[ 71 42 4 2;
45 91 5 2; ]
C =[ 34 6 1 3;
87 37 8 3;
23 3 5 3;]
Basically I want to seprate all the 1s,2s and 3s of the fourth column into another matrix. How can I do it in the Matlab!
A = X(:,X(:,4)==1);
B = X(:,X(:,4)==2);
C = X(:,X(:,4)==3);

Matlab: how I can transform this algorithm associated with matrices manipulation?

(For my problem, I use a matrix A 4x500000. And the values of A(4,k) varies between 1 and 200).
I give here an example for a case A 4x16 and A(4,k) varies between 1 and 10.
I want first to match a name to the value from 1 to 5 (=10/2):
1 = XXY;
2 = ABC;
3 = EFG;
4 = TXG;
5 = ZPF;
My goal is to find,for a vector X, a matrix M from the matrix A:
A = [20 52 70 20 52 20 52 20 20 10 52 20 11 1 52 20
32 24 91 44 60 32 24 32 32 12 11 32 2 5 24 32
40 37 24 30 11 40 37 40 40 5 10 40 40 3 37 40
2 4 1 3 4 5 2 1 3 3 8 6 7 9 6 10]
A(4,k) takes all values between 1 and 10. These values can be repeated and they all appear on the 4th line.
20
X= 32 =A(1:3,1)=A(1:3,6)=A(1:3,8)=A(1:3,9)=A(1:3,12)=A(1:3,16)
40
A(4,1) = 2;
A(4,6) = 5;
A(4,8) = 1;
A(4,9) = 3;
A(4,12) = 6;
A(4,16) = 10;
for A(4,k) corresponding to X, I associate 2 if A(4,k)<= 5, and 1 if A(4,k)> 5. For the rest of the value of A(4,k) which do not correspond to X, I associate 0:
[ 1 2 3 4 5 %% value of the fourth line of A between 1 and 5
2 2 2 0 2
ZX = 6 7 8 9 10 %% value of the fourth line of A between 6 and 10
1 0 0 0 1
2 2 2 0 2 ] %% = max(ZX(2,k),ZX(4,k))
the ultimate goal is to find the matrix M:
M = [ 1 2 3 4 5
XXY ABC EFG TXG ZPF
2 2 2 0 2 ] %% M(3,:)=ZX(5,:)
Code -
%// Assuming A, X and names to be given to the solution
A = [20 52 70 20 52 20 52 20 20 10 52 20 11 1 52 20
32 24 91 44 60 32 24 32 32 12 11 32 2 5 24 32
40 37 24 30 11 40 37 40 40 5 10 40 40 3 37 40
2 4 1 3 4 5 2 1 3 3 8 6 7 9 6 10];
X = [20 ; 32 ; 40];
names = {'XXY','ABC','EFG','TXG','ZPF'};
limit = 10; %// The maximum limit of A(4,:). Edit this to 200 for your actual case
%// Find matching 4th row elements
matches = A(4,ismember(A(1:3,:)',X','rows'));
%// Matches are compared against all possible numbers between 1 and limit
matches_pos = ismember(1:limit,matches);
%// Finally get the line 3 results of M
vals = max(2*matches_pos(1:limit/2),matches_pos( (limit/2)+1:end ));
Output -
vals =
2 2 2 0 2
For a better way to present the results, you can use a struct -
M_struct = cell2struct(num2cell(vals),names,2)
Output -
M_struct =
XXY: 2
ABC: 2
EFG: 2
TXG: 0
ZPF: 2
For writing the results to a text file -
output_file = 'results.txt'; %// Edit if needed to be saved to a different path
fid = fopen(output_file, 'w+');
for ii=1:numel(names)
fprintf(fid, '%d %s %d\n',ii, names{ii},vals(ii));
end
fclose(fid);
Text contents of the text file would be -
1 XXY 2
2 ABC 2
3 EFG 2
4 TXG 0
5 ZPF 2
A bsxfun() based approach.
Suppose your inputs are (where N can be set to 200):
A = [20 52 70 20 52 20 52 20 20 10 52 20 11 1 52 20
32 24 91 44 60 32 24 32 32 12 11 32 2 5 24 32
40 37 24 30 11 40 37 40 40 5 10 40 40 3 37 40
2 4 1 3 4 5 2 1 3 3 8 6 7 9 6 10]
X = [20; 32; 40]
N = 10;
% Match first 3 rows and return 4th
idxA = all(bsxfun(#eq, X, A(1:3,:)));
Amatch = A(4,idxA);
% Match [1:5; 5:10] to 4th row
idxZX = ismember([1:N/2; N/2+1:N], Amatch)
idxZX =
1 1 1 0 1
1 0 0 0 1
% Return M3
M3 = max(bsxfun(#times, idxZX, [2;1]))
M3 =
2 2 2 0 2

How to calculate intensity inhomogeneity based on average filter by matlab

I have a question about intensity inhomogeneity. I read a paper, it defined a way to calculate the intensity inhomogeneity based on average filter:
Let see my problem, I have a image I (below code) and a average filter with r=3. I want to calculate image transformation J based on formula (17). Could you help me to implement it by matlab code? Thank you so much.
This is my code
%Create image I
I=[3 5 5 2 0 0 6 13 1
0 3 7 5 0 0 2 8 6
4 5 5 4 2 1 3 5 9
17 10 3 1 3 7 9 9 0
7 25 0 0 5 0 10 13 2
111 105 25 19 13 11 11 8 0
103 105 15 26 0 12 2 6 0
234 238 144 140 51 44 7 8 8
231 227 150 146 43 50 8 16 9
];
%% Create filter AF
size=3; % scale parameter in Average kernel
AF=fspecial('average',[size,size]); % Average kernel
%%How to calculate CN and J
CN=mean(I(:));%Correct?
J=???
You're pretty close! The mean intensity is calculated correctly; all you are missing to calculate J is apply the filter defined with fspecial to your image:
Here is the code:
clc
clear
%Create image I
I=[3 5 5 2 0 0 6 13 1
0 3 7 5 0 0 2 8 6
4 5 5 4 2 1 3 5 9
17 10 3 1 3 7 9 9 0
7 25 0 0 5 0 10 13 2
111 105 25 19 13 11 11 8 0
103 105 15 26 0 12 2 6 0
234 238 144 140 51 44 7 8 8
231 227 150 146 43 50 8 16 9
];
% Create filter AF
size=3; % scale parameter in Average kernel
AF=fspecial('average',[size,size]); % Average kernel
%%How to calculate CN and J
CN=mean(I(:)); % This is correct
J = (CN*I)./imfilter(I,AF); % Apply the filter to the image
figure;
subplot(1,2,1)
image(I)
subplot(1,2,2)
image(J)
Resulting in the following:

corresponding indices from two different matrices in matlab

In an algorithm, in each level, I have two corresponding matrices in a way one of them has 4 times more element than the other. like children and parent, but i need to have the corresponding elements. consider the two following indices as an example for a level
1 5 9 13
2 6 10 14 and 1 3
3 7 11 15 2 4
4 8 12 16
so for example, I want to receive the element by the index of 1 from the second matrix when i have each of 1,2,5,6 element indices from the first matrix or 2 when i have 3,4,7,8 or 3 for 9,10,16,14 and so on. how can i do that?
as an another example for another level:
1 9 17 25 33 41 49 57
2 10 18 26 34 42 50 58
3 11 19 27 35 43 51 59 and 1 5 9 13
4 12 20 28 36 44 52 60 2 6 10 14
5 13 21 29 37 45 53 61 3 7 11 15
6 14 22 30 38 46 54 62 4 8 12 16
7 15 23 31 39 47 55 63
8 16 24 32 40 48 56 64
Here is one way of doing that:
% Size of matrix A (8x8)
sizeA = 8;
% Size of matrix B (4x4)
sizeB = 4;
% Index of element on matrix A
idxA = 43;
% That is how you can get the corresponding index on matrix B
[r, c] = ind2sub([sizeA sizeA], idxA);
idxB = sub2ind([sizeB sizeB], ceil(r / 2), ceil(c / 2))
It will give you idxB = 10.
It is possible that reshape could be helpful for you.
Consider
A = [1 5 9 13;
2 6 10 14;
3 7 11 15;
4 8 12 16];
B = reshape(permute(reshape(A, [2 2 2 2]), [2 4 1 3]), [4 4]);
B
1 2 5 6
3 4 7 8
9 10 13 14
11 12 15 16
Now you have a nice mapping of the indices from one level to the next.
B(1,:) corresponds to all the indices that map to element 1 in your second array, etc.
When the matrix gets larger (2n x 2n), the operation becomes
B = reshape(permute(reshape(A, [2 n 2 n]), [2 4 1 3]), [n*n 4]);
If you know the 2D indices for the first matrix, then you just divide each by 2 to get the second pair indices:
r = 3;
c = 2;
% Then A(r,c) corresponds to B(floor(r/2), floor(c/2))
If you DON'T know the indices, but instead have the element value itself, you have to find the 2D index first:
val = 7; % test value
[r c] = find(A==val);
other_val = B(floor(r/2), floor(c/2));

Matrix division & permutation to achieve Baker map

I'm trying to implement the Baker map.
Is there a function that would allow one to divide a 8 x 8 matrix by providing, for example, a sequence of divisors 2, 4, 2 and rearranging pixels in the order as shown in the matrices below?
X = reshape(1:64,8,8);
After applying divisors 2,4,2 to the matrix X one should get a matrix like A shown below.
A=[31 23 15 7 32 24 16 8;
63 55 47 39 64 56 48 40;
11 3 12 4 13 5 14 6;
27 19 28 20 29 21 30 22;
43 35 44 36 45 37 46 38;
59 51 60 52 61 53 62 54;
25 17 9 1 26 18 10 2;
57 49 41 33 58 50 42 34]
The link to the document which I am working on is:
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.5132&rep=rep1&type=pdf
This is what I want to achieve:
Edit: a little more generic solution:
%function Z = bakermap(X,divisors)
function Z = bakermap()
X = reshape(1:64,8,8)'
divisors = [ 2 4 2 ];
[x,y] = size(X);
offsets = sum(divisors)-fliplr(cumsum(fliplr(divisors)));
if any(mod(y,divisors)) && ~(sum(divisors) == y)
disp('invalid divisor vector')
return
end
blocks = #(div) cell2mat( cellfun(#mtimes, repmat({ones(x/div,div)},div,1),...
num2cell(1:div)',...
'UniformOutput',false) );
%create index matrix
I = [];
for ii = 1:numel(divisors);
I = [I, blocks(divisors(ii))+offsets(ii)];
end
%create Baker map
Y = flipud(X);
Z = [];
for jj=1:I(end)
Z = [Z; Y(I==jj)'];
end
Z = flipud(Z);
end
returns:
index matrix:
I =
1 1 3 3 3 3 7 7
1 1 3 3 3 3 7 7
1 1 4 4 4 4 7 7
1 1 4 4 4 4 7 7
2 2 5 5 5 5 8 8
2 2 5 5 5 5 8 8
2 2 6 6 6 6 8 8
2 2 6 6 6 6 8 8
Baker map:
Z =
31 23 15 7 32 24 16 8
63 55 47 39 64 56 48 40
11 3 12 4 13 5 14 6
27 19 28 20 29 21 30 22
43 35 44 36 45 37 46 38
59 51 60 52 61 53 62 54
25 17 9 1 26 18 10 2
57 49 41 33 58 50 42 34
But have a look at the if-condition, it's just possible for these cases. I don't know if that's enough. I also tried something like divisors = [ 1 4 1 2 ] - and it worked. As long as the sum of all divisors is equal the row-length and the modulus as well, there shouldn't be problems.
Explanation:
% definition of anonymous function with input parameter: div: divisor vector
blocks = #(div) cell2mat( ... % converts final result into matrix
cellfun(#mtimes, ... % multiplies the next two inputs A,B
repmat(... % A...
{ones(x/div,div)},... % cell with a matrix of ones in size
of one subblock, e.g. [1,1,1,1;1,1,1,1]
div,1),... % which is replicated div-times according
to actual by cellfun processed divisor
num2cell(1:div)',... % creates a vector [1,2,3,4...] according
to the number of divisors, so so finally
every Block A gets an increasing factor
'UniformOutput',false...% necessary additional property of cellfun
));
Have also a look at this revision to have a simpler insight in what is happening. You requested a generic solution, thats the one above, the one linked was with more manual inputs.