>> [1 2]
ans =
1 2
>> [1 ,2]
ans =
1 2
>>
It looks the same,is that true?
Nope; there's no difference. See here for more info:
The simplest way to create a matrix in
MATLAB is to use the matrix
constructor operator, []. Create a row
in the matrix by entering elements
(shown as E below) within the
brackets. Separate each element with a
comma or space:
row = [E1, E2, ..., Em] row = [E1 E2 ... Em]
Both produce a row vector when applied to scalar elements, i.e., horizontal concatenation. A space is equivalent to a comma inside square brackets to construct an array or vector. In fact, you can use spaces and commas at will within such an expression, although this may be best not done as it will be confusing to read. For example, this is difficult for me to read:
A = [1 2,3, 4 , 5 6 7, 8]
Far easier to read is either one of these alternatives:
A = [1 2 3 4 5 6 7 8]
A = [1,2,3,4,5,6,7,8]
Had you separated the elements with ; instead, this would produce vertical concatenation, which is a different animal. You can also build up arrays using these separators. So to create a 2x3 array,
A = [1 2 3;4 5 6]
A =
1 2 3
4 5 6
If you have doubt in the future test it by ISEQUAL function:
>> a=[1 2];
>> b=[1,2];
>> isequal(a,b)
ans =
1
Related
This question already has answers here:
How to obtain the mirror image of an array (MATLAB)?
(4 answers)
Closed 2 years ago.
During my course I came across that expression:
A(:,end:-1:1)
I have trouble to understand and read the morphemic structure of the 2nd Operand "end;-1;1"
Lets take the example:
A=[1 2 3; 4 5 6; 7 8 9]
I am aware of:
A(:).. Outputs [1 2 3; 4 5 6; 7 8 9] as rows. Operator is :.
A(1,:).. Outputs [1 2 3; 4 5 6; 7 8 9] as columns Operator is , then , .
A(:,1).. Outputs [1 2 3; 4 5 6; 7 8 9] as rows. Operator is , beforehand : .
A(:,end:-1:1)
Output in Matlab show me: 3x3 Matrix.
How am I supposed to read the structure?
Graphem: : ..show me the rows,
Graphem: end:-1 .. ??
Graphem: :1 ..
Somehow ":" was for me the operator for show all of the elements.
It makes sense to me that the "Operand1 , Operand2" shows me the 2 Dimensional Matrix.
First Idea:
The end:-1:1 expression seemed to me like a loop. So -1, 0, 1 => **3x Elements** ?
But when I type
A(1,end:3)
it only shows me the 3rd row.
Second Idea:
A(end:-1:1,1)
It shows me the inverted Matrix..
My background:
I am a undergraduate student from the field of language.
I build in my freetime the 8-Bit Sap1 according Ben Eater.
So I am familiar with program memory or instruction memory.
I understand only the result, but not how it is achieved by the MATLAB compiler.
Someone said to me that the "Matrixaddressing is somehow optimized".
Looking forward to a helpful answer in each step. :)
Thanks in advance!
The end keyword in matrix indexing indicates index of last element in the corresponding dimension. So, A(:,end:-1:1) simply means A(:, size(A, 2):-1:1), which in you example (A=[1 2 3; 4 5 6; 7 8 9]), is equivalent to A(:, 3:-1:1).
But to understand what it does, you need to know what 3:-1:1 does. It creates a subrange. You already know 1:3 creates [1, 2, 3]. 1:3 is simplified form of 1:1:3: rangeStrart:increment:rangeEnd. Now, 3:1 or 3:1:1 creates an empty vector, because rangeStart is greater than rangeEnd. To create [3, 2, 1] you need to use a negative step: 3:-1:1.
So, A(:,end:-1:1) means A(:, [3, 2, 1]), which inverts order of rows of A. Also, A(:,end:3) means A(:, 3:3) and eventually A(:, 3), which returns 3rd row of A.
Edit: about your misunderstandings, addressed by #CrisLuengo
I am aware of:
A(:).. Outputs [1 2 3; 4 5 6; 7 8 9] as rows. Operator is :.
A(1,:).. Outputs [1 2 3; 4 5 6; 7 8 9] as columns Operator is , then , .
A(:,1).. Outputs [1 2 3; 4 5 6; 7 8 9] as rows. Operator is ,beforehand : .
A(3, 2) is the element in the 3,2 position (third row, second column) of A
A(1, :) is equivalent to A(1, 1:size(A, 2)) and A(1, 1:end) and is the first row of A
A(:, 1) is equivalent to A(1:size(A, 1), 1) and A(1:end, 1) and is the first column of A
A(:) is equivalent to A(1:numel(A)) and is a single column containing all elements of A
In MATLAB, when accessing an array, it is accessed as A(row#,col#). row# and col# can either be integers or a vector of integers. If they are integers then one spot in the matrix is accessed. If they are vectors then MATLAB will loop through the vector and choose spots in A which correspond to the integers in the vector.
end:-1:1 creates a vector which contains the integers ranging from the number of columns (in this case because you put this vector in the col section: A(row#,col#)) to 1. Ex: 4x5 matrix, end:-1:1 would be [5 4 3 2 1].
When you put : in the row part of the matrix, that means you access all rows of the matrix.
Here's an example of A(:,end:-1:1)
The col# vector (:) is [1 2 3] and the row# vector (end:-1:1) is [3 2 1]
A = [1 2 3;
4 5 6;
7 8 9]
A(:,end:-1:1)
[3, 5, 7]
I think you're overthinking this slightly.
If we have a vector
A = [1 2 3]
and we call A(end:-1:1), then we get a vector [3 2 1]. The indexing has returned the same vector, with the values reversed. If we now have a matrix
A = [1 2 3; 4 5 6; 7 8 9]
and call A(:, end:-1:1), we get the matrix with the same values in each row, but now the columns have been reversed to give
A(:, end:-1:1) = [3 2 1; 6 5 4; 9 8 7].
Recall what the colon means in this context.
If we define a vector, v = (1:10), we get a vector with the first element being 1, the last element being 10 and each value in between being integers in steps of 1. If we instead define v = (1:2:10), we get the same, but the elements are separated by 2, not 1.
end:-1:1 is a vector made in just the same way. The first number is the final element in the row of A, and the final number is the first element in the row. Each number is separated by a value of -1. If we try
v = 10:-1:1
we get [10 9 8 7 6 5 4 3 2 1]. If we call v(2:4) we get the second, third and fourth elements of v. If we call v(1:end), we simply get v. If we call v(end:-1:1), we return v, with the elements in the reversed order.
Edit A typo.
I am currently working on a stenography assignment on how to embed secret image to a cover image using Wang's algorithm. Basically i just want to change for eg:
3d matrix
A(:,:,1) = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7];
A(:,:,3) = [7 9 3; 4 5 9; 1 9 9];
To
Str = '578019436104356987793459199'
and also vice-versa if anybody can help out.
Another way is to just use sprintf. You first need to transpose each slice independently, so the call to permute as per Ander's answer will get to that point. After you can just supply a single format string of %d (integer) and the actual permuted matrix and it will unroll all elements column-wise and concatenate all of the numbers together. The additional advantage is that you no longer need to assume that only one digit occupies each matrix element:
str = sprintf('%d', permute(A, [2 1 3]));
Example
>> str = sprintf('%d', permute(A, [2 1 3]))
str =
578019436104356987793459199
>> class(str)
ans =
char
However, to reconstruct the matrix, you will have to assume that there's one element per matrix. In this case, you could use the undocumented sprintfc function that can output one cell per character, then convert the characters to numbers with str2double. Finally, reshape your matrix and undo the transpose:
A2 = permute(reshape(str2double(sprintfc('%c', str)), size(A)), [2 1 3]);
Example
>> A2 = permute(reshape(str2double(sprintfc('%c', str)), size(A)), [2 1 3])
A2(:,:,1) =
5 7 8
0 1 9
4 3 6
A2(:,:,2) =
1 0 4
3 5 6
9 8 7
A2(:,:,3) =
7 9 3
4 5 9
1 9 9
Because of the order of the unrolling of MATLAB matrices, your problem is slightly less straightforward than it may seem. You need to use reshape and permute to make it work.
str=arrayfun(#num2str,reshape(permute(A,[2 1 3]),[],1,1)).';
A2=permute(reshape(arrayfun(#str2double,str),[size(A)]),[2 1 3]);
isequal(A2,A)
This of course assumes what #Sardar comments in your question: all numbers have single digits (i.e. are integers range 0-9)
Say we want to concatenate two matrices
a=[2 3 6] , b=[0 9 3 2 8 2]
but we don't want any repetitive elements in the concatenated matrix.
in other words we want c to be
c=[2 3 6 0 9 8]
Is there a built-in function that does that for us?
% You could use the union function to accomplish this
a = [2 3 6]; % array a
b = [0 9 3 2 8 2]; % array b
% Use the union function to concatenate a and b. It lists an item that appears in either array once.
c = union(a,b, 'stable'); % adding 'stable' keeps your current order
I have a Matrix of size M by N in which each row has some zero entries. I want to create M row vectors such that each of the vector contains the non zero elements of each row. For example if I have the following Matrix
A=[0 0 0 5;0 0 4 6;0 1 2 3;9 10 2 3]
I want four different row vectors of the following form
[5]
[4 6]
[1 2 3]
[9 10 2 3]
This can be done with accumarray using an anonymous function as fourth input argument. To make sure that the results are in the same order as in A, the grouping values used as first input should be sorted. This requires using (a linearized version of) A transposed as second input.
ind = repmat((1:size(A,2)).',1,size(A,2)).';
B = A.';
result = accumarray(ind(:), B(:), [], #(x){nonzeros(x).'});
With A = [0 0 0 5; 0 0 4 6; 0 1 2 3; 9 10 2 3]; this gives
result{1} =
5
result{2} =
4 6
result{3} =
1 2 3
result{4} =
9 10 2 3
Since Matlab doesn't support non-rectangular double arrays, you'll want to settle on a cell array. One quick way to get the desired output is to combine arrayfun with logical indexing:
nonZeroVectors = arrayfun(#(k) A(k,A(k,:)~=0),1:size(A,1),'UniformOutput',false);
I used the ('UniformOutput',false) name-value pair for the reasons indicated in the documentation (I'll note that the pair ('uni',0) also works, but I prefer verbosity). This input produces a cell array with the entries
>> nonZerosVectors{:}
ans =
5
ans =
4 6
ans =
1 2 3
ans =
9 10 2 3
Is there any easy way to concatenate matrices with unequal dimensions using zero padding?
short = [1 2 3]';
long = [4 5 6 7]';
desiredResult = horzcat(short, long);
I would like something like:
desiredResult =
1 4
2 5
3 6
0 7
Matrices in MATLAB are automatically grown and padded with zeroes when you assign to indices outside the current bounds of the matrix. For example:
>> short = [1 2 3]';
>> long = [4 5 6 7]';
>> desiredResult(1:numel(short),1) = short; %# Add short to column 1
>> desiredResult(1:numel(long),2) = long; %# Add long to column 2
>> desiredResult
desiredResult =
1 4
2 5
3 6
0 7
EDIT:
I have edited my earlier solution so that you won't have to supply a maxLength parameter to the function. The function calculates it before doing the padding.
function out=joinUnevenVectors(varargin)
%#Horizontally catenate multiple column vectors by appending zeros
%#at the ends of the shorter vectors
%#
%#SYNTAX: out = joinUnevenVectors(vec1, vec2, ... , vecN)
maxLength=max(cellfun(#numel,varargin));
out=cell2mat(cellfun(#(x)cat(1,x,zeros(maxLength-length(x),1)),varargin,'UniformOutput',false));
The convenience of having it as a function is that you can easily join multiple uneven vectors in a single line as joinUnevenVectors(vec1,vec2,vec3,vec4) and so on, without having to manually enter it in each line.
EXAMPLE:
short = [1 2 3]';
long = [4 5 6 7]';
joinUnevenVectors(short,long)
ans =
1 4
2 5
3 6
0 7
Matlab automatically does padding when writing to a non-existent element of a matrix.
Therefore, another very simple way of doing this is the following:
short=[1;2;3];
long=[4;5;6;7];
short(1:length(long),2)=long;