Josh
Josh

Reputation: 13

Dynamically generate function for use in function handle

I'd like to dynamically construct a function that can then be referred to with a function handle for later use in Matlab functions such as integral(fun,a,b).

As an example imagine a function with terms:

(x-A)/(D-A) * (x-B)/(D-B) * (x-C)/(D-C)

where x is a variable and A,B,C,D are constants from a vector (call it K=[A,B,C,D]' as an example) generated by a different function.

I could do:

fun = @(x) (x-A)/(D-A) * (x-B)/(D-B) * (x-C)/(D-C)

However, this restricts me to three terms. I'd like to be able to take an arbitrary length vector of constants and generate a function of similar form to the one above. Normally this is easy in Matlab, but it seems like function handles expect 'x' to be a scalar, so something like:

prod( (x - K(1:3)) ./ K(4)-K(1:3) )

returns an error.

Upvotes: 1

Views: 351

Answers (1)

Luis Mendo
Luis Mendo

Reputation: 112759

It's not true that

function handles expect 'x' to be a scalar

The problem is not the function handle, nor the fact that the function is anoymous. The problem is simply the operation you use to define that function: you can't do

prod( (x - K(1:3)) ./ K(4)-K(1:3) )

when both x and K are vectors with arbitrary sizes. As a side note, you have a pair of brackets missing in the denominator.

What you want (if I understand correctly) can be done using bsxfun twice. Assuming both x and K are column vectors, use

prod(bsxfun(@rdivide, bsxfun(@minus, x.', K(1:end-1)), K(end)-K(1:end-1)))

to compute your function.

So: first define K and then you can define the anonymous function and its handle as

fun = @(x) prod(bsxfun(@rdivide,bsxfun(@minus,x.',K(1:end-1)),K(end)-K(1:end-1)))

Note that the value of K is "hardwired" into the anonymous function when you define the latter. The function won't change if you later modify K (unless of course you define the function again with the new K).

Example:

>> K = [3 4 5 6].';
>> fun = @(x)prod(bsxfun(@rdivide,bsxfun(@minus,x.',K(1:end-1)),K(end)-K(1:end-1)));
>> x = [1 2].';
>> fun(x)
ans =
    -4    -1

Check:

>> prod( (x(1) - K(1:3)) ./ (K(4)-K(1:3)) )
ans =
    -4

>> prod( (x(2) - K(1:3)) ./ (K(4)-K(1:3)) )
ans =
    -1

Upvotes: 1

Related Questions