简体   繁体   中英

Create a variable number of terms in an anonymous function that outputs a vector

I'd like to create an anonymous function that does something like this:

n = 5;
x = linspace(-4,4,1000);

f = @(x,a,b,n) a(1)*exp(b(1)^2*x.^2) + a(2)*exp(b(2)^2*x.^2) + ... a(n)*exp(b(n)^2*x.^2);

I can do this as such, without passing explicit parameter n :

f1  = @(x,a,b) a(1)*exp(-b(1)^2*x.^2);
for j = 2:n 
    f1  = @(x,a,b) f1(x,a,b) + a(j)*exp(b(j)^2*x.^2);
end

but it seems, well, kind of hacky. Does someone have a better solution for this? I'd like to know how someone else would treat this.

Your hacky solution is definitely not the best, as recursive function calls in MATLAB are not very efficient, and you can quickly run into the maximum recursion depth (500 by default).

You can introduce a new dimension along which you can sum up your arrays a and b . Assuming that x , a and b are row vectors:

f = @(x,a,b,n) a(1:n)*exp((b(1:n).^2).'*x.^2)

This will use the first dimension as summing dimension: (b(1:n).^2).' is a column vector, which produces a matrix when multiplied by x (this is a dyadic product, to be precise). The resulting n * length(x) matrix can be multiplied by a(1:n) , since the latter is a matrix of size [1,n] . This vector-matrix product will also perform the summation for us.

Mini-proof:

n = 5;
x = linspace(-4,4,1000);
a = rand(1,10);
b = rand(1,10);

y = 0;
for k=1:n
   y = y + a(k)*exp(b(k)^2*x.^2);
end

y2 = a(1:n)*exp((b(1:n).^2).'*x.^2);   %'

all(abs(y-y2))<1e-10

The last command returns 1 , so the two are essentially identical.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM