Basically the sum function calculate the sum of the columns, that is to say if we have a 4x4 matrix we would get a 1X4 vector
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
sum(A)
ans =
34 34 34 34
But if I want to get the Summation of the rows then i have 2 methods, the first is to get the transpose of the matrix then get the summation of the transposed matrix,and finally get the transpose of the result...., The Second method is to use dimension argument for the Sum function "sum(A, 2)"
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
sum(A,2)
ans =
34
34
34
34
The problem is here I cannot understand how this is done, If anyone could please tell me the idea/concept behind this method,
It's hard to tell exactly how sum internally works, but we can guess it does something similar to this.
Matlab stores matrices (or N-dimensional arrays) in memory using column-major order. This means the order for the elements in memory for a 3 x 4 matrix is
1 4 7 10
2 5 8 11
3 6 9 12
So it first stores element (1,1), then (1,2), then (13), then (2,1), ...
In fact, this is the order you use when you apply linear indexing (that is, index a matrix with a single number). For example, let
A = [7 8 6 2
9 0 3 5
6 3 2 1];
Then A(4) gives 8.
With this in mind, it's easy to guess that what sum(A,1) does is traverse elements consecutively: A(1)+A(2)+A(3) to obtain the sum of the first column, then A(4)+A(5)+A(6) to sum the second column, etc. In contrast, sum(A,2) proceeds in steps of size(A,1) (3 in this example): A(1)+A(4)+A(7)+A(10) to compute the sum of the first row, etc.
As a side note, this is probably related with the observed fact that sum(A,1) is faster than sum(A,2).
I'm really not sure what you are asking. sum takes two inputs, the first of which is a multidimensional array A, say.
Now let's take sA = size(A), and d between 1 and ndims(A).
To understand what B = sum(A,d) does, first we find out what the size of B is.
That's easy, sB = sA; sB(d) = 1;. So in a way, it will "reduce" the size of A along dimension d.
The rest is trivial: every element in B is the sum of elements in A along dimension d.
Basically, sum(A) = sum(A,1) which outputs the sum of the columns in the matrix. 1 indicates the columns. So, sum(A,2) outputs the sum of the rows in the matrix. 2 indicating the rows. More than that, the sum command will output the entire matrix because there is only 2 dimensions (rows and columns)
Related
I just started learning Julia. I would like to ask how make taking slice of a row vector return a row vector?
I searched and could not find an answer.
In Matlab, taking a slice of a row vector returns a row vector as expected. But in Julia it returns an array. Version 1.5.3 (2020-11-09)
>julia
julia> x=[1 2 3 4 5 6]
1×6 Array{Int64,2}:
1 2 3 4 5 6
julia> x[1:4]
4-element Array{Int64,1}:
1
2
3
4
In Matlab
>> x=[1 2 3 4 5 6 7]
>> x(1:4)
ans =
1 2 3 4
What is the correct way in Julia to do this? i.e. a slice of row vector returns a row vector, and similarly a slice of column vector returns column vector.
What you have there, is not a row vector but a matrix with shape 1x6, that is, a 2-dimensional array. If you are interested in a real deep dive into how vectors are handled in Julia you can read this issue: https://github.com/julialang/julia/issues/4774 which is called "Taking vector transposes seriously". You can see that a lot of thought went into this design.
Julia slices will drop dimensions in a predictable way: the number of dimensions of the output is equal to the sum of dimensions of the input indices. In your case, x[1:4], the input index slice is 1D, therefore the output is 1D. If you want the output to be 2D, you need 1D+1D=2D input indices:
jl> x[1:1, 1:4]
1×4 Matrix{Int64}:
1 2 3 4
Note that the following produces a 1D array
jl> x[1, 1:4]
4-element Vector{Int64}:
1
2
3
4
That is because the first index is a scalar, which is 0-dimensional, so the output is 0D+1D=1D.
This is even preserved for empty arrays:
jl> x[1:0, 1:4]
0×4 Matrix{Int64}
This is still a matrix, even though it has size 0x4.
You should also be aware that in most cases you should prefer proper vectors: [1, 2, 3, 4, 5, 6] instead of 1xN matrices, [1 2 3 4 5 6].
Short and doubtful:
y = x[1:4]'
Longer and more educational:
If you pay close attention to the output of
x = [1 2 3 4 5 6]
You will see the conditionality of the array (!) is two:
1×6 Array{Int64,2}:
1 2 3 4 5 6
That is, because you have not collected your elements in a column, but forced it into a row. To use julia efficiently, try to use column vectors as in
y = [1,2,3,4,5,6]
Or rely more on julias' functions and use
z = collect(1:6)
Julia uses column-major layout. Each column of an array is a continues area of memory. This makes operations on columns faster than operations on rows. Other languages might have different layouts. As a matter of fact, FORTRAN and MatLab also utilize column-major arrays. The C programming languages on the other hand, uses a row major layout.
EDIT: Apparently I got lost while writing.
I believe the correct way in julia is to do it all in column vectors. There sure is a bit of algebra where this is not possible. But for most programs, it should not matter what orientation a vectors has. Therefore, in julia use a column vector.
As #2419 wrote, what you are getting with x=[1 2 3 4 5 6] is actually a one-row matrix, and Julia is more performant with column vectors.
That's said, there are of course legit uses of matrices ;-)
Here is the long story.. when you have a matrix and slice it such that the result is a single row, it is automatically converted to a column vector:
julia> x = [1 2 3 4; 10 20 30 40; 100 200 300 400]
3×4 Matrix{Int64}:
1 2 3 4
10 20 30 40
100 200 300 400
julia> a = x[2,:]
4-element Vector{Int64}:
10
20
30
40
However if you slice it to 2 or more rows, it remains a Matrix:
julia> b = x[[2,3],:]
2×4 Matrix{Int64}:
10 20 30 40
100 200 300 400
I feel myself a bit perplex with this choice, but it is like this, and it will not change now.
Note that to retrieve back a row vector with the first case it is very easy:
julia> transpose(a) # or, equivalently, `a'`
1×4 transpose(::Vector{Int64}) with eltype Int64:
10 20 30 40
Important! transpose is a matrix operation and works only with numerical matrices (or vectors).
If your matrix includes non-numerical elements, as strings, transpose would generate an error and you should instead use permutedims:
julia> x2 = [1 2 "c" 4; 10 20 "cc" 40; 100 200 300 "ddd"]
3×4 Matrix{Any}:
1 2 "c" 4
10 20 "cc" 40
100 200 300 "ddd"
julia> a2 = x2[2,:]
4-element Vector{Any}:
10
20
"cc"
40
julia> transpose(a2)
1×4 transpose(::Vector{Any}) with eltype Any:
Error showing value of type LinearAlgebra.Transpose{Any, Vector{Any}}:
ERROR: MethodError: no method matching transpose(::String)
# [...]
julia> permutedims(a2)
1×4 Matrix{Any}:
10 20 "cc" 40
However transpose is faster:
julia> using BenchmarkTools
julia> #btime transpose(a)
21.971 ns (1 allocation: 16 bytes)
1×4 transpose(::Vector{Int64}) with eltype Int64:
10 20 30 40
julia> #btime permutedims(a)
66.289 ns (2 allocations: 96 bytes)
1×4 Matrix{Int64}:
10 20 30 40
So, if you are sure your matrix is numerical, use transpose, otherwise use permutedims.
Let's say we have the following matrix
A=magic(4)
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
and we want to extract 3 submatrices, identified by the indexes for top left and bottom right corners. The indexes for a submatrix are contained in a row of the matrix i; columns 1 and 2 of i are the row indexes of the corners, columns 3 and 4 of i are the column indexes of the corners.
i.e.
i =
1 1 1 3
2 4 1 2
3 4 3 4
>> A(i(1,1):i(1,2),i(1,3):i(1,4))
ans =
16 2 3
>> A(i(2,1):i(2,2),i(2,3):i(2,4))
ans =
5 11
9 7
4 14
>> A(i(3,1):i(3,2),i(3,3):i(3,4))
ans =
6 12
15 1
The command A(i(,):i(,),i(,):i(,)) which I used to extract the submatrices is not very convenient, so I wonder is there a better way to do the job ?
If you don't want to type it all out then why not write a wrapper function?
A = magic(4);
S = #(r) A(i(r,1):i(r,2),i(r,3):i(r,4));
S(1)
S(2)
S(3)
If A may change after the definition of S then you would need to make it a parameter to the function.
S = #(A,r) A(i(r,1):i(r,2),i(r,3):i(r,4));
A = magic(4)
S(A,1)
S(A,2)
S(A,3)
Similarly if i may change then you would need to make it a parameter as well.
Edit
Unfortunately, contrary to my comment, if you want to perform assignment then A(I(r)) won't work exactly the same as what you've posted since this always returns an array instead of a matrix. One possible workaround is to use cell arrays in place of comma-separated-lists, but this isn't as elegant as the read only option. For example
S = #(r) {i(r,1):i(r,2) , i(r,3):i(r,4)};
s = S(1); A(s{:})
s = S(2); A(s{:})
s = S(3); A(s{:})
Following the same principle you could pre-define a cell array from i to make access one line.
s = arrayfun(#(r) {i(r,1):i(r,2),i(r,3):i(r,4)}, 1:size(i,1), 'UniformOutput', false);
A(s{1}{:})
A(s{2}{:})
A(s{3}{:})
data = reshape(1:21504,[256,4,21]);
data(:,5:4:end)
I test some indexes, such as:
data(:,5:4:end) ~= data(:,5:4:end,1)
data(:,5:4:end) ~= data(:,1,5:4:end)
So what is the meaning of data(:,5:4:end)?
I test some other indexes, such as:
data(1,1) == data(1,1,1)
data(1,1:3) == data(1,1:3,1)
And find some strange behavior ,such as data(1,1:10,1) returns error but data(1,1:10) is ok.
So What's happening here?
How can I understand this mechanism?
>> size(data)
ans =
256 4 21
data(1,1:10,1) selects column 1-10 from first row (all three dimensions are explicitly set), but there are only 4 columns. Therefore the error.
data(1,1:10), on the other hand, uses Linear indexing, which interpretes dimensions 2 and 3 as one long strung of values and selects its first 10 values.
Linear Indexing
What does this expression A(14) do?
When you index into the matrix A using only one subscript, MATLAB treats A as if its elements were strung out in a long column vector, by going down the columns consecutively, as in:
16
5
9
...
8
12
1
The expression A(14) simply extracts the 14th element of the implicit column vector. Indexing into a matrix with a single subscript in this way is often called linear indexing.
Here are the elements of the matrix A along with their linear indices:
matrix_with_linear_indices.gif
The linear index of each element is shown in the upper left.
From the diagram you can see that A(14) is the same as A(2,4).
The single subscript can be a vector containing more than one linear index, as in:
A([6 12 15])
ans =
11 15 12
Consider again the problem of extracting just the (2,1), (3,2), and (4,4) elements of A. You can use linear indexing to extract those elements:
A([2 7 16])
ans =
5 7 1
That's easy to see for this example, but how do you compute linear indices in general? MATLAB provides a function called sub2ind that converts from row and column subscripts to linear indices. You can use it to extract the desired elements this way:
idx = sub2ind(size(A), [2 3 4], [1 2 4])
ans =
2 7 16
A(idx)
ans =
5 7 1
(Copied from http://de.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html)
data(:, 5:4:end) will access all elements in the first dimension of data and starting from index 5 every 4th index until the last index in the second dimension of data. The syntax for this indexing technique can be explained like this:
data(startIndex:step:endIndex)
If data has more dimensions than you used for indexing, this will assume : for every dimension after that.
To sum up my question:
data=reshape(1:24,2,3,4)
data(:,:,1) =
1 3 5
2 4 6
data(:,:,2) =
7 9 11
8 10 12
data(:,:,3) =
13 15 17
14 16 18
data(:,:,4) =
19 21 23
20 22 24
Using this example you can know what Matlab doing:
data(:,1)
ans =
1
2
data(:,12)
ans =
23
24
data(:,[1,12])
ans =
1 23
2 24
data(:,5:4:end)
ans =
9 17
10 18
If you use data(:,13),it throws an error.
I have a vector of values which represent an index of a row to be removed in some matrix M (an image). There's only one row value per column in this vector (i.e. if the image is 128 x 500, my vector contains 500 values).
I'm pretty new to MATLAB so I'm unsure if there's a more efficient way of removing a single pixel (row,col value) from a matrix so I've come here to ask that.
I was thinking of making a new matrix with one less row, looping through each column up until I find the row whose value I wish to remove, and "shift" the column up by one and then move onto the next column to do the same.
Is there a better way?
Thanks
Yes, there is a solution which avoids loops and is thus faster to write and to execute. It makes use of linear indexing, and exploits the fact that you can remove a matrix entry by assigning it an empty value ([]):
% Example data matrix:
M = [1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20];
% Example vector of rows to be removed for each column:
vector = [2 3 4 1 3];
[r c] = size(M);
ind = sub2ind([r c],vector,1:c);
M(ind) = [];
M = reshape(M,r-1,c);
This gives the result:
>> M =
1 5 9 14 17
3 6 10 15 18
4 8 11 16 20
I have a matrix of 2d lets assume the values of the matrix
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
17 24 1 8 15
11 18 25 2 9
This matrix is going to be divided into three different matrices randomly let say
b =
17 24 1 8 15
23 5 7 14 16
c =
4 6 13 20 22
11 18 25 2 9
d =
10 12 19 21 3
17 24 1 8 15
How can i know the index of the vectors in matrix d for example in the original matrix a,note that the values of the matrix can be duplicated.
for example if i want to know the index of {10 12 19 21 3} in matrix a?
or the index of {17 24 1 8 15} in matrix a,but for this one should return only on index value?
I would appreciate it so much if you can help me with this. Thank you in advance
You can use ismember with the 'rows' option. For example:
tf = ismember(a, c, 'rows')
Should produce:
tf =
0
0
1
0
0
1
To get the indices of the rows, you can apply find on the result of ismember (note that it's redundant if you're planning to use this vector for matrix indexing). Here find(tf) return the vector [3; 6].
If you want to know the number of the row in matrix a that matches a single vector, you either use the method explained and apply find, or use the second output parameter of ismember. For example:
[tf, loc] = ismember(a, [10 12 19 21 3], 'rows')
returns loc = 4 for your example. Note that here a is the second parameter, so that the output variable loc would hold a meaningful result.
Handling floating-point numbers
If your data contains floating point numbers, The ismember approach is going to fail because floating-point comparisons are inaccurate. Here's a shorter variant of Amro's solution:
x = reshape(c', size(c, 2), 1, []);
tf = any(all(abs(bsxfun(#minus, a', x)) < eps), 3)';
Essentially this is a one-liner, but I've split it into two commands for clarity:
x is the target rows to be searched, concatenated along the third dimension.
bsxfun subtracts each row in turn from all rows of a, and the magnitude of the result is compared to some small threshold value (e.g eps). If all elements in a row fall below it, mark this row as "1".
It depends on how you build those divided matrices. For example:
a = magic(5);
d = a([2 1 2 3],:);
then the matching rows are obviously: 2 1 2 3
EDIT:
Let me expand on the idea of using ismember shown by #EitanT to handle floating-point comparisons:
tf = any(cell2mat(arrayfun(#(i) all(abs(bsxfun(#minus, a, d(i,:)))<1e-9,2), ...
1:size(d,1), 'UniformOutput',false)), 2)
not pretty but works :) This would be necessary for comparisons such as: 0.1*3 == 0.3
(basically it compares each row of d against all rows of a using an absolute difference)