Using interp1 multiple times to find a root : interp1 on a matrix without loops. Using interp1 multiple times for different values of query points without loops.
4 次查看(过去 30 天)
显示 更早的评论
Dear All, I have the following problem:
I have a vector of arguments x and a vector of values v (both are monotonic; the root may not necessarily exist). I would like to find a root of function v(x). I could flip the axes and use interp1 in point 0:
root = interp1(-v,x,0);
The problem is that I have to do it many times, i.e. for many values of parameters affecting the vector v, which is actually a vector v(alpha,beta,gamma). Obviosuly I could use nested loops:
for alpha = 1:a
for beta = 1:b
for gamma = 1:c
root(alpha,beta,gamma) = interp1(-v(alpha,beta,gamma),x,0);
end
end
end
Unfortunately, this solution is very slow (a,b and c are large numbers). As far as I know interp1 does not allow to use a matrix as its first input so I do not know how to vectorize it.
How to solve this problem in a fast way? Either by speeding up the solution using vectors getting rid of loops or by using any other method than interp1. Interp1 has quite a large fixed cost of being called so it is very slow in the loop environment while it speeds up when vectorized (but as I know only the second argument (i.e. values ) can be used as a mtrix )
The other problem is:
Is it possible to use interp1 for multiple values of query points without using loops? something like this:
root = interp1(x,v(:,alpha,beta,gamma),x0(alpha,beta,gamma));
where x is a vector, v(:,alpha,beta,gamma) is a multidimensional matrix (array) and x0(alpha,beta,gamma) is a point. The given syntax is doing a 1 dimensional interpolation over the first dimension of v for every combination of alpha,beta and gamma for a given point x0, which varies for all combinations of parameters.
I would be grateful for any hints!
2 个评论
Image Analyst
2016-11-26
How large are a, b, and c? And why do you need to make up this huge 3D matrix? Give us some background/context.
回答(1 个)
Daniel kiracofe
2016-11-27
My first question here would be, are you pre-allocating root? i.e. do you have root = zeros(a,b,c) before your loop? If not, then probably what is taking up the time is memory allocation, not the actual interpolation.
If memory is not your problem, then you should be able to get some speedup by using a modified version of interp1(). i.e. interp1() is a pretty general function. it works for either increasing or decreasing vectors, it checks to make sure you don't have duplicated points, it allows multiple interpolation method, etc. If you know for sure that you only have, say, increasing vectors and never have duplicated points, you could take advantage of that knowledge to write a quicker routine. Or take advantage of such routines already written:
https://www.mathworks.com/matlabcentral/fileexchange/43325-quicker-1d-linear-interpolation--interp1qr
4 个评论
Daniel kiracofe
2016-11-29
Hmmm. There are some suspicious lines here. Look at this one
ap1(:,:,:,:,:) = interp1(-squeeze(F1(:,t,aux1,aux2,aux3,aux4,aux5)),a,0,'spline');
Are you sure you didn't mean to do something like this instead?
ap1(aux1,aux2,aux3,aux4,aux5) = interp1(-squeeze(F1(:,t,aux1,aux2,aux3,aux4,aux5)),a,0,'spline');
As written, this implies that you are overwriting the previous value of ap1 every time through the loop. i.e. you calculate a value, through it away, repeat. You would only keep the last one. If this is really what you are doing, then pre-allocation of ap1 shouldn't matter, because it's not changing size during each execution of the loop. I suspect you are trying to post a simplified version of the code, and just made a cut and paste error. If it is your real code, then you can save a ton of time by eliminating all 5 loops and just doing
ap1(:,:,:,:,:) = interp1(-squeeze(F1(:,t,na,nh,nx,nA,nS)),a,0,'spline')
On the other hand, preallocation of variables like F1, F2, eta2, should save time, as those are growing in the loop.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!