Sum of sparse vectors: bug or feature? - arrays

I recently stumbled upon the following behavior in MATLAB R2022a:
>> a = sparse(1,2,1)
a =
(1,2) 1
>> b = sparse(2,1,18)
b =
(2,1) 18
>> a+b
ans =
(2,1) 18
(1,2) 1
(2,2) 19
The presence of the (2,2) element with value 19 is quite puzzling. Intuitively, I would have expected to get either a zero (no element) or an error indicating that the vectors' sizes are not compatible. I couldn't find an explanation for this behavior in the documentation.
So, is this a bug or a feature?

This is due to implicit broadcasting and expected behaviour, also for full() arrays. Compare:
bsxfun(#plus, [0 1], [0; 18])
ans =
0 1
18 19
(I'm running R2007b, so need bsxfun() instead of implicit broadcasting).
What happens with unequal-sized vectors is that they are broadcast ("extended") into the appropriate size for addition, see e.g. this blog post on an in-depth explanation.
Verbosely writing our toy example
a = [0 1]
b = [ 0
18]
a + b = [0 1] + [ 0
18]
% Is broadcast to
= [0 1 [ 0 0
0 1] + 18 18]
% element wise addition
= [ 0 1
18 19]

This is in fact similarly happening with full arrays, i.e. not restricted to sparse vectors, and this is normal behavior according to the documentation (see the Add Row and Column Vector section).

Related

Combining two matrices using ismember condition in MATLAB

I have a matrix A of size 1x10575 and another matrix B of size 13462x30974. All values of A are members of B. I would like to obtain a new matrix C of size 13462x10575 with the following condition.
If the value of B is a member of A, then return all values in the respective column of B. If A is not a member of B then do not respect this column anymore.
This would be an example of how the matrices could look like:
A = [1 2 3 4 5 6; 11 12 13 14 15 16; 21 22 23 24 25 26];
B = [1 2 5 6];
The output should look like:
C = [1 2 5 6; 11 12 14 15; 21 22 24 25];
I tried the following code, yet it returns the output C in the wrong format (1x417281728).
[isMatch, index] = ismember(B(1, :), A);
C = nan(size(B, 1), numel(A));
C(:, index(isMatch)) = B(:, isMatch);
What you basically want to do is the following: "For each element in the array A, check whether this element exists in B, and then return the entire column." So your guess with ismember was completely correct, as you want to check whether A is a member of B. For your example, the result would be:
1 1 0 0 1 1
0 0 0 0 0 0
0 0 0 0 0 0
So, you have to collapse all these indices into a single array, which says that there is at least one member which has a binary of 1. This you can do using the any command, which basically checks that there exists at least one TRUE in the considered dimension. So ultimately you end up with:
C = A(:,any(ismember(A,B),1))
[Note that in your example you have changed A and B, so in the code I posted it is also changed].

Can't understand some array syntax

I found a MATLAB code like this one:
x = [1, ([1:(m-1)].^a)];
where a and m are scalar.
Could somebody explain that? I'm not so familiar with the MATLAB programming language.
1:(m-1) creates and array from 1 to m-1 in steps of 1.
.^a raises each element in the previous array to the power a (^ is a regular power and tries to compute the matrix power, the . makes operations element-wise, i.e. raise each element to power a instead of the whole matrix)
[1, y] is simply the array y with a 1 prepended as first element.
Putting this all together we find that x is an array which starts with 1, followed by an integer array 1:(m-1) with each element raised to the power a.
m=5;a=3;
x = [1, ([1:(m-1)].^a)]
x =
1 1 8 27 64
Broken down in steps:
tmp = 1:(m-1)
tmp =
1 2 3 4
tmp2 = tmp.^a
ans =
1 8 27 64
x = [1 tmp2]
x =
1 1 8 27 64

MATLAB: Check if a value in a cell array remains the same

My question may be a bit "silly", but I am stucked here, so I would really need your help.
So, we have a cell array Q 5520x1, like the one below:
I'm only interested in the first two numbers of each row. To be specifically clear, giving
K>> Q{1}
ans = 0 1 0 238
I only care about 0 and 1, and so on with the other rows. Only the first two numbers of each row. Let's just ignore the rest values in each row of Q, they are more or less irrelevant.
My problem is, how is it possible to check if the first value of each row in the cell array Q, in the example above 0, remains the same? What I would like to achieve, is while the first value is the same, I want to store in another cell array, all the second values. In case of number 0, I want to store the values
[1,3,127,129,216,217,252,253,302,303,342,343]
and so on. How could this be done?
Any help or advice would be really appreciated.
% Example Q
Q = {[0 1 135 134];
[0 3 154 26];
[0 16 146 234];
[1 2 324 125];
[1 7 213 252]};
A = cell2mat(Q(1:2760));
[~,~,ind2] = unique(A(:,1));
C = arrayfun(#(x)A(find(ind2==x),2),1:max(ind2),'UniformOutput',false);
C{1}
ans =
1
3
16
C{2}
ans =
2
7
You can use unique and accumarray as follows:
Q = {[0 1 0 238]
[0 3 1 84]
[1 2 1 85]
[3 4 5 6]}; %// example data. Cell array of equal-size row vectors
Qm = vertcat(Q{:}); %// convert Q into matrix
[vals, ~, id] = unique(Qm(:,1)); %// get unique id for 1st col
result = accumarray(id, Qm(:,2), [], #(x){x.'}); %'// gather 2nd col values according to id
This gives:
vals =
0
1
3
result{1} =
1 3
result{2} =
2
result{3} =
4
You can do it with a for loop :
cell_range = max(cellfun(#(x) x(1),Q));
C = cell(cell_range,1)
for i = 1:length(Q)
M = Q{i};
disp(M(1));
C{M(1)} = [C{M(1)}, M(2)];
end

How to insert elements according to array of indices in MATLAB?

Say, I have Index array I = [2 4 6]
Another, array A =[1 0 0]
I want to insert elements of array A in array C at position 2 , 4 and 6.
Array C is initially empty.
Run 2: I = [1, 7, 8]
A = [0 0 1]
I would want to insert elements of array A in array C at position 1 , 7 and 8.
And, so on.
Please help.
Thanks.
Cheery essentially answered the question for you, but in order to be complete, simply use the array I and index into C and use I to place the values of A into the corresponding slots in C. As such:
C(I) = A;
If C was not already allocated, then C will pad whatever you didn't index with zeroes. As such, given your two examples, this is what we get:
I1 = [2 4 6];
I2 = [1 7 8];
A1 = [1 0 0];
A2 = [0 0 1];
C1(I1) = A1
C2(I2) = A2
C1 =
0 1 0 0 0 0
C2 =
0 0 0 0 0 0 0 1
However, because your array A already has zeroes, you can't really see the effect of this type of assignment. If you change up your array A into some other values that don't include zero, then you'll see that this does work.

MATLAB: compare elements in arrays

suppose there are arrays A and B, both of which can have any arbitrary numbers and size. for example
A=[1 2 3]
B=[4 8 52 7 10]
i was wondering if there was any way to check if any of the elements in A are contained in B without using a loop? Once again, the numbers and size of the array will be arbitrary so i can't hard code it. Any help and input would be appreciated. Thanks!
You mean like this:
A=[1 2 3]; B=[4 8 52 7 10]
ismember(A,B)
ans =
0 0 0
Add to #NasserM.Abbasi: ismember will work regardless shapes and sizes, it is always element-wise. So if you have A=[1 2; 3 4] and B=[1 3; 4 2; 1 2],
then ismember will return :
ismember(A,B); % -> [1 1; 1 1] due to element-wise membership check
ismember(A,B, 'rows'); % -> [1 0] since it checks row-wise.
use ismember carefully according to the possible shapes in A and B.

Resources