Matrix transposition without using loops..? - matrix

How to transpose a matrix without using any kind of loops. If it's nxn we can make the diagonal as base and shift elements. But for nxm matrix I think this solution is not feasible.
Anyway, to read or store we need to use loops right...??
Any solution without loops..??

If you have known at the beginning the dimension of the matrix, then you will not need any loop. Because you just can swap the matrix position to transpose the matrix overall. In this first condition you don't need loop as well even if the dimension is m x n.
But if you don't know the dimension of matrix in the beginning, then we definitely will need loop to iterate the matrix to read some position and swap to other position in process of transposing matrix.

For storing the entire transposed matrix, you definitely need to use a loop. This is not really a big deal since storing a matrix uses loops anyway, as you need to loop through the members of the matrix to store it.
If you are just reading it, you can use the definition of a matrix transpose and just translate the indicies. For example, in C:
int getTransposedElement(int i,int j, int** originalMatrix) {
return originalMatrix[j,i];
}
If you are using a language with classes and polymorphism, you can create a new matrix class that does this automatically. This has the additional benefit that it avoids copying the original matrix, which saves memory and allows changes to the transposed matrix to be reflected in the original matrix.

Related

Julia - How do I add a matrix to a list of matrices

I'm new to Julia, and I am currently working on a model where I need to add a matrix to list of matrices. I am trying to accomplish this with:
push!(BranchDomainNew, BranchDomain[k])
Where BranchDomainNew is a 1x7 matrix (3D) made up of matrices. I am trying to append BranchDomain[k] (another matrix of the same dimensions) to this list. Ultimately, my goal is to have BranchDomainNew be 8 matrices long, with the last index containing BranchDomain[k].
Here's the error I keep getting:
MethodError: no method matching push!(::Matrix{Any}, ::Matrix{Bool})
I also tried using append!(), which unfortunately also did not work - I got the same error (except append! instead of push!). I'd love to know why these methods don't work for this, and how I can accomplish this goal. Also, I am working with version v"1.7.2". Thanks
You cannot push! or append! elements to a matrix, because matrices are 2-dimensional entities, and adding single elements could ruin its shape, and is therefore not allowed. You can instead concatenate rows or columns using hcat or vcat.
But it looks like what you really should use is a Vector, not a 1xN Matrix.
So make sure that BranchDomainNew is a Vector of matrices, instead of a Matrix of matrices. Then you can push! and append! all you like.
You did not show how you made your matrix, but it is possible that you did something like this:
BranchDomainNew = [mat1 mat2 mat3] # create 1x3 Matrix
when you should have done
BranchDomainNew = [mat1, mat2, mat3] # create length 3 Vector
It is a common mistake for many new Julia users to use 1xN or Nx1 matrices, when they should actually use a length-N vector. For example, they often initialize arrays as zeros(N, 1), when they should use zeros(N)
The difference is important, and in almost all cases a vector is better.

How to reduce a matrix rank using some zeros?

I'm working of matrices having rank >1. It is possible to reduce the rank of a matrix to rank=1 substituing some values to zeros?
Rank in a matrix refers to how many of the column vectors are independent and non-zero (Or row vectors, but I was taught to always use column vectors). So, if you're willing to lose a lot of the information about the transformation your matrix is defining, you could create a matrix that's just the first non-zero column of your matrix, and everything else set to zero. Guaranteed to be rank 1.
However, that loses a whole lot of information about the transformation. Perhaps a more useful thing to do would be project your matrix onto a space of size 1x1. There are ways to do this in such a way that can create an injection from your matrix to the new space, guaranteeing that no two matrices produce an equivalent result. The first one that comes to mind is:
Let A be an n x m matrix
Let {P_i} be the ith prime number.
Let F(A) = {sum from i to (n * m)} {P_i} ^ (A_(i div n),(i mod m))
While this generates a single number, you can think of a single number as a 1 x 1 matrix, which, if non-zero, has rank 1.
All that being said, rank 1 matrices are kinda boring and you can do cooler stuff with matrices if you keep it at rank != 1. In particular, if you have an n x n matrix with rank n, a whole world of possibility opens up. It really depends on what you want to use these matrices for.
You might want to look at the singular value decomposition, which can be used to write your matrix as a sum of weighted outer products (see here). Choosing only the highest-weighted component of this sum will give you the closest rank-1 approximation to the decomposed matrix.
Most common linear algebra libraries (Eigen, OpenCV, NumPy) have an SVD implementation.

sub2ind all x and y coordinates of a matrix

I am a quite newbie on matlab and i have a simple issue that is disturbing me,
I want to know if its possible to covert all the subscripts of a matrix to linear indices.
when using SUB2IND i must inform de x and y coordinates, but i want to convert all at the same time.
i can use function FIND which returns two vectors x and y and this way i can use SUB2IND succesfully, but FIND only returns the x and y coordinates of nonzero elements.
is there a smart way to do this?
If you want all of the elements of an array A as linear subscripts, this can be done simply via:
IND = 1:numel(A);
This works for any size or dimension array.
More on array indexing in Matlab, including the difference between linear indexing and logical indexing. When you use find you're essentially using logical indexing to obtain linear indexing. The find function can be used to reliably obtain all of your linear indices, via IND = find(A==A);, but this is horrendously inefficient.
you don't need to convert, just use a single number \ 1-D vector when accessing elements of your matrix. For example, given a 5x5 matrix M
M=magic(5);
you can access the last element using M(5,5) or using M(25) ...
similarly M(21:25) will give you the info of M(1,5),M(2,5),...M(5,5).

Fastest way to check if a vector increases matrix rank

Given an n-by-m matrix A, with it being guaranteed that n>m=rank(A), and given a n-by-1 column v, what is the fastest way to check if [A v] has rank strictly bigger than A?
For my application, A is sparse, n is about 2^12, and m is anywhere in 1:n-1.
Comparing rank(full([A v])) takes about a second on my machine, and I need to do it tens of thousands of times, so I would be very happy to discover a quicker way.
There is no need to do repeated solves IF you can afford to do ONE computation of the null space. Just one call to null will suffice. Given a new vector V, if the dot product with V and the nullspace basis is non-zero, then V will increase the rank of the matrix. For example, suppose we have the matrix M, which of course has a rank of 2.
M = [1 1;2 2;3 1;4 2];
nullM = null(M')';
Will a new column vector [1;1;1;1] increase the rank if we appended it to M?
nullM*[1;1;1;1]
ans =
-0.0321573705742971
-0.602164651199413
Yes, since it has a non-zero projection on at least one of the basis vectors in nullM.
How about this vector:
nullM*[0;0;1;1]
ans =
1.11022302462516e-16
2.22044604925031e-16
In this case, both numbers are essentially zero, so the vector in question would not have increased the rank of M.
The point is, only a simple matrix-vector multiplication is necessary once the null space basis has been generated. If your matrix is too large (and the matrix nearly of full rank) that a call to null will fail here, then you will need to do more work. However, n = 4096 is not excessively large as long as the matrix does not have too many columns.
One alternative if null is too much is a call to svds, to find those singular vectors that are essentially zero. These will form the nullspace basis that we need.
I would use sprank for sparse matrixes. Check it out, it might be faster than any other method.
Edit : As pointed out correctly by #IanHincks, it is not the rank. I am leaving the answer here, just in case someone else will need it in the future.
Maybe you can try to solve the system A*x=v, if it has a solution that means that the rank does not increase.
x=(B\A)';
norm(A*x-B) %% if this is small then the rank does not increase

Principal component analysis m-by-n matrix implementation

Does anyone know how to implement the Principal component analysis (PCA) on a m-by-n matrix in matlab for normalization?
Assuming each column is a sample (that is, you have n samples each of dimension m), and it's stored in a matrix A you first have to subtract off the column means:
Amm = bsxfun(#minus,A,mean(A,2));
then you want to do an eigenvalue decomposition on 1/size(Amm,2)*Amm*Amm' (you can use 1/(size(Amm,2)-1) as a scale factor if you want an interpetation as an unbiased covariance matrix) with:
[v,d] = eig(1/size(Amm,2)*Amm*Amm');
And the columns of v are going to be your PCA vectors. The entries of d are going to be your corresponding "variances".
However, if your m is huge then this is not the best way to go because storing Amm*Amm' is not practical. You want to instead compute:
[u,s,v] = svd(1/sqrt(size(Amm,2))*Amm,'econ');
This time u contains your PCA vectors. The entries of s are related to the entries of d by a sqrt.
Note: there's another way to go if m is huge, i.e. computing eig(1/size(Amm,2)*Amm
'*Amm); (notice the switch of transposes as compared to above) and doing a little trickery, but it's a longer explanation so I won't get into it.

Resources