Symbolic function for matrices - matlab

How to create symbolic function for matrices?
For example, I want to have matrix multiplication
A = sym('A',[5,1])
B = sym('B',[1,5])
f = symfun(A * B,[A, B])
But I have an error because A and B have different dimensions, and I can't use square brackets.

symfun only supports scalar arguments, thus you can only define a symbolic function with 10 scalar arguments:
f = symfun(A * B,[A(:); B(:)])
I recommend to work with the symbolic expression instead and use subs to evaluate:
f=A*B
Further you can also use a function handle:
f=#(a,b)(a*b);
f(A,B)

Related

Use of 'ArrayValued' in Matlab numerical integration

Why when performing numerical integration in Matlab with integral does this case need 'ArrayValued' to be set to true:
f = #(x) 5;
integral(f,0,2,'ArrayValued',true)
... while in this case the option isn't needed?:
f = #(x) x;
integral(f,0,2)
From the documentation for integral describing the integrand argument:
For scalar-valued problems, the function y = fun(x) must accept a
vector argument, x, and return a vector result, y. This generally
means that fun must use array operators instead of matrix operators.
For example, use .* (times) rather than * (mtimes). If you set the
'ArrayValued' option to true, then fun must accept a scalar and return
an array of fixed size.
So, a constant function like f = #(x) 5 does not return a result the same size as x if x is a vector. The integral function requires this because under the hood it is vectorized for scalar functions for performance – it actually evaluates the integrand at multiple points simultaneously with a single function call.
You can make your constant function compliant and not require 'ArrayValued' to be true with something like this:
f = #(x) 5+0*x;
integral(f,0,2)

How to convert symbolic expression to function handle for optimization [Matlab]?

syms a12 a13
x=sym('x',[1,2]);
fun=a12+a13
fun=subs(fun,[a12 a13],[x(1) x(2)])
%fun=matlabFunction(fun)
fun = #(x) fun
I am pursuing the method to substitute all the symbols in a symbol expression by a variables vector and convert the symbol expression into a function #(x), so that I can use this function for optimization.
You were on the right path when choosing to employ matlabfunction. However, you probably missed out one of its optional parameters, signally Vars;
Order of input variables or vectors in a generated MATLAB function,
specified as a character vector, a vector of symbolic variables, or a
one-dimensional cell array of character vectors, symbolic variables,
or vectors of symbolic variables.
The number of specified input variables must equal or exceed the
number of free variables in f. Do not use the same names for the input
variables specified by Vars and the output variables specified by
Outputs.
By default, when you convert symbolic expressions, the order is
alphabetical. When you convert symbolic functions, their input
arguments appear in front of other variables, and all other variables
are sorted alphabetically.
See Specify Input Arguments for Generated Function
syms a12 a13;
x = sym('x',[1,2]);
fun = a12 + a13;
fun=subs(fun,[a12 a13],[x(1) x(2)]);
g = matlabFunction(fun,'Vars',{x})
g =
function_handle with value:
#(in1)in1(:,1)+in1(:,2)
For the sake of testing if it works:
k = [1 2];
g(k) % Output: 3

Applying bsxfun to function with multiple output arguments

Let us assume we have a function myfunction with two output arguments
function [ arg1, arg2 ] = myfunction( a, b )
arg1 = a*b;
arg2 = a+b;
end
I want to apply myfunction to vector A and B:
fun = #myfunction;
A = 1:10;
B = 1:17;
[C, D] = bsxfun(fun,A,B)
This gives an error. How can I use bsxfun with functions having multiple output arguments?
bsxfun generates the output from all combinations of orthogonal matrices / vectors. Therefore to make your example work for even one output you have to transpose one of the inputs:
output1 = bsxfun(#myfunction,A,B.');
But as rayryeng commented, the problem with bsxfun is that it can return only one output. As Cris Luengo suggested in a comment you can instead use arrayfun. The difference is that for arrayfun you have to explicit generate all input combinations by expanding the input 1xN and 1xM vectors to NxM matrices:
For Matlab 2016b and later:
[output1, output2] = arrayfun(#myfunction,A.*ones(numel(B),1),B.'.*ones(1,numel(A)));
Matlab pre-2016b:
[output1, output2] = arrayfun(#myfunction,bsxfun(#times,A,ones(numel(B),1)),bsxfun(#times,B.',ones(1,numel(A))))
Instead of using bsxfun to expand the matrices you could also use repmat- but that's generally a bit slower.
Btw., If you have a function with many outputs and can't be bothered with writing [output1, output2, output3, ...] = ... you can just save them in a cell:
outputs = cell(nargout(#myfunction),1);
[outputs{:}] = arrayfun(#myfunction,....);
You cannot, the bsxfun is only for binary operations

Series-function with vector-coefficients in Matlab

I have a vector v and would like to define a function x using following formular:
Now I try to define this in Matlab, but for some reason I can't access an array within a symsum.
v = [1 2 3 4];
syms k
x = #(t) symsum(v(k) * exp(2*pi*i*k*t/size(v)), k, 1, size(x_n));
When I try to evaluate this Function x(4) I get an exception:
Error using sym/subsindex (line 796)
Invalid indexing or function definition. When defining a function, ensure that the arguments are
symbolic variables and the body of the function is a SYM expression. When indexing, the input
must be numeric, logical, or ':'.
Do you know, why? Do you have a solution or workaround?

How to decipher matlab function syntax ambiguity [duplicate]

This question already has answers here:
What is the # operator (at sign) in MATLAB?
(3 answers)
Closed 9 years ago.
I cannot find this syntax anywhere
y = #(beta, x)x*beta;
where x is some vector or matrix lets say. Is # used to reference another function so you can have more than one externally visiuble function in the same .m file? Sorry I'm new to matlab but can't find this in the documentation
That is the way to define an anonymous function in Matlab. It is basically the same as
function result = y(beta, x)
result = x * beta;
but without needing an m-file or subfunction to define it. They can be constructed within other m-files or even within an expression. Typical use is as a throw-away function inside the call of some complex function that needs a function as one of its inputs, i.e.:
>> arrayfun(#(x) x^2, 1:10)
ans =
1 4 9 16 25 36 49 64 81 100
I personally use them a lot to refactor a list of repetitive statements
a = complex_expression(x, y, z, 1)
b = complex_expression(x, y, z, 3)
c = complex_expression(x, y, z, 8)
into
f = #(n) complex_expression(x, y, z, n)
a = f(1)
b = f(3)
c = f(8)
More info from the Mathworks. They are more or less the same as a lambda expression in Python.
Think of # as anonymous which means an unnamed function (technically, in MATLAB, you must give it a name since you cannot do e.g., (#(x, y) x + y)(1, 2), that name is whatever variable you assign the anonymous function to).
The syntax #(x, y) x + y reads: create an anonymous # function with parameters x and y and return the result of the evaluation of the expression following the next closing parenthesis. In this case, that's the addition of x and y.
One thing that almost no one I know who uses MATLAB uses on a regular basis and instead uses repmat hell instead is bsxfun (it stands for binary singleton expansion).
With the expression bsxfun(#plus, randn(1000, 20), randn(1000, 1)) you essentially repmat the right hand side 20 times to form a new matrix that you then pass to the #plus function handle. You can pass any function around this way. Take a look at cellfun and arrayfun. They are incredibly useful.