How to transpose a matrix without MATLAB's transpose tool - matlab

I have an image, which I have listed as a matrix. I want to take the transpose of that image and then display that image on the screen.
I would like to know how to do this the "hard" way, ie without using MATLAB's transpose function.

function [B] = trans(A)
[r c] = size(A);
B = zeros(c,r);
for i = 1:r
for j = 1:c
B(j,i) = A(i,j)
end
end
end

As this is for a class, I won't give you an exact answer, but I will nudge you in the right direction. I'm assuming that you are looking for a method that involves manually transposing the information, rather than using builtin functions.
Matlab stores values in a matrix in the form of a vector and a "size" - for instance, a 2x3 matrix would be stored with six values in a vector, and then [2,3] (internally) to tell it that it's 2x3 and not 6x1.
For the 2x3 matrix, this is the order of the values in the vector:
1 3 5
2 4 6
To reference the value in (2,2), you can reference it as A(2,2), or as A(4). The value in (1,3) can be referenced as A(5).
As such, if you can construct a vector referencing the values in the transposed order, then you can assign the new values into the appropriate order and store them in a matrix of appropriate size. To make the point, consider the transpose of the above matrix:
1 2
3 4
5 6
This would be represented as (1,3,5,2,4,6) with size (3,2). If you can construct the vector (1,3,5,2,4,6), then you can use that vector to assign the values appropriately.

Here's hint toward a solution: The transpose transforms the element A(1,2) from the normal array A into the element B(2,1) from the transposed array B (B=A'), and vice versa. Thus, you can iterate through all the rows and column, and apply the transformation element-by-element.

Are you allowed to use flipud and fliplr ?
In this case you can represent the transposition as a sequence of flips (I'll leave it to you to figure out the exact sequence).

You can use rot90 with flipud/fliplr for this.

Related

Vectorizing a parallel FOR loop across multiple dimensions MATLAB

Please correct me if there are somethings unclear in this question. I have two matrices pop, and ben of 3 dimensions. Call these dimensions as c,t,w . I want to repeat the exact same process I describe below for all of the c dimensions, without using a for loop as that is slow. For the discussion below, fix a value of the dimension c, to explain my thinking, later I will give a MWE. So when c is fixed I have a 2D matrix with dimension t,w.
Now I repeat the entire process (coming below!) for all of the w dimension.
If the value of u is zero, then I find the next non zero entry in this same t dimension. I save both this entry as well as the corresponding t index. If the value of u is non zero, I simply store this value and the corresponding t index. Call the index as i - note i would be of dimension (c,t,w). The last entry of every u(c,:,w) is guaranteed to be non zero.
Example if the u(c,:,w) vector is [ 3 0 4 2 0 1], then the corresponding i values are [1,3,3,4,6,6].
Now I take these entries and define a new 3d array of dimension (c,t,w) as follows. I take my B array and do the following what is not a correct syntax but to explain you: B(c,t,w)/u(c,i(c,t,w),w). Meaning I take the B values and divide it by the u values corresponding to the non zero indices of u from i that I computed.
For the above example, the denominator would be [3,4,4,2,1,1]. I hope that makes sense!!
QUESTION:
To do this, as this process simply repeats for all c, I can do a very fast vectorizable calculation for a single c. But for multiple c I do not know how to avoid the for loop. I don't knw how to do vectorizable calculations across dimensions.
Here is what I did, where c_size is the dimension of c.
for c=c_size:-1:1
uu=squeeze(pop(c,:,:)) ; % EXTRACT A 2D MATRIX FROM pop.
BB=squeeze(B(c,:,:)) ; % EXTRACT A 2D MATRIX FROM B
ii = nan(size(uu)); % Start with all nan values
[dum_row, ~] = find(uu); % Get row indices of non-zero values
ii(uu ~= 0) = dum_row; % Place row indices in locations of non-zero values
ii = cummin(ii, 1, 'reverse'); % Column-wise cumulative minimum, starting from bottomi
dum_i = ii+(time_size+1).*repmat(0:(scenario_size-1), time_size+1, 1); % Create linear index
ben(c,:,:) = BB(dum_i)./uu(dum_i);
i(c,:,:) = ii ;
clear dum_i dum_row uu BB ii
end
The central question is to avoid this for loop.
Related questions:
Vectorizable FIND function with if statement MATLAB
Efficiently finding non zero numbers from a large matrix
Vectorizable FIND function with if statement MATLAB

swapping elements of a given symbolic matrices

So, the problem is simple to understand. Given any symbolic matrix of any dimmension I want to swap the elements in order to obtain one matrix of the same size, same elements but distributed differently.
For instance
syms a b c
A=[a b c;0 0 c]
swapping A we can get:
A=[b a c;0 c 0];
Using randperm(numel(A)) you can generate a random permutation of the numbers 1:numel(A), which are the indices in your matrix.
A(:)=A(randperm(numel(A)));
The A(:) on the left side is required to preserve the shape, otherwise you end up with a vector of the elements. If you wish to keep your matrix A unchanged:
B=A; %just to get a matrix of same size and datatype
B(:)=A(randperm(numel(A)));

Remove duplicates in correlations in matlab

Please see the following issue:
P=rand(4,4);
for i=1:size(P,2)
for j=1:size(P,2)
[r,p]=corr(P(:,i),P(:,j))
end
end
Clearly, the loop will cause the number of correlations to be doubled (i.e., corr(P(:,1),P(:,4)) and corr(P(:,4),P(:,1)). Does anyone have a suggestion on how to avoid this? Perhaps not using a loop?
Thanks!
I have four suggestions for you, depending on what exactly you are doing to compute your matrices. I'm assuming the example you gave is a simplified version of what needs to be done.
First Method - Adjusting the inner loop index
One thing you can do is change your j loop index so that it only goes from 1 up to i. This way, you get a lower triangular matrix and just concentrate on the values within the lower triangular half of your matrix. The upper half would essentially be all set to zero. In other words:
for i = 1 : size(P,2)
for j = 1 : i
%// Your code here
end
end
Second Method - Leave it unchanged, but then use unique
You can go ahead and use the same matrix like you did before with the full two for loops, but you can then filter the duplicates by using unique. In other words, you can do this:
[Y,indices] = unique(P);
Y will give you a list of unique values within the matrix P and indices will give you the locations of where these occurred within P. Note that these are column major indices, and so if you wanted to find the row and column locations of where these locations occur, you can do:
[rows,cols] = ind2sub(size(P), indices);
Third Method - Use pdist and squareform
Since you're looking for a solution that requires no loops, take a look at the pdist function. Given a M x N matrix, pdist will find distances between each pair of rows in a matrix. squareform will then transform these distances into a matrix like what you have seen above. In other words, do this:
dists = pdist(P.', 'correlation');
distMatrix = squareform(dists);
Fourth Method - Use the corr method straight out of the box
You can just use corr in the following way:
[rho, pvals] = corr(P);
corr in this case will produce a m x m matrix that contains the correlation coefficient between each pair of columns an n x m matrix stored in P.
Hopefully one of these will work!
this works ?
for i=1:size(P,2)
for j=1:i
Since you are just correlating each column with the other, then why not just use (straight from the documentation)
[Rho,Pval] = corr(P);
I don't have the Statistics Toolbox, but according to http://www.mathworks.com/help/stats/corr.html,
corr(X) returns a p-by-p matrix containing the pairwise linear correlation coefficient between each pair of columns in the n-by-p matrix X.

Reshape function (apparently) is useless?

reshape function should change the shape of a matrix.
But if I try using it (it's also written in the manual) I discover that if I declare:
reshape(A,m,n);
Then A must have m lines and n columns.
If I try using reshape passing as arguments numbers different from these, I get an error.
So appearently, it does not reshape any matrix, it just does return the same matrix if I pass m and n as arguments, and return an error otherwise.
So if I have a 4x4 matrix and I want to make it smaller: 2x2, I can't.
It changes the shape, not the size of the array. To change the shape the number of elements must not change. So if you have 4x4 you can go to 8x2 or 2x8 or 16x1 etc. but not 2x2 (what do you expect to happen to the other elements?)
Reshape rearranges elements; if you do B = reshape(A, u) then logically B must have the same number of elements (note that size(B) == prod(u)) as A (length(B(:)) == length(A(:))). Otherwise, how would it know which elements to drop if A had more, or where would it get new ones if B had more?
One situation in which reshape is useful is when for some reason your square matrix was unrolled into a vector (perhaps by another function) and you simply need to arrange it back to its previous form.
When you want to get a smaller part of a matrix, use A(i1:i2, j1:j2). When you want to "tile" a matrix, use repmat(A, i, j).
As #thrope says, reshape changes the shape, not the number of elements. If you have a 4x4 matrix and you want the upper left 2x2 corner of it, use B=A(1:2,1:2) or the bottom right 2x2 corner, B=A(3:4,3:4).

Efficient Blending of Non-Nan-Sparse Transformed Mosaic Images in Matlab

I'm currently working on improving the blending part of the image mosaic sample application on VLfeat's homepage. In this final blending stage I want to combine two non-nan-sparse images, both being the output from two images interpolations using interp2 with nan-flag. Specifically, given two image matrices A and B and blended matrix C all of same dimension M-by-N, I want for each matrix position (i,j) in A and B want to check whehter
both A and B have a defined value in (i,j) so make C(i,j) the average of them or,
either A or B have a defined (~isnan()) value in (i,j) so put that in C(i,j) or,
neither A nor B have a defined value in (i,j) thereby leaving C(i,j) as is
assuming C is initialized to all nan values.
I haven't find a simple nor elegant way of doing this without having to
reshape A and B into vectors
find non-nan vector indexes AI=find(~isnan(A)) and BI=find(~isnan(B))
find intersection II of AI and BI
use II, AI and BI to modify a vector C of same length as A and B as mentioned in three steps above
reshape C back to M-by-N to finally get result wanted
I have tried to express the same steps using matrices and matrix indexes without success. Is this the only way of doing this in MATLAB? It seems kind of cumbersome.
Maybe I'm missing something (I do not understand why you need to reshape matrix to vectors, for example).
Anyway, here is a try:
% Unconditionnaly compute the average into temp D matrix
D=(A+B)/2;
% Restore A and B values where B and A are NaN
D(isnan(A))=B(isnan(A));
D(isnan(B))=A(isnan(B));
% Only modify C wherever the final result is not NaN
C(~isnan(D))=D(~isnan(D));