Azzera filtri
Azzera filtri

Function that makes Anonymous Functions

18 visualizzazioni (ultimi 30 giorni)
I want to create a MATLAB function that takes a set of data, fits a curve with the least error, and returns the fitted curve as an anonymous function. When I attempted this, the anonymous function contained variables instead of numerical coefficients. Is there a way to modify the function so that it generates an anonymous function with specific numerical coefficients?

Risposta accettata

Matt J
Matt J il 12 Dic 2023
Modificato: Matt J il 12 Dic 2023
When I attempted this, the anonymous function contained variables instead of numerical coefficients
I assume you mean that in the example below, you would like the anonymous function fn to be displayed with something like 3.141593 in place of C
C=pi;
fn=@(x) C*x+1
fn = function_handle with value:
@(x)C*x+1
If so, you can do things like the following, but bear in mind that if you don't use sprintf to print the coefficient to 15 digits, the resulting output of fn() will accordingly not be computed to full double precision.
fn=str2func(sprintf('@(x) %.15f*x+1',C))
fn = function_handle with value:
@(x)3.141592653589793*x+1
  3 Commenti
Steven Lord
Steven Lord il 12 Dic 2023
And note that while this is possible for this small case, in general you wouldn't want the numeric value of the coefficient to be displayed.
A = gallery('moler', 5)
A = 5×5
1 -1 -1 -1 -1 -1 2 0 0 0 -1 0 3 1 1 -1 0 1 4 2 -1 0 1 2 5
f = @(x) A*x
f = function_handle with value:
@(x)A*x
Would you really want f to display the 5-by-5 matrix as part of its display? Okay, I suppose that's not too bad. How about something a bit larger?
B = gallery('moler', 1e3);
g = @(x) B*x
g = function_handle with value:
@(x)B*x
size(B)
ans = 1×2
1000 1000
That would be a bit bigger of a display.
strlength(formattedDisplayText(B))
ans = 12064751
I wouldn't want the display of g to show more than 12 million characters. I'm perfectly happy for the anonymous function to "remember" the value of B and use it in computations.
info = functions(g)
info = struct with fields:
function: '@(x)B*x' type: 'anonymous' file: '/tmp/Editor_enflz/LiveEditorEvaluationHelperEeditorId.m' workspace: {[1×1 struct]} within_file_path: ''
isequal(info.workspace{1}.B, B)
ans = logical
1

Accedi per commentare.

Più risposte (2)

Image Analyst
Image Analyst il 12 Dic 2023
Did you try something like this:
x = [5, 10];
y = [15, 25];
% Get parameters.
[a, b] = GetFit(x, y)
a = 2.0000
b = 5.0000
% Define anonymous function
f = @(x) a*x+b
f = function_handle with value:
@(x)a*x+b
% Call anonymous function with a value of 7.5
yFit = f(7.5)
yFit = 20.0000
%=======================================================
function [a, b] = GetFit(x, y)
coefficients = polyfit(x, y, 1);
a = coefficients(1);
b = coefficients(2);
end

Walter Roberson
Walter Roberson il 12 Dic 2023
When an anonymous function is created and the function has reference to variables that are not named parameters, then MATLAB inserts the names of the variables into the anonymous function. MATLAB also associates a property named workspace with the anonymous function, which is a scalar cell array. Inside the scalar cell array, there is a struct with one field for each "captured" variable, and with the associated value.
When anonymous functions are created, MATLAB makes no attempt to substitute values for variables that are used in the function. It does not even examine the values to determine their class: all it looks for is whether the name is defined as a variable in scope, and if so creates a copy-on-write reference to the name.
MATLAB will not attempt to substitute the text equivalent of variables for variable names.
If MATLAB were to attempt to substitute the text equivalent of variables for variable names, it would at most be able to do so for objects that could be exactly duplicated by plain text constructor calls, such as classes that do not have methods that can assign to class properties, with all of the initialization being in the class initiazation or the class constructor. Numeric classes are potentially do-able -- but remember that MATLAB does not have any direct syntax for constructing numeric arrays with more than 2 dimensions, so the text that would have to be emitted for 3 or more dimensions would have to include calls to cat() along dimensions of smaller pieces constructed with [] calls. That would get a bit messy fairly quickly. And what if the variable is fairly large?
The alternative that would allow MATLAB to encode more types of variables would be if the way MATLAB encoded variables was that it exposed its internal interface to serialize and deserialize objects https://undocumentedmatlab.com/articles/serializing-deserializing-matlab-data . The way that MATLAB sends objects between parallel clients and workers is that it serializes the objects into text and deserializes them on the other side. Serialization of objects contains information about how to recreate some relatively complicated objects.
Unfortuantely, serialized objects are unreadable by humans. So it is not clear that it would help anything for MATLAB to convert an anonymous function like @(x) x + A into
@(x) x + deserialize('yPdph0W.026c2QMiNKhbFNDGsRgYxLNlt1spYRcLn6Sme01TENS3NOJwUBJrdgdGt0NbxTRfmOTfleo262ArZByYrKEiXI19oXQ6e8bBVLD69tk0pFurMK9OJqHsCMMb')
It might have converted the objects into printable text instead of just encoding the object names, but have you gained anything of worth?

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Prodotti


Release

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by