Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 726
anon01 Avatar asked Feb 04 '26 21:02

anon01


1 Answers

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.

like image 177


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!