How to prevent adding a number to a matrix elements?

9 views (last 30 days)
in matlab if we have an matix like A[n,n], when we add a scalar value (b) to it, solve it like this:
A+b*ones(n)
but i want if in my cod exist addition like A+b, matlab dont add an scalar num to matrix and show error, is any way to do it?
for example
A=[1 2;3 4]
b=3
in fact A is 2 by 2 matrix and b is 1 by 1 and they should not added with together but matlab change b as a 2 by to matrix then solve (A+b*ones(2)) as
ans=[4 5;6 7]
but i want to matlab return error mismatch matrix dimensions.

Answers (3)

Jan
Jan on 27 Nov 2017
The auto-expanding of scalars is a typical feature of Matlab since it has been created. This behavior can and should not be changed in general. But you can write your own functions for addition:
function c = xPlus(a, b)
if isequal(size(a), size(b))
c = a + b;
else
error('ExtraOPs:xPlus:SizeMismatch', 'Sizes of inputs do not match.');
end
end
Then:
A = [1 2;3 4]
b = 3
C = xPlus(A, b)
% >> Error message
Or maybe more general:
function SameSize(a, b)
if ~isequal(size(a), size(b))
error('ExtraOPs:SameSize:Mismatch', 'Sizes of inputs do not match.');
end
end
Then:
A = [1 2;3 4]
b = 3
SameSize(A, b);
C = A + b
This is much better then trying to overload the built-in operators, which would confuse Matlab's toolbox functions and many other 3rd party codes.
  4 Comments
Jan
Jan on 29 Nov 2017
using function confuse me
Then this might be the best point to start from. Inserting a "SameSize(A, b)" does not look too confusing and a reader knows the purpose immediately. It might be more confusing for a person who is familiar with Matlab to see "A + b" failing for a scalar b.
mohammad m
mohammad m on 30 Nov 2017
Edited: mohammad m on 1 Dec 2017
in fact i wrote my code by (+ & -) operator's and there are many additions with different terms in it, so by using of functions, my code's lines will be longer and because of different terms of additions in every line, i should use a special function's for them, for ex:
A,B ,... are matrices
a,b,... scalars
C=(a+b+c)*A+(a+b+d+...)*B;
so if i mistakenly don't write (A), matlab solve it as:
C=(a+b+c)+(a+b+d+...)*B;
in many cases i used of this property of matlab but i'm trying to find any way that i can cancel it for example by writing (.+) instead of (+), so i think that it's better that i write my own class.

Sign in to comment.


Jos (10584)
Jos (10584) on 28 Nov 2017
Many, if not all, functions rely on scalar expansion to happen for the plus operator. I strongly suggest you either get used to this behaviour of MatLab, or use a function to test explicitly for the same size of the two operants before you execute the addition (as Walter and Jan already suggested).
  10 Comments
Guillaume
Guillaume on 30 Nov 2017
Personnaly, I like the new implicit expansion because it makes the language more consistant. Before, you had special cases which frankly should never have been allowed.
Now: you can perform binay operations if corresponding dimensions are the same or one of them is 1.
Before: you can perform binay operations if corresponding dimensions are the same, OR one input is scalar, OR both inputs have at most one dimension greater than 1 (i.e both are vectors in possibly different dimension).
Special cases in a language grammar are always bad. You can't write generic code anymore. It'd be great if similar special cases for vectors were removed from other functions as well (sum, A(B), etc.)
Jan
Jan on 30 Nov 2017
@Guillaume: The auto-expanding did not cause any problems in my code, because I never relied on catching errors, if the sizes of the inputs are not matching. I find
v = 1:10;
M = v + v.'
nicer than
M = bsxfun(@plus, v, v.')
But I have used a C-Mex function since Matlab 5.3 already to perform this:
M = Expand(v, '+', v.')
I used BLAS libraries and unfolded loops for the standard cases [1 x N] and [M x 1]. In some cases this this is even faster than BSFXUN, but the auto-expansion is harder to beat.
With this groundwork, it was easy to adjust my code to auto-expanding: Simply search for "Expand(" and replace the pattern to get:
% M = Expand(v, '+', v.'); %@:ExpandConverted
AssertMatchSize(v, v.'); %@:Debug
M = v + v.'; %@:Auto-Expand >= R0216b
Finally I use a tool, which comments/uncomments all lines containing the key "%@:Debug" automatically (Brrrr, ugly like a C-preprocessor, but such useful :-) ). The "%@:ExpandConverted" allows to track or undo all changes automatically also.
But as soon as a programmer wrote (what I never did):
try
c = a + b;
catch % Reply NaN for not matching sizes:
c = NaN;
end
the auto-expanding kills the code and it could cost many many many hours of debugging and modifying the code - including testing the software afterwards again exhaustively.
The magic comments based on a unique key are powerful for maintaining larger projects (some hundred thousands lines of code), but of course this is ugly as all meta-programming methods. I use this method, because it let me convert all my codes to run with or without auto-expansion in a minute. But of course it is even easier to let it produce code, which does not run at all.
Sorry, I left the topic. This does not help Mohammad M anymore.

Sign in to comment.


Walter Roberson
Walter Roberson on 27 Nov 2017
You could perhaps subclass the appropriate numeric types https://www.mathworks.com/help/matlab/matlab_oop/subclassing-matlab-built-in-classes.html redefining the plus() and minus() methods to detect scalar addition and error out. This would require that you deliberately make your matrix a member of the appropriate type and that you are careful about how you assign values.
  1 Comment
mohammad m
mohammad m on 27 Nov 2017
thank you for answering but actually i don't understand how i can fix it

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!