Trying to package anonymous function + function parameters in a structure

I assumed this would work but it doesn't:
myStruct.A = 3;
myStruct.B = 7;
myStruct.myFunc = @(x) myStruct.A*x + myStruct.B;
test1 = myStruct.myFunc(1) %Returns 10
myStruct.B = 6;
test2 = myStruct.myFunc(1) %Still returns 10 but i want it to return 9
This is a trivial example but in my actual script the function i am working with it quite complicated; Imagine that this goes from Struct.A to Struct.Z and every one is a vector or matrix. This would get very tedious if I had to write the function with a @(x, A,B,C,..Z).
Looking for recomedations on how to acheive this.

 Risposta accettata

Your anonymous function takes a "snapshot" of the variable myStruct as it exists when the anonymous function is taken. The only way to update that "snapshot" is to recreate the anonymous function. You can see this using the debugging tool functions. As its documentation page states, don't try using this programmatically. It's intended to debugging and diagnosing problems.
myStruct.A = 3;
myStruct.B = 7;
myStruct.myFunc = @(x) myStruct.A*x + myStruct.B;
data = functions(myStruct.myFunc)
data.workspace{1}
data.workspace{1}.myStruct
Probably the easiest option, since you say you don't want to define an anonymous function with 27 inputs (and I wouldn't want to define such a function either) is to define one with two inputs.
myStruct.myFunc = @(x, myStruct) myStruct.A*x + myStruct.B;
myStruct.A = 3;
myStruct.B = 7;
myStruct.myFunc(1, myStruct) % 10
myStruct2 = myStruct;
myStruct2.B = 6;
myStruct.myFunc(1, myStruct2) % 9
This has an added benefit of allowing you to pass the same struct array into multiple functions. Each one uses the pieces of data it wants and ignores those pieces it doesn't.
myStruct2.C = 46;
myStruct2.myFunc2 = @(x, myStruct) myStruct.C-x./myStruct.A;
myStruct2.myFunc2(12, myStruct2) % ignores myStruct2.B entirely

5 Commenti

Brilliant. I wish I thought of this
Thank you so much for your time. You saved me a lot of effort because i would have attempted something way more difficult.
You're welcome.
By the way, if your struct fields are always all scalars (or are all "stackable" in some dimension) you could simplify this a little more by using an array.
f = @(A, rowind) A(rowind, :);
M = magic(5) % 5 pieces of data, each row vectors with 5 elements
secondPieceOfData = f(M, 2)
Another example is the red, green, and blue data for an RGB truecolor image. They are each matrices of the same size, so they can be "stacked" (concatenated) in the third dimension to make an M-by-N-by-3 array. This simple function just extracts the selected color data.
showColorPlane = @(imageArray, rgb) imageArray(:, :, rgb)
I = imread('ngc6543a.jpg'); % Sample image included in MATLAB
figure;
image(showColorPlane(I, 1));
title('Red')
figure;
image(showColorPlane(I, 2));
title('Green')
figure;
image(showColorPlane(I, 3));
title('Blue')
figure
image(I)
title('All three')
Thanks. I am already doing this in some cases. But most of my scalars have unrelated meanings and units so if i put them in an array the code becomes very unreadable by the rest of my team
I wish Matlab allowed default values for anonymous functions, this would save me some typing and make my code more readable.

Accedi per commentare.

Più risposte (0)

Prodotti

Release

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by