You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to use anonymous functions
2 views (last 30 days)
Show older comments
I am trying to understand anonymous functions. What exactly does this do:
pTransition = [
0 0 0 0 0
0 .05 .1 .05 0
0 .1 .4 .1 0
0 .05 .1 .05 0
0 0 0 0 0 ];
getPLocalTransition = @(localCoordinate) ...
pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3);
1 Comment
Walter Roberson
on 5 Mar 2022
What exactly does this do
We do not know exactly what it does. The details of how function handles are created and processed internally are MATLAB proprietary details, hidden in code that people outside Mathworks do not have access to.
I could probably spend more than an hour writing up and providing references to how it probably works internally, in order to be consistent with actions we can test and documentation we have access to, but unless you are into Compiler Construction, and Denotation Semantics, that would likely be a waste of my time, compared to the possibility that you could instead ask a specific question that you are trying to resolve in your mind.
When you get into an elevator and you ask "How exactly does this work?" are you asking about multi-phase motor theory, or are you asking about the material science behind the precise choice of compounds used in the emergency brakes, or are you asking about how the emergency phone works, or are you asking about how capacitance sensing works for the push buttons?
Accepted Answer
KSSV
on 5 Mar 2022
The function needs a localCoordinate as input and it should be a 1X2 array. The array can have values 0,1,2.
Depedning on the values given, to the array 3 is added, these are the indices and the respective values are extracted from pTransition.
74 Comments
Walter Roberson
on 5 Mar 2022
The input localCoordinate does not need to be a row vector: it could be a column vector or any array with at least two entries (since linear indexing is used.)
The first two entries of localCoordinates must be integers chosen from [-2, -1, 0, 1, 2]. I suspect that the normal values are chosen from [-1, 0, 1] representing offsets from the center of the array.
Ken
on 5 Mar 2022
I intend using the above to determine the probability of a robot being in state x_t, having been at x_tm1 and given input u_t. I used the foll. lines but get error.
calcPTransition = @(x_t, u_t, x_tm1) ;
calcPTransition(x_t[1,1]=u_t[1,1]+{x_tm1[1,1]};
Walter Roberson
on 6 Mar 2022
You need to provide a body of code when you define an anonymous function.
MATLAB does not use [] for indexing.
MATLAB does not permit assignment in the middle of an expression.
In context, that {} after an operator is building a cell array (rather than indexing). But no addition operator is defined for cell arrays.
I see a hint there that you just might be trying to update a variable from inside an anonymous function. It is not strictly impossible to update (some) variables from within anonymous functions, but it not an intended use, and it is tricky and ugly to update a variable from inside an anonymous function. Anonymous functions should be used for extracting and calculating.
Ken
on 6 Mar 2022
I want to first compute the local coordinates given x_t x_{t-1} and u_t, and then want to make sure to clip these local coordinates to the bounds [-2, 2] using the min and max functions. This is to ensure that it remains within the bounds of pTransition (5X5 matrix). Trouble is I keep getting error messges.
Walter Roberson
on 6 Mar 2022
getPLocalTransition = @(localCoordinate) ...
pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3);
x_t = u_t + x_tm1;
x_t = max(-2, min(2, x_t));
calcPTransition = getPLocalTransition(x_t);
Walter Roberson
on 6 Mar 2022
No anonymous function can ever have an assignment operator within it.
But it does not need to have that.
calcPTransition = @(x_t, u_t, x_tm1) getPLocalTransition( max(-2, min(2, u_t + x_tm1)) )
Note that this does not update x_t to the new value.
Ken
on 6 Mar 2022
x_t = u_t + x_tm1;
x_t = max(-2, min(2, x_t));
calcPTransition = getPLocalTransition(x_t);
The previous solution (above) seems better, only problem is since u_t etc. was not declared, it gave error.
Unrecognized function or variable 'u_t'.
Error in solution (line 11)
x_t = u_t + x_tm1;
Walter Roberson
on 6 Mar 2022
When you were experimenting with the code
calcPTransition = @(x_t, u_t, x_tm1) ;
calcPTransition(x_t[1,1]=u_t[1,1]+{x_tm1[1,1]};
then what were you planning to pass in to calcPTransition when you called the function handle?
Ken
on 6 Mar 2022
The line "calcPTransition(x_t[1,1]=u_t[1,1]+{x_tm1[1,1]};" was just me trying different approaches to make it work so should be ignored. What I am trying is:
calcPTransition calculates the prob of being in state x_t being previously in state x_tm1 and given the input u_t. x_t and x_tm1 are 1 X 2 vectors of integer grid cell co-ordinates. So, x_t, x_tm1 and u_t were what I was planning to pass to calcPTransition
Walter Roberson
on 7 Mar 2022
It is Sunday evening where I am. We have been cooking and cleaning.
What is your input u_t? Is it a vector of two offsets?
So you look up one single probability... then what? You cannot use one single probability to transition—not unless you only have two states and the probability of switching states is 1 minus the probability that you look up.
Walter Roberson
on 7 Mar 2022
Again, what are you going to do with that probability?
If you are doing a simulation of which state you end up in given particular inputs, then at each step you need to know what all the possibilities are, and you need to generate a random number and use it to figure out which state to transit to. And then you would go back and resimulate multiple times to build up a probability. (Or equivalently, keep track of a whole bunch of states in parallel.)
If you are trying to analyze in one pass to find the mathematical probabilities without simulation, then you would probably need to do an analysis using Markov Chain theory, perhaps involving taking eigenvalues.
Ken
on 7 Mar 2022
Edited: Ken
on 7 Mar 2022
This is tracking the position of the robot on a global grid, the current global coordinates of the robot are still important. For example, if x_{t-1} = (0, 0), and u_t = (0, 2), then p(x_t = (0, 2)) is 0.4. Now, consider same u_t, however x_{t-1} = (0, 1). In that case, p(x_t = (0, 2)) is 0.1.
Steven Lord
on 7 Mar 2022
Let's take a step back from the code for a moment. Describe what data you have (and the format in which you have it stored) and explain in words not code what you're trying to do with that data. It's possible if the operations you're trying to perform are iterative that it would be difficult or impossible to write your code as just anonymous functions.
Walter Roberson
on 7 Mar 2022
Might I suggest that the real meaning of the table might be:
If you are currently in a state, then you have a 0.4 of staying in the same state, you have a 0.05 probability each of moving in one of the diagonal directions, and you have a .1 probability each of moving forward, back, left, right.
At the moment I do not know how the inputs are intended to influence this. One possibility is that they shift the location that you are considered to be currently "at" -- so for example if your modified current location was considered to be back-left then you might have a 0.4 of moving ahead-right -- and a 0.05 of moving two steps to the right on this move.
Ken
on 7 Mar 2022
Edited: Torsten
on 7 Mar 2022
I am trying the Markov localization prediction algorithm in MATLAB. My robot moves in global coordinates depicted in a square grid. I know its previous stae x_t-1. I give it an input u_twhich is a 2-element integer offset. I now try to predict the state x_t where the robot has moved.For this, I have a transition 5X5 grid called pTransition. This has its probabilities in each square of the grid. I try to calculate state x_t (probability) of where the robot has moved to. I use an anonymous function calculatePTransition for this purpose which has x_t,x_t-1 and u_t as its arguments. This is as shown below.
pTransition = [
0 0 0 0 0
0 .05 .1 .05 0
0 .1 .4 .1 0
0 .05 .1 .05 0
0 0 0 0 0 ];
getPLocalTransition = @(localCoordinate) ...
pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3);
%%%%%%%%%%% PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE %%%%%%%%%%%
calcPTransition = @(x_t, u_t, x_tm1) ...;
plotPredictionUpdate(calcPTransition);
Torsten
on 7 Mar 2022
Edited: Torsten
on 7 Mar 2022
So the matrix gives P(x_t = x_(t-1) + u_t) for 9 possible translation vectors u_t ?
P(x_t = x_(t-1) + (0,0)) = 0.4
P(x_t = x_(t-1) + (1,0)) = P(x_t = x_(t-1) + (0,1)) = P(x_t = x_(t-1) + (-1,0)) = P(x_t = x_(t-1) + (0,-1)) = 0.1
P(x_t = x_(t-1) + (1,1)) = P(x_t = x_(t-1) + (1,-1)) = P(x_t = x_(t-1) + (-1,1)) = P(x_t = x_(t-1) + (-1,-1)) = 0.05 ?
Then "local_coordinate" would be u_t.
Walter Roberson
on 7 Mar 2022
Put whatever you want in the anonymous function, as long as it is syntactically valid. That anonymous function has no relevance to your goal, if you have described your goal correctly.
Ken
on 8 Mar 2022
Q You first have to tell us what calcPTransition is supposed to output given x_t, u_t and x_tm1.
The probability that x_t = x_tm1 + u_t ?
A Yes, calcPTransition is supposed to output x_t given u_t and x_tm1
In the above Q nd A, my A may not have been precise. It should be the probability indicated in the cell obtained by x_t = x_tm1 + u_t
Ken
on 8 Mar 2022
pTransition = [
0 0 0 0 0
0 .05 .1 .05 0
0 .1 .4 .1 0
0 .05 .1 .05 0
0 0 0 0 0 ];
getPLocalTransition = @(localCoordinate) ...
pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3);
%%%%%%%%%%% PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE %%%%%%%%%%%
calcPTransition = @(x_t, u_t, x_tm1)...
x_t = u_t + x_tm1;
x_t = max(-2, min(2, x_t));
calcPTransition = getPLocalTransition(x_t);
plotPredictionUpdate(calcPTransition);
With the above script, I get:
File: solution.m Line: 11 Column: 5
Incorrect use of '=' operator. Assign a value to a variable using '=' and compare values for equality using '=='.
Walter Roberson
on 8 Mar 2022
I am pretty sure that I have said multiple times that you cannot have an assignment inside an anonymous function.
Furthermore if your code
calcPTransition = @(x_t, u_t, x_tm1)...
x_t = u_t + x_tm1;
x_t = max(-2, min(2, x_t));
was a valid way to define an anonymous function, then observe that in the next line
calcPTransition = getPLocalTransition(x_t);
you would be overwriting all of calcPTransition.
Also, when I look at the line
plotPredictionUpdate(calcPTransition);
I am left with the suspicion that plotPredictionUpdate is expecting a function handle. But what it does with that function handle is not known to us.
Ken
on 8 Mar 2022
Your solution "calcPTransition = @(x_t, u_t, x_tm1) getPLocalTransition( max(-2, min(2, u_t + x_tm1)) );" almost worked i.e. no compile errors and it did plot using plotPredictionUpdate(calcPTransition); The error I got when running it was it did not update x_t. So, the plot statement is correct.
Walter Roberson
on 8 Mar 2022
You could define x_t in terms of a handle class that also defines some mathematical operations such as plus(), together with some kind of update operation.
But... if I have deduced properly what the undocumented function plotPredictionUpdate() is (approximately) intended to do, then I would be astonished if updating x_t in calcPTransition would be the proper thing to do. I predict that plotPredictionUpdate() calls the function handle multiple times with different parameters to explorer the local area. If I am correct, then unless you knew the scan order, updating the value of x_t while plotPredictionUpdate() is running would give you very wrong results.
Ken
on 8 Mar 2022
This is the problem as originally laid out . You will see that plot is already given in the problem - nothing done by me:
pTransition = [
0 0 0 0 0
0 .05 .1 .05 0
0 .1 .4 .1 0
0 .05 .1 .05 0
0 0 0 0 0 ];
getPLocalTransition = @(localCoordinate) ...
pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3);
%%%%%%%%%%% PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE %%%%%%%%%%%
calcPTransition = @(x_t, u_t, x_tm1) ???; % maybe use getPLocalTransition
plotPredictionUpdate(calcPTransition);
Walter Roberson
on 8 Mar 2022
The material you have presented to us has no solution.
Ken
on 9 Mar 2022
Not sure of that. This is a published problem that has been solved many times. Got a suggestion to use a helper function in the anonymous function i.e.
calcPTransition = @(x_t, u_t, x_tm1) getPLocalTransition(get_direction(x_t, u_t, x_tm1));
Walter Roberson
on 9 Mar 2022
I am 100% certain that the material you have presented to us has no solution.
Ken
on 9 Mar 2022
I tried this but getting compile error:
calcPTransition = @(x_t, u_t, x_tm1) getPLocalTransition(get_direction(x_t, u_t, x_tm1));
plotPredictionUpdate(calcPTransition);
function dir = get_direction(x_t, u_t, x_tm1)
dir = [0,0]; % do your calculations on as many lines as you desire
x_t=u_t+x_tm1;
x_t=max(-2,min(u_t+x_tm1));
%calcPTransition = getPLocalTransition(x_t );
end
plotPredictionUpdate(calcPTransition);
error:
Error in solution: Line: 21 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "get_direction" function definition to before the first local function definition.
Walter Roberson
on 10 Mar 2022
Why are you calling plotPredictionUpdate() a second time? You should only have that first place.
Walter Roberson
on 10 Mar 2022
In the code you posted, the (second) line
plotPredictionUpdate(calcPTransition);
was after the function definition for get_direction()
In MATLAB, once you start your first function definition, everything else to the bottom of the file has to be function definitions.
The code you had in https://www.mathworks.com/matlabcentral/answers/1664204-how-to-use-anonymous-functions#comment_2030754 would not define an anonymous function, then call plotPredictionupdate(), then define the function get_direction, and then switch back to the original script to call plotPredictionUpdate a second time. MATLAB is just not designed that way.
In MATLAB, once you have hit your first function line, you have a couple of possibilities. You can have a structure that looks like
some code before any function
function first_function
code for first_function
end
function second_function
code for second_function
end
This defines first_function and second_function independently inside a script. Notice that all the executable code is either before the first function or else is inside a function/end pair.
Or you can have
some code before any function
function first_function
code for first_function
function second_function
code for second_function
end
end
This defines second_function to be private to first_function, and cannot (normally) be called anywhere except from first_function. Notice that all executable code is either before the first function or else is inside a function/end pair
Or you can have
some code before any function
function first_function
code for first_function
function second_function
code for second_function
end
more code for first_function
end
This defines second_function to be private to first_function, and cannot (normally) be called anywhere except from first_function. The "code for first function" would be sort-of executed before attempting to define second_function, and after second_function was defined, you would return to defining first function with the "more coe for first_function". Notice that all executable code is either before the first function or else is inside a function/end pair.
But you cannot do
some code before any function
function first_function
code for first_function
end
more code outside any function
Once you get to the first function then all code must be within a function/end pair.
The rules are a bit different for files that do not have any "script" at the top -- files that immediately start with a function line. In such files, you can use the function/end pair like above, or you can define all functions with no end for functions at all:
function first_function
code for first_function
function second_function
code for second_function
If you were to put in an end matching any function statement in such a file, you would get an error message. Either every function statement must have a matching end statement, or else no function statement can have an end statement. But inside a script file (a file for which the first executable word is not function or classdef ) then matching function/end is the only option.
Ken
on 10 Mar 2022
Thanks. Tried:
pTransition = [
0 0 0 0 0
0 .05 .1 .05 0
0 .1 .4 .1 0
0 .05 .1 .05 0
0 0 0 0 0 ];
getPLocalTransition = @(localCoordinate) ...
pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3);
%%%%%%%%%%% PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE %%%%%%%%%%%
calcPTransition = @(x_t, u_t, x_tm1) getPLocalTransition(get_direction(x_t, u_t, x_tm1));
plotPredictionUpdate(calcPTransition);
function dir = get_direction(x_t, u_t, x_tm1)
dir = [0;0]; % do your calculations on as many lines as you desire
x_t=u_t+x_tm1;
x_t=max(-2,min(u_t+x_tm1));
end
Got error:calcPTransition evaluates to a wrong value for x_t=[1 1], u=[-4 -4],
x_tm1=[0 0] : 0.4 (0 expected)
the goal is to find an expression for the transition probabilities of the robot ending up in
cell x_t, which is given by x_tm1+u_t plus some noise as defined by pTransition. To lookup the
probability for a given x_t from pTransition, you need to transform x_t into local indices
centered around x_tm1+u_t.
For example, in case where x_t = x_tm1 + u_t (no noise), the index of the local transition matrix
should be [0, 0].
Walter Roberson
on 10 Mar 2022
function dir = get_direction(x_t, u_t, x_tm1)
dir = [0;0]; % do your calculations on as many lines as you desire
x_t=u_t+x_tm1;
x_t=max(-2,min(u_t+x_tm1));
end
That code always returns [0;0] no matter what inputs are passed.
It also ignores the input x_t, and creates its own x_t but does not do anything with the value.
Walter Roberson
on 10 Mar 2022
Is it correct that dir should always be [0;0] ? Or is dir what you calculate through the max(min) ?
Ken
on 10 Mar 2022
I don't think dir should always be [0;0] . The goal is to find an expression for the transition probabilities of the robot ending up in cell x_t, which is given by x_tm1+u_t plus some noise as defined by pTransition. To lookup the probability for a given x_t from pTransition, you need to transform x_t into local indices centered around x_tm1+u_t.
For example, in case where x_t = x_tm1 + u_t (no noise), the index of the local transition matrix should be [0, 0].
Walter Roberson
on 11 Mar 2022
function dir = get_direction(x_t, u_t, x_tm1)
dir = [0;0]; % do your calculations on as many lines as you desire
That is a constant. No matter what parameters are passed, you always assign [0;0] to dir .
dir is also your return variable. Unless another value is assigned to dir before the end of the function, this constant will be what you return.
x_t=u_t+x_tm1;
That overwrites that x_t that was passed in. It is not obvious why you bother passing in x_t if you are just going to overwrite it, but perhaps you have Good Reasons.
x_t=max(-2,min(u_t+x_tm1));
Okay, you limit the x_t you calculated. That is fine so far.
end
But now you have completed the function. You have not assigned anything else to dir so it is always going to return [0;0] . You assigned something internally into x_t but that is confined to the function workspace, and will not affect anything outside the function.
To emphasize: the change you make to x_t here will not change x_t in the calling function.
As far as MATLAB is concerned, your function is effectively
function dir = get_direction(~, ~, ~)
dir = [0;0];
if nargin < 3; error('insufficient arguments'); end
now waste a bit of time
end
I would suggest to you that it is highly likely that your output variable, dir should be set to something calculated based upon at least one of the input variables.
Ken
on 11 Mar 2022
I checked with some inputs i.e. u_t=[0, 0] and x-t=[1,1] etc. and it seems to point to the correct grid in pTansition. So in tht case calcpTransition should give the correct probability. Not sure if this is a rigorous check.
Walter Roberson
on 12 Mar 2022
Possibly
function dir = get_direction(x_t, u_t, x_tm1)
dir = u_t+x_tm1;
dir = max(-2,min(u_t+x_tm1));
end
Walter Roberson
on 12 Mar 2022
Where did the 2 go in the min() call ? https://www.mathworks.com/matlabcentral/answers/1664204-how-to-use-anonymous-functions#comment_2023794
Walter Roberson
on 12 Mar 2022
I was copying from one of your posts in which the 2 was missing; https://www.mathworks.com/matlabcentral/answers/1664204-how-to-use-anonymous-functions#comment_2032654
Walter Roberson
on 12 Mar 2022
It seems to me that you only have 8 possibilities to test
- temp = [0;0];
- temp = x_t;
- temp = u_t;
- temp = x_tm1;
- temp = x_t + u_t;
- temp = x_t + x_tm1;
- temp = u_t + x_tm1;
- temp = x_t + u_t + x_tm1;
Followed by
dir = max(-2, min(2, temp));
One of those should work.
Walter Roberson
on 12 Mar 2022
Did you try all 8 possibilities?
Walter Roberson
on 12 Mar 2022
Okay, well, have fun with that then.
Walter Roberson
on 12 Mar 2022
I have nothing further to contribute to your pinv with accuracy thread.
Ken
on 12 Mar 2022
Got a response:
"You now have 2 issues left, the first one is about the MATLAB function syntax: When you define a function with function dir = get_direction(x_t, u_t, x_tm1), the variable dir is what gets returned in the end, so your code has always returned [0,0] so far.
The second is about the vector that you are calculating. The matrix pTransition describes the probability to move onto a neighbouring cell of x_tm1+u_t, further getPLocalTransition(...) expects a direction vector that is relative to this location. Since you use u_t+x_tm1 as input, which is relative to wold origin (0,0), this will most likely result to a probability of 0 (because the map is much bigger than the 5x5 of pTransition)."
Ken
on 12 Mar 2022
I tried this i.e. did not use dir=[0;0]. Then I used the foll sentence to convert to local coordinates. Still no luck. getPLocalTransition(pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3)); function dir = get_direction(x_t, u_t, x_tm1); temp = u_t + x_tm1 ; dir = getPLocalTransition(max(-2,min(2,temp))); dir= getPLocalTransition(pTransition(localCoordinate(1) + 3, localCoordinate(2) + 3)); end
More Answers (0)
See Also
Categories
Find more on Encryption / Cryptography in Help Center and File Exchange
Tags
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)