How to prevent adding a number to a matrix elements?

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)

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

i know that i can use my own function, but there are many addition like this in my code, and using function confuse me, so i try to find a way that fix it by symbolic addition (+)
Then you will need to subclass like I posted before. It would look something like,
A = NoExpansionArray([1 2; 3 4]); %Make A a member of your class
b = NoExpansionArray(3);
c = A + b;
where NoExpansionArray has been defined something like
classdef NoExpansionArray < double
methods
function obj = plus(first, second)
if ~isa(first, 'NoExpansionArray') || ~isa(second, 'NoExpansionArray')
error('Both operands must be NoExpansionArray for addition');
end
if ~isequal(size(first), size(second))
error('Do not add NoExpansionArray of different sizes');
end
obj = builtin('plus', first, second);
end
function obj = minus(first, second)
if ~isa(first, 'NoExpansionArray') || ~isa(second, 'NoExpansionArray')
error('Both operands must be NoExpansionArray for subtraction');
end
if ~isequal(size(first), size(second))
error('Do not subtract NoExpansionArray of different sizes');
end
obj = builtin('minus', first, second);
end
end
The above is untested.
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.
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.

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

I strongly suggest you either get used to this behaviour
+1. I'm going to be even more brutal and say that if you cannot get used to this behaviour then matlab is not the right tool for you. Trying to make matlab conform to some completely opposite behaviour is a fool's errand.
... though I still think there ought to be a way to turn off the new (R2016b) implicit expansion as a debugging tool.
I second that, Walter. Bugs turning into features are, occasionally, quite annoying :)
@Walter: I agree. I do like the expansion, because it improves the readability of many codes. But the "auto" remains a problem. It would have been very nice to implement an "intentional-expanding" by e.g. ":+", ":-", ":*", ":/" and so on. This has the disadvantage, that the code is not backward compatible anymore.
":/"
certainly seems appropriate for behaviour that ought to give an error but is now a feature!
I foresee all kind of new weird bugs here :)
1:+3 → [1 2 3] or 4?
A character that is not otherwise used much in MATLAB:
$+
$-
$*
etc
@Jos: You are right, ":+" fails in "1:+3". There are more unused characters: §$&?# or the auto-expand classifier can be appended: +:
Nevertheless, MathWorks decided unfortunately to stay at the standard operators and I expect that this will not be changed anymore. We asked for a dwim operator for so many years, now we got a operator-less dwim behavior.
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.)
@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.

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

thank you for answering but actually i don't understand how i can fix it

Sign in to comment.

Categories

Find more on Code Execution in Help Center and File Exchange

Tags

Asked:

on 27 Nov 2017

Edited:

on 1 Dec 2017

Community Treasure Hunt

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

Start Hunting!