MATLAB operators as functions - matlab

I was just curious that whether all operators in MATLAB are internally implemented as functions? We have equivalent functions for almost all MATLAB operators. plus for +, minus for -, eq for == and transpose for '.

Most operators are represented by functions, yes.
A thorough list is provided on the MathWorks page Implementing Operators for Your Class, reproduced here:
a + b plus(a,b) Binary addition
a - b minus(a,b) Binary subtraction
-a uminus(a) Unary minus
+a uplus(a) Unary plus
a.*b times(a,b) Element-wise multiplication
a*b mtimes(a,b) Matrix multiplication
a./b rdivide(a,b) Right element-wise division
a.\b ldivide(a,b) Left element-wise division
a/b mrdivide(a,b) Matrix right division
a\b mldivide(a,b) Matrix left division
a.^b power(a,b) Element-wise power
a^b mpower(a,b) Matrix power
a < b lt(a,b) Less than
a > b gt(a,b) Greater than
a <= b le(a,b) Less than or equal to
a >= b ge(a,b) Greater than or equal to
a ~= b ne(a,b) Not equal to
a == b eq(a,b) Equality
a & b and(a,b) Logical AND
a | b or(a,b) Logical OR
~a not(a) Logical NOT
a:d:b colon(a,d,b) Colon operator
a:b
colon(a,b)
a' ctranspose(a) Complex conjugate transpose
a.' transpose(a) Matrix transpose
command line output display(a) Display method
[a b] horzcat(a,b,...) Horizontal concatenation
[a; b] vertcat(a,b,...) Vertical concatenation
a(s1,s2,...sn) subsref(a,s) Subscripted reference
a(s1,...,sn) = b subsasgn(a,s,b) Subscripted assignment
b(a) subsindex(a) Subscript index
Another good place to look for a list is actually the documentation for bsxfun, which applies any element-wise function with very powerful virtual data replication.
Often useful is vertcat. horizontal vs. vertical concatenation with a comma separated list:
>> c = {'a','b'};
>> horzcat(c{:}) % [c{1} c{2}]
ans =
ab
>> vertcat(c{:}) % [c{1};c{2}]
ans =
a
b
In addition to many other documented operators with named functions (colon,transpose,etc.), there are a couple undocumented ones that you can access with builtin:
parenthesis
>> x = [4 5 6];
>> builtin('_paren',x,[2 3]) % x([2 3])
ans =
5 6
curly braces
>> c = {'one','two'};
>> builtin('_brace',c,2) % c{2}
ans =
two
struct field access (dot)
>> s = struct('f','contents');
>> builtin('_dot',s,'f') % s.f
ans =
contents
However, note that the proper and supported way to use (), {}, or . is via subsref, subasgn, and subindex, depending on the context.
These builtins refer to the operators described in help paren. Also explore the punctuation listed in help punct.

Yes, that's how MATLAB enables operator overloading, by mapping infix operators to named functions.
The documentation lists (by category) the functions invoked by operators. And more here.

Related

Why does MATLAB fail to check the equality of this trigonometric expression

isequaln() is testing symbolic objects for equality as stated in the documentation. However, this is not the case with the following script.
syms a
f1=cos(a)^2;
f2=1-sin(a)^2;
isequaln(f1,f2)
ans =
logical
0
MATLAB does not return the correct answer. What does MATLAB do when comparing equality for symbolic expressions, compare strings (i.e. a typical scenario for regular expressions), or something else?
At the bottom of the documentation page, there is a section called "Tips", which contains the following item:
isequaln(A,B) checks if A and B are the same size and their contents are syntactically the same expression, treating NaN values as equal. To check whether the mathematical comparison A == B holds for all values of variables in A and B, use isAlways(A == B).
(emphasis mine)
isAlways does what you want:
syms a
f1 = cos(a)^2;
f2 = 1-sin(a)^2;
isAlways(f1 == f2)
This outputs true.
Alternatives:
>> simplify(f1-f2)
ans =
0
>> simplify(f1==f2)
ans =
symtrue

Vectorized processing of each N-dimension array in (N+1)-dimension array in Matlab? [duplicate]

You can apply a function to every item in a vector by saying, for example, v + 1, or you can use the function arrayfun. How can I do it for every row/column of a matrix without using a for loop?
Many built-in operations like sum and prod are already able to operate across rows or columns, so you may be able to refactor the function you are applying to take advantage of this.
If that's not a viable option, one way to do it is to collect the rows or columns into cells using mat2cell or num2cell, then use cellfun to operate on the resulting cell array.
As an example, let's say you want to sum the columns of a matrix M. You can do this simply using sum:
M = magic(10); %# A 10-by-10 matrix
columnSums = sum(M, 1); %# A 1-by-10 vector of sums for each column
And here is how you would do this using the more complicated num2cell/cellfun option:
M = magic(10); %# A 10-by-10 matrix
C = num2cell(M, 1); %# Collect the columns into cells
columnSums = cellfun(#sum, C); %# A 1-by-10 vector of sums for each cell
You may want the more obscure Matlab function bsxfun. From the Matlab documentation, bsxfun "applies the element-by-element binary operation specified by the function handle fun to arrays A and B, with singleton expansion enabled."
#gnovice stated above that sum and other basic functions already operate on the first non-singleton dimension (i.e., rows if there's more than one row, columns if there's only one row, or higher dimensions if the lower dimensions all have size==1). However, bsxfun works for any function, including (and especially) user-defined functions.
For example, let's say you have a matrix A and a row vector B. E.g., let's say:
A = [1 2 3;
4 5 6;
7 8 9]
B = [0 1 2]
You want a function power_by_col which returns in a vector C all the elements in A to the power of the corresponding column of B.
From the above example, C is a 3x3 matrix:
C = [1^0 2^1 3^2;
4^0 5^1 6^2;
7^0 8^1 9^2]
i.e.,
C = [1 2 9;
1 5 36;
1 8 81]
You could do this the brute force way using repmat:
C = A.^repmat(B, size(A, 1), 1)
Or you could do this the classy way using bsxfun, which internally takes care of the repmat step:
C = bsxfun(#(x,y) x.^y, A, B)
So bsxfun saves you some steps (you don't need to explicitly calculate the dimensions of A). However, in some informal tests of mine, it turns out that repmat is roughly twice as fast if the function to be applied (like my power function, above) is simple. So you'll need to choose whether you want simplicity or speed.
I can't comment on how efficient this is, but here's a solution:
applyToGivenRow = #(func, matrix) #(row) func(matrix(row, :))
applyToRows = #(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1))'
% Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = #sum;
applyToRows(myFunc, myMx)
Building on Alex's answer, here is a more generic function:
applyToGivenRow = #(func, matrix) #(row) func(matrix(row, :));
newApplyToRows = #(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1), 'UniformOutput', false)';
takeAll = #(x) reshape([x{:}], size(x{1},2), size(x,1))';
genericApplyToRows = #(func, matrix) takeAll(newApplyToRows(func, matrix));
Here is a comparison between the two functions:
>> % Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = #(x) [mean(x), std(x), sum(x), length(x)];
>> genericApplyToRows(myFunc, myMx)
ans =
2 1 6 3
5 1 15 3
8 1 24 3
>> applyToRows(myFunc, myMx)
??? Error using ==> arrayfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
Error in ==> #(func,matrix)arrayfun(applyToGivenRow(func,matrix),1:size(matrix,1))'
For completeness/interest I'd like to add that matlab does have a function that allows you to operate on data per-row rather than per-element. It is called rowfun (http://www.mathworks.se/help/matlab/ref/rowfun.html), but the only "problem" is that it operates on tables (http://www.mathworks.se/help/matlab/ref/table.html) rather than matrices.
Adding to the evolving nature of the answer to this question, starting with r2016b, MATLAB will implicitly expand singleton dimensions, removing the need for bsxfun in many cases.
From the r2016b release notes:
Implicit Expansion: Apply element-wise operations and functions to arrays with automatic expansion of dimensions of length 1
Implicit expansion is a generalization of scalar expansion. With
scalar expansion, a scalar expands to be the same size as another
array to facilitate element-wise operations. With implicit expansion,
the element-wise operators and functions listed here can implicitly
expand their inputs to be the same size, as long as the arrays have
compatible sizes. Two arrays have compatible sizes if, for every
dimension, the dimension sizes of the inputs are either the same or
one of them is 1. See Compatible Array Sizes for Basic Operations and
Array vs. Matrix Operations for more information.
Element-wise arithmetic operators — +, -, .*, .^, ./, .\
Relational operators — <, <=, >, >=, ==, ~=
Logical operators — &, |, xor
Bit-wise functions — bitand, bitor, bitxor
Elementary math functions — max, min, mod, rem, hypot, atan2, atan2d
For example, you can calculate the mean of each column in a matrix A,
and then subtract the vector of mean values from each column with A -
mean(A).
Previously, this functionality was available via the bsxfun function.
It is now recommended that you replace most uses of bsxfun with direct
calls to the functions and operators that support implicit expansion.
Compared to using bsxfun, implicit expansion offers faster speed,
better memory usage, and improved readability of code.
None of the above answers worked "out of the box" for me, however, the following function, obtained by copying the ideas of the other answers works:
apply_func_2_cols = #(f,M) cell2mat(cellfun(f,num2cell(M,1), 'UniformOutput',0));
It takes a function f and applies it to every column of the matrix M.
So for example:
f = #(v) [0 1;1 0]*v + [0 0.1]';
apply_func_2_cols(f,[0 0 1 1;0 1 0 1])
ans =
0.00000 1.00000 0.00000 1.00000
0.10000 0.10000 1.10000 1.10000
With recent versions of Matlab, you can use the Table data structure to your advantage. There's even a 'rowfun' operation but I found it easier just to do this:
a = magic(6);
incrementRow = cell2mat(cellfun(#(x) x+1,table2cell(table(a)),'UniformOutput',0))
or here's an older one I had that doesn't require tables, for older Matlab versions.
dataBinner = cell2mat(arrayfun(#(x) Binner(a(x,:),2)',1:size(a,1),'UniformOutput',0)')
The accepted answer seems to be to convert to cells first and then use cellfun to operate over all of the cells. I do not know the specific application, but in general I would think using bsxfun to operate over the matrix would be more efficient. Basically bsxfun applies an operation element-by-element across two arrays. So if you wanted to multiply each item in an n x 1 vector by each item in an m x 1 vector to get an n x m array, you could use:
vec1 = [ stuff ]; % n x 1 vector
vec2 = [ stuff ]; % m x 1 vector
result = bsxfun('times', vec1.', vec2);
This will give you matrix called result wherein the (i, j) entry will be the ith element of vec1 multiplied by the jth element of vec2.
You can use bsxfun for all sorts of built-in functions, and you can declare your own. The documentation has a list of many built-in functions, but basically you can name any function that accepts two arrays (vector or matrix) as arguments and get it to work.
I like splitapply, which allows a function to be applied to the columns of A using splitapply(fun,A,1:size(A,2)).
For example
A = magic(5);
B = splitapply(#(x) x+1, A, 1:size(A,2));
C = splitapply(#std, A, 1:size(A,2));
To apply the function to the rows, you could use
splitapply(fun, A', 1:size(A,1))';
(My source for this solution is here.)
Stumbled upon this question/answer while seeking how to compute the row sums of a matrix.
I would just like to add that Matlab's SUM function actually has support for summing for a given dimension, i.e a standard matrix with two dimensions.
So to calculate the column sums do:
colsum = sum(M) % or sum(M, 1)
and for the row sums, simply do
rowsum = sum(M, 2)
My bet is that this is faster than both programming a for loop and converting to cells :)
All this can be found in the matlab help for SUM.
if you know the length of your rows you can make something like this:
a=rand(9,3);
b=rand(9,3);
arrayfun(#(x1,x2,y1,y2,z1,z2) line([x1,x2],[y1,y2],[z1,z2]) , a(:,1),b(:,1),a(:,2),b(:,2),a(:,3),b(:,3) )

behavior of colon operator (:) with matrix or vector arguments

We all know the matlab colon operator to create a linear sequence, i.e.
1:5 = [1 2 3 4 5]
Now I found that the arguments of the colon operator can also be applied to vectors or matrices. However I do not understand the definition behind.
Examples
[1 2 3 4]:5 == [1 2 3 4 5]
[1 2; 3 4]:3 == [1 2 3]
Why is this?
The second argument can be vector or matrix as well.
Ultimately I would like to understand sequences such as
1:2:3:4:5
which is fully legal in matlab and [1 5] by the way!
Note 1:2:3:4:5:6 is left associative i.e. parsed as ((1:2:3):4:5):6.
So what is the behavior for the colon operator with matrix/vector arguments?
EDIT: corrected the statement of left associativity.
The documentation for the colon operator says:
If you specify nonscalar arrays, MATLAB interprets j:i:k as j(1):i(1):k(1).
Your first example is interpreted as 1:3, the second as 1:5
Expressions with more than two : are parsed left-associative:
a:b:c:d:e==(a:b:c):d:e
.
>> 1:2:3:4:5
ans =
1 5

How can I make XOR work for logical matrix in MATLAB?

>> XOR(X,X)
??? Undefined function or method 'XOR' for input arguments of type 'logical'.
Why XOR can't be used for logical matrix?
And I tried a more simple example:
>> A=[1 0;1 0];
>> B=[1 1;0 0];
>> XOR(A,B)
??? Undefined function or method 'XOR' for input arguments of type 'double'.
How can I properly use XOR?
It works for me.
A=[1 0;1 0];
B=[1 1;0 0];
xor(A,B)
ans =
0 1
1 0
Yet when I try this...
XOR(A,B)
??? Undefined function or method 'XOR' for input arguments of type 'double'.
See the difference. Leave caps off to fix the problem.
I think the ambiguity arises because of a MathWorks convention used in their documentation. When they show the name of a function in their help, they use all caps. For example, here is the help for xor.
>> help xor
XOR Logical EXCLUSIVE OR.
XOR(S,T) is the logical symmetric difference of elements S and T.
The result is logical 1 (TRUE) where either S or T, but not both, is
nonzero. The result is logical 0 (FALSE) where S and T are both zero
or nonzero. S and T must have the same dimensions (or one can be a
scalar).
Even so, when you use the function, you do so with lower case letters in the function name.
How about the following:
C = abs(A-B);
The statement above makes C the XOR of A and B, because xor is true where the entries are different from each other, and 1-0 or 0-1 will give 1 or -1 (and abs of that will give 1), while 0-0 and 1-1 are both 1.
If you really want, you can create an "XOR.m" file with the following definition:
function C=XOR(A,B)
% function C=XOR(A,B)
% INPUTS:
% A - m x n matrix, consisting only of 1s or 0s.
% B - m x n matrix, consisting only of 1s or 0s.
% OUTPUT:
% C - m x n matrix, containing the logical XOR of the elements of A and B
C=abs(A-B)
However, you should keep in mind that function calls in Matlab are horrifically slow, so you might want to just write out the definition that I gave you wherever you happen to need it.
Edit
I did not originally understand your question.... you need to use xor and not XOR, and if it is complaining that your matrices are doubles instead of logicals, then use A==1 and B==1 instead of A and B. Matlab is case sensitive when it comes to variable names and built-in functions such as the xor function.
See this post. C = A~=B

How can I apply a function to every row/column of a matrix in MATLAB?

You can apply a function to every item in a vector by saying, for example, v + 1, or you can use the function arrayfun. How can I do it for every row/column of a matrix without using a for loop?
Many built-in operations like sum and prod are already able to operate across rows or columns, so you may be able to refactor the function you are applying to take advantage of this.
If that's not a viable option, one way to do it is to collect the rows or columns into cells using mat2cell or num2cell, then use cellfun to operate on the resulting cell array.
As an example, let's say you want to sum the columns of a matrix M. You can do this simply using sum:
M = magic(10); %# A 10-by-10 matrix
columnSums = sum(M, 1); %# A 1-by-10 vector of sums for each column
And here is how you would do this using the more complicated num2cell/cellfun option:
M = magic(10); %# A 10-by-10 matrix
C = num2cell(M, 1); %# Collect the columns into cells
columnSums = cellfun(#sum, C); %# A 1-by-10 vector of sums for each cell
You may want the more obscure Matlab function bsxfun. From the Matlab documentation, bsxfun "applies the element-by-element binary operation specified by the function handle fun to arrays A and B, with singleton expansion enabled."
#gnovice stated above that sum and other basic functions already operate on the first non-singleton dimension (i.e., rows if there's more than one row, columns if there's only one row, or higher dimensions if the lower dimensions all have size==1). However, bsxfun works for any function, including (and especially) user-defined functions.
For example, let's say you have a matrix A and a row vector B. E.g., let's say:
A = [1 2 3;
4 5 6;
7 8 9]
B = [0 1 2]
You want a function power_by_col which returns in a vector C all the elements in A to the power of the corresponding column of B.
From the above example, C is a 3x3 matrix:
C = [1^0 2^1 3^2;
4^0 5^1 6^2;
7^0 8^1 9^2]
i.e.,
C = [1 2 9;
1 5 36;
1 8 81]
You could do this the brute force way using repmat:
C = A.^repmat(B, size(A, 1), 1)
Or you could do this the classy way using bsxfun, which internally takes care of the repmat step:
C = bsxfun(#(x,y) x.^y, A, B)
So bsxfun saves you some steps (you don't need to explicitly calculate the dimensions of A). However, in some informal tests of mine, it turns out that repmat is roughly twice as fast if the function to be applied (like my power function, above) is simple. So you'll need to choose whether you want simplicity or speed.
I can't comment on how efficient this is, but here's a solution:
applyToGivenRow = #(func, matrix) #(row) func(matrix(row, :))
applyToRows = #(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1))'
% Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = #sum;
applyToRows(myFunc, myMx)
Building on Alex's answer, here is a more generic function:
applyToGivenRow = #(func, matrix) #(row) func(matrix(row, :));
newApplyToRows = #(func, matrix) arrayfun(applyToGivenRow(func, matrix), 1:size(matrix,1), 'UniformOutput', false)';
takeAll = #(x) reshape([x{:}], size(x{1},2), size(x,1))';
genericApplyToRows = #(func, matrix) takeAll(newApplyToRows(func, matrix));
Here is a comparison between the two functions:
>> % Example
myMx = [1 2 3; 4 5 6; 7 8 9];
myFunc = #(x) [mean(x), std(x), sum(x), length(x)];
>> genericApplyToRows(myFunc, myMx)
ans =
2 1 6 3
5 1 15 3
8 1 24 3
>> applyToRows(myFunc, myMx)
??? Error using ==> arrayfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
Error in ==> #(func,matrix)arrayfun(applyToGivenRow(func,matrix),1:size(matrix,1))'
For completeness/interest I'd like to add that matlab does have a function that allows you to operate on data per-row rather than per-element. It is called rowfun (http://www.mathworks.se/help/matlab/ref/rowfun.html), but the only "problem" is that it operates on tables (http://www.mathworks.se/help/matlab/ref/table.html) rather than matrices.
Adding to the evolving nature of the answer to this question, starting with r2016b, MATLAB will implicitly expand singleton dimensions, removing the need for bsxfun in many cases.
From the r2016b release notes:
Implicit Expansion: Apply element-wise operations and functions to arrays with automatic expansion of dimensions of length 1
Implicit expansion is a generalization of scalar expansion. With
scalar expansion, a scalar expands to be the same size as another
array to facilitate element-wise operations. With implicit expansion,
the element-wise operators and functions listed here can implicitly
expand their inputs to be the same size, as long as the arrays have
compatible sizes. Two arrays have compatible sizes if, for every
dimension, the dimension sizes of the inputs are either the same or
one of them is 1. See Compatible Array Sizes for Basic Operations and
Array vs. Matrix Operations for more information.
Element-wise arithmetic operators — +, -, .*, .^, ./, .\
Relational operators — <, <=, >, >=, ==, ~=
Logical operators — &, |, xor
Bit-wise functions — bitand, bitor, bitxor
Elementary math functions — max, min, mod, rem, hypot, atan2, atan2d
For example, you can calculate the mean of each column in a matrix A,
and then subtract the vector of mean values from each column with A -
mean(A).
Previously, this functionality was available via the bsxfun function.
It is now recommended that you replace most uses of bsxfun with direct
calls to the functions and operators that support implicit expansion.
Compared to using bsxfun, implicit expansion offers faster speed,
better memory usage, and improved readability of code.
None of the above answers worked "out of the box" for me, however, the following function, obtained by copying the ideas of the other answers works:
apply_func_2_cols = #(f,M) cell2mat(cellfun(f,num2cell(M,1), 'UniformOutput',0));
It takes a function f and applies it to every column of the matrix M.
So for example:
f = #(v) [0 1;1 0]*v + [0 0.1]';
apply_func_2_cols(f,[0 0 1 1;0 1 0 1])
ans =
0.00000 1.00000 0.00000 1.00000
0.10000 0.10000 1.10000 1.10000
With recent versions of Matlab, you can use the Table data structure to your advantage. There's even a 'rowfun' operation but I found it easier just to do this:
a = magic(6);
incrementRow = cell2mat(cellfun(#(x) x+1,table2cell(table(a)),'UniformOutput',0))
or here's an older one I had that doesn't require tables, for older Matlab versions.
dataBinner = cell2mat(arrayfun(#(x) Binner(a(x,:),2)',1:size(a,1),'UniformOutput',0)')
The accepted answer seems to be to convert to cells first and then use cellfun to operate over all of the cells. I do not know the specific application, but in general I would think using bsxfun to operate over the matrix would be more efficient. Basically bsxfun applies an operation element-by-element across two arrays. So if you wanted to multiply each item in an n x 1 vector by each item in an m x 1 vector to get an n x m array, you could use:
vec1 = [ stuff ]; % n x 1 vector
vec2 = [ stuff ]; % m x 1 vector
result = bsxfun('times', vec1.', vec2);
This will give you matrix called result wherein the (i, j) entry will be the ith element of vec1 multiplied by the jth element of vec2.
You can use bsxfun for all sorts of built-in functions, and you can declare your own. The documentation has a list of many built-in functions, but basically you can name any function that accepts two arrays (vector or matrix) as arguments and get it to work.
I like splitapply, which allows a function to be applied to the columns of A using splitapply(fun,A,1:size(A,2)).
For example
A = magic(5);
B = splitapply(#(x) x+1, A, 1:size(A,2));
C = splitapply(#std, A, 1:size(A,2));
To apply the function to the rows, you could use
splitapply(fun, A', 1:size(A,1))';
(My source for this solution is here.)
Stumbled upon this question/answer while seeking how to compute the row sums of a matrix.
I would just like to add that Matlab's SUM function actually has support for summing for a given dimension, i.e a standard matrix with two dimensions.
So to calculate the column sums do:
colsum = sum(M) % or sum(M, 1)
and for the row sums, simply do
rowsum = sum(M, 2)
My bet is that this is faster than both programming a for loop and converting to cells :)
All this can be found in the matlab help for SUM.
if you know the length of your rows you can make something like this:
a=rand(9,3);
b=rand(9,3);
arrayfun(#(x1,x2,y1,y2,z1,z2) line([x1,x2],[y1,y2],[z1,z2]) , a(:,1),b(:,1),a(:,2),b(:,2),a(:,3),b(:,3) )