- Technical Services and Consulting
- Embedded Systems
- Electrical and Electronics Engineering
Automatically change the input arguments of function handles
32 次查看(过去 30 天)
显示 更早的评论
I have a function with four variables (u, v, w and t) and I would like to analyze the influence of different combinations of two of the variables, for specific values of the other two. To do that I define an anonymous function handle.
For example, to analyze the influence of u and v for w = 0, t = 0.
fun = @(u, v) u + v.^2 – w + sin(t) + rot(u,v).
where rot is another function handle that depends on u, v and w:
rot = @(u,v) = u.^2 + v + 2.*w.*u;
My question is the following: is it possible to change the input arguments of the function handle automatically? That is, if I want to change, and analyze the influence of v-w for u = 0 and t = 0, instead of writing
fun = @(v,w) u + v.^2 – w + sin(t) + rot(v,w)
save the four variables in an array and use something similar to this:
var = [u,v,w,t]
input1 = var(2); input2 = var(3)
fun = @(input1,input2) u + v.^2 – w + sin(t) + rot(input1,input2)
In doing so, I was hoping that once the two input arguments (input1,input2) are selected (among u, v, w and t), the input arguments in all the function handles of the script will be automatically changed. This would be of great help, as there are several function handles in the problem I'm trying to solve.
I know that this may be done by using matlabFunction() and changing "Vars" inside. However, I want to avoid the use of matlabFunction() since I am also using some logical conditions that are not supported by it. Is there any way to do that?
Thank you in advance for your help.
0 个评论
回答(2 个)
Hassaan
2024-1-2
you can design a higher-order function—a function that returns other functions—to achieve the flexibility you're looking for.
Let's say you have a base function and rot function like this
% Example usage
fixedVars.u = 1; % u is not fixed
fixedVars.v = 2; % v is not fixed
fixedVars.w = 0; % w is fixed to 0
fixedVars.t = 0; % t is fixed to 0
% Generate the function handle for analyzing u and v
fun = generateFunctionHandle(fixedVars, @rot);
% Now fun can be used as a function of u and v, with w and t fixed
result = fun(1, 2); % Example call with u=1, v=2
function result = baseFunction(u, v, w, t, rotFunc)
result = u + v.^2 - w + sin(t) + rotFunc(u, v, w);
end
function r = rot(u, v, w)
% Some operations involving u, v, and w
r = u*v*w;...; % Replace with actual computation
fprintf("rot: %f\n",r);
end
function fun = generateFunctionHandle(fixedVars, rotFunc)
% fixedVars is a struct with fields 'u', 'v', 'w', 't' indicating fixed values or NaN for variables to be used as inputs
fun = @(x, y) baseFunction(...
isnan(fixedVars.u) * x + ~isnan(fixedVars.u) * fixedVars.u, ...
isnan(fixedVars.v) * x + ~isnan(fixedVars.v) * fixedVars.v, ...
isnan(fixedVars.w) * x + ~isnan(fixedVars.w) * fixedVars.w, ...
isnan(fixedVars.t) * x + ~isnan(fixedVars.t) * fixedVars.t, ...
@(u, v, w) rotFunc(...
isnan(fixedVars.u) * y + ~isnan(fixedVars.u) * fixedVars.u, ...
isnan(fixedVars.v) * y + ~isnan(fixedVars.v) * fixedVars.v, ...
isnan(fixedVars.w) * y + ~isnan(fixedVars.w) * fixedVars.w));
end
Whenever you want to change which variables are inputs, you can call generateFunctionHandle again with a different fixedVars struct.
Please note that this approach assumes that rot can also be expressed in terms of two variables, which might not be the case based on your initial description. If rot needs to take three arguments, you'll need to adjust the higher-order function accordingly.
The use of isnan in the generateFunctionHandle function is a trick to select between the fixed value and the input value based on whether the fixed value is NaN or not.
This method is somewhat complex and may not be the most efficient. If you find that this approach becomes unwieldy or hard to maintain, it may be worth considering structuring your code differently or using classes to encapsulate the varying parameters.
------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
Steven Lord
2024-1-2
So you want to fix some of the input arguments while leaving others alone? Let's take a simple example function handle.
f = @(x, y, z) x.^2+sin(y)-exp(z);
If I wanted to make a new function handle, one that only accepted x and y and passed in a constant value of 1 for z, I could do that by defining a new function handle that calls the existing one.
g = @(x, y) f(x, y, 1);
format longg
[g(2, 3); f(2, 3, 1)]
Need a new function handle that accepts the inputs in a different order than f does?
h = @(z, x, y) f(x, y, z)
[h(1, 2, 3); f(2, 3, 1)]
3 个评论
Steven Lord
2024-1-3
f = @(x, y) x.^2-y.^3;
data = {1:5, 6:10, 11:15};
result12 = f(data{[1, 2]})
check12 = f(1:5, 6:10)
result23 = f(data{[2, 3]})
check23 = f(6:10, 11:15)
result31 = f(data{[3, 1]})
check31 = f(11:15, 1:5)
While I've hard-coded the indices into the data cell array for purposes of demonstration, you could generate those indices automatically. The check variables show that the comma-separated list calls match the explicitly listed input calls.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Whos 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!