Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to evaluate a MATLAB anonymous function that takes an arbitrary number of variables n, given a n-dimensional vector?

I'm relatively new to MATLAB so perhaps there's something I'm missing. The task is the following: we must program a certain algorithm for optimizing a continuous function f: Rn ---> R. The thing is, to do so I need to minimize a scalar function that depends on f, and work with said minimum, for example:

%given f, and a vector y

g=@(s) f(y + s*e_i)   %e_i is the i-th canonical vector
[lambda, ~]=fminsearch(g,0)

disp(lambda)

The problem is that, if for example f(x,y)=x+y, one can't input f([1,2]), you need to write f(1,2), so I don't know how to define the function g properly so I can find the needed scalar value.

I know that if f were a fixed dimension, let's say 3, I could literally write

eval_f = @(v) f(v(1), v(2), v(3))

g = @(s) eval_f(y + s*e_i)

but the code must be open to receive any function. I have also tried using f(num2cell(y + s*e_i){:}) but I get an "Invalid array indexing" error, as I can't chain the parenthesis and an output. I have tried creating a more complex auxiliary function

eval_f=@(fun,v) fun(feval(@(x) x{:},num2cell(v)));
g=@(s) eval_f(f,y + s*ei);

But doing feval(@(x) x{:},v) in the end only returns the first element of v, and f doesn't get evaluated correctly and thus g isn't correctly defined.

How could I define g?

like image 926
Pucho Avatar asked Oct 15 '25 16:10

Pucho


1 Answers

Note that you need a function handle to minimise, but that doesn't mean you have to define everything in anonymous functions. It might be easier to test and debug if you just write a complete function block, so you have your main function g which evaluates some variable-sized v using a predefined f:

function x = g( f, v )
% v is an array of unknown size, the values of which should be 
% passed as separate inputs to f
    % Convert to cell so we can use {:} syntax in function call
    vc = num2cell( v );
    % Evaluate
    x = f( v{:} );
end

Then all your anonymous function needs to do is wrap this up so that it accepts a single input

gf = @(s) g( f, y + s*e_i )
[lambda,~] = fminsearch( gf, 0 )

Alternatively if you'd written the definition of f directly within the function block for g then you wouldn't need to define gf at all, you could point directly at g if it took a single input.


If you have these in the same script, you would normally put the function block at the bottom (although since R2024b they can go anywhere)

like image 138
Wolfie Avatar answered Oct 18 '25 07:10

Wolfie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!