Is there any matlab documentation that can explain why multiplying empty arrays gives zero matrices?

Is there any matlab documentation that can explain why multiplying empty arrays gives zero matrices?
Here is the sample
A=double.empty(5,0);
B=double.empty(0,5);
C=A*B
C =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

1 commentaire

Using block matrices A, B, C, & D:
[A,B] * [C;D] = A*C + B*D
If B and D are empty but the concatenation is valid, then:
[A,B] = A
[C;D] = C
Hence
A*C + B*D = A*C
This requires that
B*D = zeros(height(B),width(D))
Otherwise, standard linear algebra identities would break.
Thus zeros(...) is the only consistent result.

Connectez-vous pour commenter.

 Réponse acceptée

From group theory point of view, sum/product (group operator) of an empty set gives the group neutral element. The most basic examples are
sum([])
ans = 0
prod([])
ans = 1
From that property, mathematically by definition of matrix multiplication; the product AB :=A*B of
A = double.empty(m,0)
B = double.empty(0,n)
is equal to
zeros(m,n)
since each element AB(i,j) of A*B is a sum of an empty set.
This is mathematically defined, not MATLAB own convention, no doc description should be necessary.

24 commentaires

I meant to write this as well, but you beat me to it, haha.
@Dyuman Joshi: That is an excellent summary, thank you for the link! See also:
Thank you very much for the information you provided. Very helpful. But there are two things I don't understand
1 The result of this calculation is correct, but I don't see the benefit of the empty matrix in the calculation process."this empty matrices are very convenient"---Why?
Why empty array can be we “avoid program around edge cases”?
I don't see the need for [A B], nor does [C; D],
Running A*B directly gives the same result
>> p = 0; A = ones(3,2); B = ones(3,p); C = ones(2,3); D = ones(p,3);
>> [A B]*[C; D]
ans =
2 2 2
2 2 2
2 2 2
2 “Nowadays MATLAB gets it right”--------Why?What proves that Matlab's original choice is correct?
@Bruno Luong Thanks for your anwser.I have only studied linear algebra, not group and ring . If I don't understand the group and ring , can I understand the multiplication of empty arrays in matlab to get a zero matrix? Or not?
@fa wu If you study linear algebra then I'm surprise you don't understand this argument of the paper
p = 0; A = ones(3,2); B = ones(3,p); C = ones(2,3); D = ones(p,3);
[A B]*[C; D]
ans = 3×3
2 2 2 2 2 2 2 2 2
Because B and D are empty (with compatible size for valid concatenation)
[A B] is A
and
[C; D] is C;
so clearly
[A B]*[C;D] = A*C % (eqt1)
% also = [2 2 2;
% 2 2 2;
% 2 2 2]; % by direct calculation of A*C, but that is not important
% for what will follow
However from linear algebra we have
[A B]*[C;D] = A*C + B*D;
So just rearrange we get
B*D = [A B]*[C;D] - A*C; (eqt2)
But we have etablish in (eqt1) that
[A B]*[C;D] = A*C (eqt3)
therefore form eqt(2) and (3)
B*D = [A B]*[C;D] - A*C = zeros(3,3)
% = zeros(height(A),widt(C)) == zeros(height(B),width(D))
That's why zeros(height(B),width(D)) is the only possible correct answer for B*D, compatible with linear algebra.
The product of an m-by-k matrix and a k-by-n matrix is an m-by-n matrix. This holds no matter what m, k, and n are. This is standard matrix multiplication.
In your example, m is 5, k is 0, and n is 5. Therefore by this general rule the result of multiplying a 5-by-0 and a 0-by-5 must be a 5-by-5 matrix.
So what should the elements of the resulting matrix be? There are a couple reasonable possibilities IMO. But if you write matrix multiplication naively (this is not how MATLAB implements it internally, BTW) you could do so with a double for loop using the dot product function dot.
A = zeros(5, 0);
B = zeros(0, 5);
result = naiveMatrixMultiply(A, B)
result = 5×5
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Why are the elements of the result 0? What's the dot product of a 1-by-0 row of A and a 0-by-1 column of B? By the (handwaving) definition of a dot product you multiply corresponding elements of the two vectors and sum all those products. But the empty row of A and column of B have no elements. What's the sum of no elements in MATLAB?
sum([])
ans = 0
Hopefully this makes sense.
function result = naiveMatrixMultiply(A, B)
assert(width(A) == height(B)) % number of columns of A must == number of rows of B
for whichRow = 1:height(A)
for whichCol = 1:width(B)
result(whichRow, whichCol) = dot(A(whichRow, :), B(:, whichCol));
end
end
end
"I don't see the need for [A B], nor does [C; D],"
Note that p is a variable that could be any positive integer, including zero. This means that in general you can write code using MATLAB that works correctly without any special cases, even for empty arrays.
@Steven Lord "What's the sum of no elements in MATLAB?"
0 by experiment. But what justifies 0 is the logical answer?
Of course you could go down to the road one step and say a natural way to implement dot product is
function result = naiveVectorDot(u, v)
assert(isvector(u) == isvector(v)) % both must be vector
u = reshap(u, 1, []);
v = reshap(v, 1, []);
assert(width(u) == width(v)) % having a same number of elements
result = 0;
for i = 1:width(u)
result = result + u(i)*v(i);
end
Or do similar with naiveSum.
But personally I find argument using MATLAB to justify MATLAB is kind of not beyond criticable.
Thanks for your comment, it's very helpful. I see. This can make the program more robust and flexible!
Thank you for your detailed derivation, I understand your thinking. just one thing i have a mental block
[A B]*[C;D] = A*C + B*D;
I think B*D=[] ,because p=0,
If this hurdle is overcome, I understand the whole derivation.
Thank you for your detailed and patient answer, very much appreciated.
I understand your train of thought, "dot product of a 1-by-0 row of A and a 0-by-1 column of B?" should =[]+[]
But I don't understand the math behind sum([])=0.
Of course, if this is the rule of matlab, I can also accept it.
IMO @Stephen23 explanation backup the fact that concatenation of an array A with empty array returns the array A unchanged. But I don't see it explains why the product of two empty matrices A and B is zeros(heigth(A),width(B)).
On a side note, something that MATLAB accepts but I find it not totally logic is this kind of concatenation is tolerate
A = rand(2,3),
B = zeros(0,0);
cat2AB = cat(2,A,B), %[A,B]
cat1AB = cat(1,A,B), %[A;B]
But I'll admit it would drive me crazy if it throw an error.
"But I don't see it explains why the product of two empty matrices A and B is zeros(heigth(A),width(B))."
I didn't explain that (you already covered that very well). I was trying to explain why this is useful.
@fa wu "I think B*D=[] ,because p=0,"
NOOOOOO. common, you are no better than that IA robot @Riya that gives a wrong reply if you still think the same.
@fa wu "But I don't understand the math behind sum([])=0. Of course, if this is the rule of matlab, I can also accept it."
No again, there is nothing in here that must be ruled by MATLAB.
And watch this, I do not even use MATLAB sum, just addition between two numbers and I never have a zero appears anywhere in my code.
a = 10; % any non-empty array of integers would also do
computesumb_strangeway = @(a,b) sum_non_empty_array([a,b])-sum_non_empty_array(a);
b = [1 2 3 4];
computesumb_strangeway(a, b)
ans = 10
b = [1 2 3];
computesumb_strangeway(a, b)
ans = 6
b = [1 2];
computesumb_strangeway(a, b)
ans = 3
b = [1];
computesumb_strangeway(a, b)
ans = 1
b = []; % ***** PAY ATTENTION HERE THE EDGE CASE ****
computesumb_strangeway(a, b) % watch this, and we never need to directly use MATLAB sum of empty array
ans = 0
function s = sum_non_empty_array(x)
assert(~isempty(x), 'sum on empty array not allowed')
s = x(1);
for k=2:length(x)
s = s + x(k);
end
end
Are functions like dot and cross handled correctly and consistently for empty inputs?
a = double.empty(3,0);
b = a;
Why does dot return vector and not a scalar (maybe because there is no such thing as an empty scalar?)?
c = dot(a,b)
c = 1×0 empty double row vector
isscalar(c)
ans = logical
0
Compute the dot product by vector multiplication. Still not a scalar, but a different result.
c = a.'*b
c = []
isscalar(c)
ans = logical
0
Which result of the two above is correct, or perhaps preferred?
If one of the operands is non-empty
d = [1;2;3];
dot fails,
try
dot(d,b)
catch ME
ME.message
end
ans = 'A and B must be same size.'
but vector multiplication does not fail
d.'*b
ans = 1×0 empty double row vector
cross returns an empty row vector
c = cross(a,b)
c = 3×0 empty double matrix
Is c perpendicular to both a and b?
Reminder : MATLAB dot and cross stock functions are vectorized functions, they both can be applied on 2 sets of same cardinal of vectors. The cardinal can be 0 (empty sets) or not.
"Why does dot return vector and not a scalar (maybe because there is no such thing as an empty scalar?)?" c = dot(a,b)
The result is actually an empty array of scalar. It's correct to me
"Compute the dot product by vector multiplication. Still not a scalar, but a different result. c = a.'*b
This formula intended for dot replacement is incorrect. It is only correct if a and b are (3 x 1).
Is c perpendicular to both a and b? c = cross(a,b)
This question does not have much sense, it returns an empty set of vectors in R^3. There is nothing to check for any specific property.
Overall, to me everything in your MATLAB examples are coherent.
Why does dot return vector and not a scalar (maybe because there is no such thing as an empty scalar?)?
If you call dot with an empty vector (either 1-by-0 or 0-by-1) as the inputs it will return a scalar.
a = zeros(1, 0)
a = 1×0 empty double row vector
isvector(a)
ans = logical
1
isempty(a)
ans = logical
1
b = zeros(0, 1)
b = 0×1 empty double column vector
isvector(b)
ans = logical
1
isempty(b)
ans = logical
1
D = dot(a, b)
D = 0
isscalar(D)
ans = logical
1
And yes, there is no such thing as an empty scalar. An empty array must have size 0 in one of its dimensions (see isempty.) A scalar must have size [1 1] (as per isscalar.) The definitions of the two terms are incompatible with each other (the size vector [1 1] does not have 0 as one of its elements.)
I see thing like this;
Three scalars in a row vector
[1 2 3]
Two scalars in a row vector
[4 5]
One scalar in a row vector
[6]
zero scalar in a row vector
zeros(1,0)
This can be viewed as an empty set of scalar. Yes it is NOT a scalar, but an empty set of scalar as I interpret it.
Your comment presents a fascinating addition rule that has inspired me! Is MATLAB's "sum([]) = 0" based on this addition rule set? Your mentioned"there is nothing in here that must be ruled by MATLAB“ suggests that this method is rooted in some mathematical theory? What is the name of this mathematical theory, and do you have any recommended books on the subject?
"Your mentioned"there is nothing in here that must be ruled by MATLAB“ suggests that this method is rooted in some mathematical theory? What is the name of this mathematical theory, and do you have any recommended books on the subject?"
Group theory (just as Bruno Luong already told you in the very first sentence of their answer):
May I ask a question? What operation does 'c = a.'*b' in your post perform?
a.' performs matrix transposition, if a is column vector as in the context it puts a as row vector
* is matrix multiplication.
So for a and b columns vectors of the same height a.'*b is sum(a.*b)
Actualy the right formula for dot replacement is a'*b not a.'*b as Paul wrote.
The [] matrix in MATLAB is treated kind of specially by a lot of older functions, because as described in the post from Professor Nick Higham's blog that @Dyuman Joshi posted in an earlier comment, in the original version of MATLAB that was the empty matrix.
The behavior of sum of [] returning 0, if you're willing to allow one special quirk of concatenation related to the [] matrix (where it can be concatenated with a vector even though it doesn't have the same number of rows), can be shown as follows. If concatenating a vector and [] together results in that same vector (which it does):
a = 1:5
a = 1×5
1 2 3 4 5
b = [a, []]
b = 1×5
1 2 3 4 5
and if you accept that the sum of the concatenation of two arrays should be the same as the sum of each of those arrays added together:
sum12345 = sum(1:5) % 1:5 is the same as [1:3 4:5]
sum12345 = 15
sum123 = sum(1:3)
sum123 = 6
sum45 = sum(4:5)
sum45 = 9
sum12345 == sum123 + sum45 % true
ans = logical
1
then sum([a []]) equals sum(a) + sum([]). But [a []] is just a, so that simplifies to sum(a) = sum(a) + sum([]). Subtract sum(a) from both sides and 0 = sum([]).

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Produits

Version

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by