How to decipher matlab function syntax ambiguity [duplicate] - matlab

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.

Related

Convert input of an anonymous function

I have an anonymous function A taking two arguments. I need to convert this function so it takes one argument, by changing the other argument to a constant.
For example having a function:
A = #(X, Y) X + Y;
I would like now to have:
B = #(Y) 3 + Y;
This seems to be a normal thing to do in mathematics, so I guess there is a way to do such thing in MATLAB. I cannot find the solution though.
The reason I need to do something like this is that I have a function that does some calculations on A, but also needs to solve problems when one of the A's arguments is constant. For example find a minimum of the A for X = 3.
You can use the same anonymous function and put X as 3 in it but if you want to create another anonymous function, here is how to do that:
A = #(X, Y) X + Y;
B = #(Y) A(3,Y); %Here you have put X=3
To verify:
>> A(3,4)
ans =
7
>> B(4)
ans =
7

Row--wise application of an inline function

I defined an inline function f that takes as argument a (1,3) vector
a = [3;0.5;1];
b = 3 ;
f = #(x) x*a+b ;
Suppose I have a matrix X of size (N,3). If I want to apply f to each row of X, I can simply write :
f(X)
I verified that f(X) is a (N,1) vector such that f(X)(i) = f(X(i,:)).
Now, if I a add a quadratic term :
f = #(x) x*A*x' + x*a + b ;
the command f(X) raises an error :
Error using +
Matrix dimensions must agree.
Error in #(x) x*A*x' + x*a + b
I guess Matlab is considering the whole matrix X as the input to f. So it does not create a vector with each row, i, being equal to f(X(i,:)). How can I do it ?
I found out that there exist a built-in function rowfun that could help me, but it seems to be available only in versions r2016 (I have version r2015a)
That is correct, and expected.
MATLAB tries to stay close to mathematical notation, and what you are doing (X*A*X' for A 3×3 and X N×3) is valid math, but not quite what you intend to do -- you'll end up with a N×N matrix, which you cannot add to the N×1 matrix x*a.
The workaround is simple, but ugly:
f_vect = #(x) sum( (x*A).*x, 2 ) + x*a + b;
Now, unless your N is enormous, and you have to do this billions of times every minute of every day, the performance of this is more than acceptable.
Iff however this really and truly is your program's bottleneck, than I'd suggest taking a look at MMX on the File Exchange. Together with permute(), this will allow you to use those fast BLAS/MKL operations to do this calculation, speeding it up a notch.
Note that bsxfun isn't going to work here, because that does not support mtimes() (matrix multiplication).
You can also upgrade to MATLAB R2016b, which will have built-in implicit dimension expansion, presumably also for mtimes() -- but better check, not sure about that one.

Use fminsearch to find local minimizer and the minima at that value

I am having trouble using fminsearch: getting the error that there were not enough input arguments for my function.
f = #(x1,x2,x3) x1.^2 + 3.*x2.^2 + 4.*x3.^2 - 2.*x1.*x2 + 5.*x1 + 3.*x2 + 2.*x3;
[x, val] = fminsearch(f,0)
Is there something wrong with my function? I keep getting errors anytime I want to use it as an input function with any other command.
I am having trouble using fminsearch [...]
Stop right there and think some more about the function you're trying to minimize.
Numerical optimization (which is what fminsearch does) is unnecessary, here. Your function is a quadratic function of vector x; in other words, its value at x can be expressed as
x^T A x + b^T x
where matrix A and vector b are defined as follows (using MATLAB notation):
A = [ 1 -1 0;
-1 3 0;
0 0 4]
and
b = [5 3 2].'
Because A is positive definite, your function has one and only one minimum, which can be computed in MATLAB with
x_sol = -0.5 * A \ b;
Now, if you're curious about the cause of the error you ran into, have a look at fuesika's answer; but do without fminsearch whenever you can.
It is exactly what Matlab is telling you: your function expects three arguments. You are passing only one.
Instead of
[x, val] = fminsearch(f,0)
you should call it like
[x, val] = fminsearch(f,[0,0,0])
since you define the function f to accept a three dimensional vector as input only.
You can read more about the specification of fminsearch in the online documentation at http://mathworks.com/help/matlab/ref/fminsearch.html:
x = fminsearch(fun,x0) starts at the point x0 and returns a value x
that is a local minimizer of the function described in fun. x0 can be
a scalar, vector, or matrix. fun is a function_handle.

How to pass the value of an array to a mathematical function in Matlab?

I have a defined mathematical function: f =Inline('x1^2+x2^2+2*x1*x2','x1','x2')
and I have an array that represents the number value of x1 and x2. (e.g. the array is A=[1 2])
I want to automate the process of getting the f(x1,x2), but I couldn't figure out the right way that Matlab can take in the array and assign values to x1 and x2.
What can I do to pass in the array values to the mathematical model and get the function value?
You should be using anonymous functions instead of inline since inline will be removed in a future release of MATLAB.
Example (from the docs):
sqr = #(x) x.^2;
a = sqr(5)
a =
25
In your case:
f = #(x) x(1)^2+x(2)^2+2*x(1)*x(2);
Now it expects x to be a two (or more) value array.
A = [1 2];
f(A) =
9
Note:
I don't have MATLAB on my home computer so I haven't actually tested this but it should get you going in the right direction. Have a look over the docs and you'll be fine.

Simple MATLAB Variable Question

Please help me write a MATLAB program that constructs a column matrix b, such that
b1 = 3x1 - 3/4y0
b2 = 3x2
...
bn-2 = 3xn-2
bn-1 = 3xn-1 - 3/4yn
where x and y are variables. Notice that y only appears in the first and last entries of b.
My problem is that I don't know how variables work in MATLAB. I tried
b = 3*x
and it says
??? Undefined function or variable 'x'
So, how do we create variables instead of constants?
Thanks!
EDIT:
From your comments above, what you need is MATLAB's symbolic toolbox, which allows you to perform computations in terms of variables (without assigning an explicit value to them). Here's a small example:
syms x %#declare x to be a symbolic variable
y=1+x;
z=expand(y^2)
z=
x^2 + 2*x + 1
You will need to use expand sometimes to get the full form of the polynomial, because the default behaviour is to keep it in its simplest form, which is (1+x)^2. Here's another example to find the roots of a general quadratic
syms a b c x
y=a*x^2+b*x+c;
solve(y)
ans =
-(b + (b^2 - 4*a*c)^(1/2))/(2*a)
-(b - (b^2 - 4*a*c)^(1/2))/(2*a)
I think you meant bn and xn in the last line... Anyway, here's how you do it:
b=3*x;
b([1,end])=b([1,end])-3/4*y([1,end])
You can also do it in a single line as
b=3*x-3/4*[y(1); zeros(n-2,1); y(end)];
where n is the length of your vector.
You never stated your problem...
Anyways just set the first entry of b individually first. Then use a loop to set the next values of b from 2 up to n-2. Then set the last entry of b individually.
On a side note, if x is a vector, you can simply vectorize the loop part.