Matrix to Vector Conversion in Matlab - matlab

I have a MxN Matrix and would like to convert into a vector MNx1 with all the elements of the row from the Matrix as the elements of the Vector.
I tried using reshape but I was not successful.
Here is the small code snippet and the expected result.
S=[0 1
1 0
1 1
1 1 ]
Expected Result:
S_prime= [ 0 1 1 0 1 1 1 1]
P.S: Using a loop and concatenation is not an option, I am sure there is a easy straight forward technique, which I am not aware.
Thanks

You could try transposing S and using (:)
S = S'
S_prime = S(:)
or for a row vector:
S_prime = S(:)'

Reshape takes the elements column wise so transpose S before reshaping.
>> reshape(S',1,[])
ans =
0 1 1 0 1 1 1 1

reshape(S',1,prod(size(S)))
or shortcut
reshape(S',1,[])
But the question makes me wonder what your original problem is, and if this way really is part of the correct solution to the original problem.

Octave has a very nice function: vec().
The document at http://www.mathcs.emory.edu/~nagy/courses/fall10/515/KroneckerIntro.pdf states the following.
vector x = vec(X)
can be obtained with the MATLAB statement: x = reshape(X, q*n, 1)

Related

Output a matrix size n x m, 1 when the sum of the indices is even, 0 otherwise

I'm attempting the following as a hobby, not as homework. In Computer Programming with MATLAB: J. Michael Fitpatrick and Akos Ledeczi, there is a practice problem that asks this:
Write a function called alternate that takes two positive integers, n and m, as input arguments (the function does not have to check the format of the input) and returns one matrix as an output argument. Each element of the n-by-m output matrix for which the sum of its indices is even is 1.
All other elements are zero.
A previous problem was similar, and I wrote a very simple function that does what it asks:
function A = alternate(n,m)
A(1:n,1:m)=0;
A(2:2:n,2:2:m)=1;
A(1:2:n,1:2:m)=1;
end
Now my question is, is that good enough? It outputs exactly what it asks for, but it's not checking for the sum. So far we haven't discussed nested if statements or anything of that sort, we just started going over very basic functions. I feel like giving it more functionality would allow it to be recycled better for future use.
Great to see you're learning, step 1 in learning any programming language should be to ensure you always add relevant comments! This helps you, and anyone reading your code. So the first improvement would be this:
function A = alternate(n,m)
% Function to return an n*m matrix, which is 1 when the sum of the indices is even
A(1:n,1:m)=0; % Create the n*m array of zeros
A(2:2:n,2:2:m)=1; % All elements with even row and col indices: even+even=even
A(1:2:n,1:2:m)=1; % All elements with odd row and col indicies: odd+odd=even
end
You can, however, make this more concise (discounting comments), and perhaps more clearly relate to the brief:
function A = alternate(n,m)
% Function to return an n*m matrix, which is 1 when the sum of the indices is even
% Sum of row and col indices. Uses implicit expansion (R2016b+) to form
% a matrix from a row and column array
idx = (1:n).' + (1:m);
% We want 1 when x is even, 0 when odd. mod(x,2) is the opposite, so 1-mod(x,2) works:
A = 1 - mod( idx, 2 );
end
Both functions do the same thing, and it's personal preference (and performance related for large problems) which you should use.
I'd argue that, even without comments, the alternative I've written more clearly does what it says on the tin. You don't have to know the brief to understand you're looking for the even index sums, since I've done the sum and tested if even. Your code requires interpretation.
It can also be written as a one-liner, whereas the indexing approach can't be (as you've done it).
A = 1 - mod( (1:n).' + (1:m), 2 ); % 1 when row + column index is even
Your function works fine and output the desired result, let me propose you an alternative:
function A = alternate(n,m)
A = zeros( n , m ) ; % pre-allocate result (all elements at 0)
[x,y] = meshgrid(1:m,1:n) ; % define a grid of indices
A(mod(x+y,2)==0) = 1 ; % modify elements of "A" whose indices verify the condition
end
Which returns:
>> alternate(4,5)
ans =
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
initialisation:
The first line is the equivalent to your first line, but it is the cannonical MATLAB way of creating a new matrix.
It uses the function zeros(n,m).
Note that MATLAB has similar functions to create and preallocate matrices for different types, for examples:
ones(n,m) Create
a matrix of double, size [n,m] with all elements set to 1
nan(n,m) Create a
matrix of double, size [n,m] with all elements set to NaN
false(n,m) Create a
matrix of boolean size [n,m] with all elements set to false
There are several other matrix construction predefined function, some more specialised (like eye), so before trying hard to generate your initial matrix, you can look in the documentation if a specialised function exist for your case.
indices
The second line generate 2 matrices x and y which will be the indices of A. It uses the function meshgrid. For example in the case shown above, x and y look like:
| x = | y = |
| 1 2 3 4 5 | 1 1 1 1 1 |
| 1 2 3 4 5 | 2 2 2 2 2 |
| 1 2 3 4 5 | 3 3 3 3 3 |
| 1 2 3 4 5 | 4 4 4 4 4 |
odd/even indices
To calculate the sum of the indices, it is now trivial in MATLAB, as easy as:
>> x+y
ans =
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
Now we just need to know which ones are even. For this we'll use the modulo operator (mod) on this summed matrix:
>> mod(x+y,2)==0
ans =
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
This result logical matrix is the same size as A and contain 1 where the sum of the indices is even, and 0 otherwise. We can use this logical matrix to modify only the elements of A which satisfied the condition:
>> A(mod(x+y,2)==0) = 1
A =
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
Note that in this case the logical matrix found in the previous step would have been ok since the value to assign to the special indices is 1, which is the same as the numeric representation of true for MATLAB. In case you wanted to assign a different value, but the same indices condition, simply replace the last assignment:
A(mod(x+y,2)==0) = your_target_value ;
I don't like spoiling the learning. So let me just give you some hints.
Matlab is very efficient if you do operations on vectors, not on individual elements. So, why not creating two matrices (e.g. N, M) that holds all the indices? Have a look at the meshgrid() function.
Than you might be able find all positions with an even sum of indices in one line.
Second hint is that the outputs of a logic operation, e.g. B = A==4, yields a logic matrix. You can convert this to a matrix of zeros by using B = double(B).
Have fun!

Why code is not giving proper results Matlab?

I know this type of questions may have been answered before but i am a beginner in matlab so please bear my kiddy questions.
I wan to generate a 11*12 matrix from a set of values. i have five different vectors named X,Y Z,u,v.
my code is:
A=zeros(12,11);
for i=1:6
A=[X(i) Y(i) Z(i) 1 0 0 0 0 (-u(i)*X(i)) (-u(i)*Y(i)) (-u(i)*Z(i)),0 0 0 0 X(i) Y(i) Z(i) 1 (-v(i)*X(i)) (-v(i)*Y(i)) (-v(i)*Z(i))];
end
Here for each iteration i want to fill two rows. So it becomes 12 rows in total. But the problem is that
1. it is giving me 22*1 matrix
2. It is giving wrong values
That means it is appending columns in each iteration that i do not want.
Kindly help me to find a 11*12 matrix. Thanks
You are assigning a completely new matrix to A on every iteration, so this will result in what you get.
What you want is to replace the rows each iteration. You can index the matrix to do this:
A(1,:) = [1 2 3 4];
This, for example, will replace the first row with the given values. So you can use
A(i*2-1,:)=[X(i) Y(i) Z(i) 1 0 0 0 0 (-u(i)*X(i)) (-u(i)*Y(i)) (-u(i)*Z(i))];
A(i*2,:)=[0 0 0 0 X(i) Y(i) Z(i) 1 (-v(i)*X(i)) (-v(i)*Y(i)) (-v(i)*Z(i))];
Unfortunately I don't have Matlab here now to see if you could combine those into one line by indexing A(i*2-1:i*2,:) or not.

Matlab:Efficient assignment of values in a sparse matrix

I'm working in Matlab and I have the next problem:
I have a B matrix of nx2 elements, which contains indexes for the assignment of a big sparse matrix A (almost 500,000x80,000). For each row of B, the first column is the column index of A that has to contain a 1, and the second column is the column index of A that has to contain -1.
For example:
B= 1 3
2 5
1 5
4 1
5 2
For this B matrix, The Corresponding A matrix has to be like this:
A= 1 0 -1 0 0
0 1 0 0 -1
1 0 0 0 -1
-1 0 0 1 0
0 -1 0 0 1
So, for the row i of B, the corresponding row i of A must be full of zeros except on A(i,B(i,1))=1 and A(i,B(i,2))=-1
This is very easy with a for loop over all the rows of B, but it's extremely slow. I also tried the next formulation:
A(:,B(:,1))=1
A(:,B(:,2))=-1
But matlab gave me an "Out of Memory Error". If anybody knows a more efficient way to achieve this, please let me know.
Thanks in advance!
You can use the sparse function:
m = size(B,1); %// number of rows of A. Or choose larger if needed
n = max(B(:)); %// number of columns of A. Or choose larger if needed
s = size(B,1);
A = sparse(1:s, B(:,1), 1, m, n) + sparse(1:s, B(:,2), -1, m, n);
I think you should be able to do this using the sub2ind function. This function converts matrix subscripts to linear indices. You should be able to do it like so:
pind = sub2ind(size(A),1:n,B(:,1)); % positive indices
nind = sub2ind(size(A),1:n,B(:,2)); % negative indices
A(pind) = 1;
A(nind) = -1;
EDIT: I (wrongly, I think) assumed the sparse matrix A already existed. If it doesn't exist, then this method wouldn't be the best option.

MATLAB Matrix construction advice

I need to use MATLAB to solve the following matrix equation:
This matrix is nxn, and I can construct most of the matrix using the following MATLAB code:
e = ones(n,1);
A = h^(-2)*spdiags([e (h^2 - 2)*e e], [-1 0 1], n, n);
What's a good way to change the first and last row? Perhaps it would be nice to just add a nice matrix B with the first row as [ 2/h 1/h^2 0 ... 0 0 0 ] and the last row as [ 0 0 0 ... 0 1/h^2 (2h + 1)/h^2] and just take A + B. How would you do this though?
I think the simplest way is best in this case as you aren't modifying much of the matrix you have created:
A(1,:)=A(1,:)+[2/h 1/h^2 zeros(1,n-2)];
A(n,:)=A(n,:)+[zeros(1,n-2) 1/h^2 2/h];
or even replace individual elements rather than rows.

Entropy of Matrix using Matlab

Given a matrix A with dimension m x n and the entries in the matrix lies [0,1]
For example
A = [0.5 0 0 0.5 0
0 0.5 0 0 0.5
1 0 0 0 0]
I would like to calculate sum(sum(a_ij log(a_ij))), where a_ij is the i th row and j th col entry in the matrix A. Since there exist an 0 entry in the matrix, i always get NAN as a result.
How do i consider only non-zero entries to calculate sum(sum(a_ij log(a_ij))) [entropy of the matrix].
To consider only specific elements of a matrix you can use logical indexing. For example if you only want to select non-zero entries of A you can use A(A~=0). So for your problem the solution can be written:
sum(A(A~=0).*log(A(A~=0)));
EDIT: wow that is some kind of coincidence, I've just seen your comment after posting this. Well, glad you've worked it out yourself.
If it is a very large array:
sum(A.*log(A+eps))
which should be faster than indexing.
Another possibility:
x = A(:);
E = x' * log(x + (x==0))