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)));
Related
I have a matrix W which is a block diagonal matrix with dimensions 2*4, and each of its two block diagonals is 1*2 vector. I want to find the values of its entries that minimize the difference between the following function:
( F = BH-AW )
Where: W is the required block diagonal matrix to be optimized, B is a 2*2 matrix, H is a given 2*4 matrix, and A is a 2*2 matrix. A and B are calculated using the functions used in the attached code.
I tried this attached code, but I think it is now in an infinite loop and I don't know what should I do?
%% My code is:
while ((B*H)-(A*W)~=zeros(2,4))
w1=randn(1,2);
% generate the first block diagonal vector with dimensions 1*2. The values of each entry of the block diagonal vector maybe not the same.
w2=randn(1,2);
% generate the second block diagonal vector with dimensions 1*2.
W=blkdiag(w1,w2);
% build the block diagonal matrix that I want to optimize with dimensions 2*4.
R=sqrtm(W*inv(inv(P)+(H'*inv(eye(2)+D)*H))*W');
% R is a 2*2 matrix that will be used to calculate matrix A using the LLL lattice reduction algorithm. The values of P (4*4 matrix), H (2*4 matrix) and D (2*2 matrix) are given. It's clear here that matrix R is a function of W.
A= LLL(R,3/4);
% I use here LLL lattice reduction algorithm to obtain 2*2 matrix A which is function of R.
B=A'*W*P*H'*inv(eye(2)+D+H*P*H');
% B is 2*2 matrix which is function of A and W. The values of P (4*4 matrix), H (2*4 matrix) and D (2*2 matrix) are given.
end
Numerical operations with floating point numbers are only approximate on a computer (any number is only ever represented with a finite number of bits, which means you cannot exactly represent Pi for example). For more info, see this link.
Consequently, it is extremely unlikely that the loop you wrote will ever terminate, because the difference between B*H and A*W will not be exactly zero. Instead, you need to use a tolerance factor to decide when you are satisfied with the similarity achieved.
Additionally, as suggested by others in comment, the "distance" between two matrices is typically measured using some sort of norm (e.g. the Frobenius norm). By default, the norm function in Matlab will give the 2-norm of an input matrix.
In your case, this would give something like:
tol = 1e-6;
while norm(B*H-A*W) > tol
% generate the first block diagonal vector with dimensions 1*2.
% The values of each entry of the block diagonal vector maybe not the same.
w1=randn(1,2);
% generate the second block diagonal vector with dimensions 1*2.
w2=randn(1,2);
% build the block diagonal matrix that I want to optimize with dimensions 2*4.
W=blkdiag(w1,w2);
% R is a 2*2 matrix that will be used to calculate matrix A using the LLL lattice reduction algorithm.
% The values of P (4*4 matrix), H (2*4 matrix) and D (2*2 matrix) are given.
% It's clear here that matrix R is a function of W.
R=sqrtm(W/(inv(P)+(H'/(eye(2)+D)*H))*W');
% I use here LLL lattice reduction algorithm to obtain 2*2 matrix A which is function of R.
A= LLL(R,3/4);
% B is 2*2 matrix which is function of A and W. The values of P (4*4 matrix),
% H (2*4 matrix) and D (2*2 matrix) are given.
B=A'*W*P*H'/(eye(2)+D+H*P*H');
end
Note that:
With regards to the actual algorithm, I am a little bit concerned that your loop never seems to update the value of W, but instead updates matrices A and B. This suggests that your description of the problem might be incorrect or incomplete, but that is beyond the scope of this forum anyway (ask on Maths.SE if you want to know more).
Using inv() directly is discouraged in many cases. This is because the algorithm to compute the inverse of a matrix is less reliable than the algorithm to solve systems of the type AX=B. Matlab should give you a warning to use / and \ where possible; I would advise following this recommendation unless you know what you are doing.
In Matlab, I have created a matrix A with size (244x2014723)
and a matrix B with size (244x1)
I was able to calculate the correlation matrix using corr(A,B) which yielded in a matrix of size 2014723x1. So, every column of matrix A correlates with matrix B and gives one row value in the matrix of size 2014723x1.
My question is when I ask for a covariance matrix using cov(A,B), I get an error saying A and B should be of same sizes. Why do I get this error? How is the method to find corr(A,B) any different from cov(A,B)?
The answer is pretty clear if you read the documentation:
cov:
If A and B are matrices of observations, cov(A,B) treats A and B as vectors and is equivalent to cov(A(:),B(:)). A and B must have equal size.
corr
corr(X,Y) returns a p1-by-p2 matrix containing the pairwise correlation coefficient between each pair of columns in the n-by-p1 and n-by-p2 matrices X and Y.
The difference between corr(X,Y) and the MATLABĀ® function corrcoef(X,Y) is that corrcoef(X,Y) returns a matrix of correlation coefficients for the two column vectors X and Y. If X and Y are not column vectors, corrcoef(X,Y) converts them to column vectors.
One way you could get the covariances of your vector with each column of you matrix is to use a loop. Another way (might be in-efficient depending on the size) is
C = cov([B,A])
and then look at the first row (or column) or C.
See link
In the more about section, the equation describing how cov is computed for cov(A,B) makes it clear why they need to be the same size. The summation is over only one variable which enumerates the elements of A,B.
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.
Is it possible to reverse the following in matlab:
[U,S,V]=svds(fulldata,columns);
Quoting MathWorks:
[U,S,V] = svd(X) produces a diagonal matrix S of the same dimension as X, with nonnegative diagonal elements in decreasing order, and unitary matrices U and V so that X = U*S*V'.
In the case of svds, one will lose some information unless columns is equal to the size of the square matrix fulldata. In this case, I believe the original matrix cannot be reconstructed uniquely.
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));