Eliminate terrible for loop, code optimisation, data attached

2 次查看(过去 30 天)
The problem:
I have 3 (very large) grids of data.... x y z, where x and y are variables that determine 'performance' z.
There are multiple sets of x y z..... so, x1 y1 z1, x2 y2 z2, x3 y3 z3....
y values are set by the user.... The x value combinations are calculated from other code. They are all possible combinations that can make a user-specified total (xtotal)
My goal is to find z values for known x and y... and repeat for different sets of x values. Added a picture to illustrate what I'm aiming to do - get the values from the red elements:
I have managed to create a for loop that achieves this - however it is SLOW. I am sure there is a more efficient way to do this using grids but have struggled.
Working code and data is attached, the time-consuming (10+ seconds!) loop in there is:
Outputs=zeros(size(xvals),length(xvals))
for i=1:size(indz)
x1loc=find(x1(1,:)==xvals(i,1))
Outputs(i,1)=z1(y1loc,x1loc)
x2loc=find(x2(1,:)==xvals(i,2))
Outputs(i,2)=z2(y2loc,x2loc)
x3loc=find(x3(1,:)==xvals(i,3))
Outputs(i,3)=z3(y3loc,x3loc)
end
Fairly sure there will be some way to optimise this using grids, or some other matlab trick I'm less familiar with... Stuck!

回答(2 个)

Matt J
Matt J 2014-12-10
编辑:Matt J 2014-12-10
No need to loop at all (nor to use the FIND command). Just do
x1loc = ( x1(1,:)==xvals(:,1).' );
Outputs(:,1)=z1(y1loc,x1loc);
and similarly with x2loc and x3loc.
  1 个评论
Mat
Mat 2014-12-10
I was about to say wow, this must surely be the most extreme example of overcomplicating things! However this doesn't work...
>> x1loc = ( x1(1,:)==xvals(:,1).' );
??? Error using ==> eq
Matrix dimensions must agree.
x1 is vector of 25 different values. xvals often has around 150 values, many repeat values because, for example, if x1=100 and xtotal=200, then x2 and x2 can equal 20-80, 30-70, 40-60.... etc.
x1 and xvals are not likely to have matching dimensions. Don't think it can work this way...?

请先登录,再进行评论。


Matt J
Matt J 2014-12-10
编辑:Matt J 2014-12-10
How about
F1=griddedInterpolant(x1,y1,z1,'nearest');
Output(:,1)=F1({xvals,y1loc});
It might also be worth conserving memory by making x1,y1 into grid vectors instead of a Full Grid, as explained in the documentation for griddedInterpolant .
  2 个评论
Mat
Mat 2014-12-10
I had a quick try and this doesn't work either (Undefined function or method 'griddedInterpolant' for input arguments of type 'double'.)
Haven't fiddled around with it because I'd like to avoid functions not supported by matlab coder (e.g griddedInterpolant).
In the script, I modify the inputs so that they fit the nearest value that already exist on the existing grid, so not sure how interpolation would help here.
Matt J
Matt J 2014-12-10
编辑:Matt J 2014-12-10
I had a quick try and this doesn't work either (Undefined function or method 'griddedInterpolant' for input arguments of type 'double'.)
You seem to have a pretty old version of MATLAB. You could use interp2 instead. It is supported by the Matlab Coder.
In the script, I modify the inputs so that they fit the nearest value that already exist on the existing grid, so not sure how interpolation would help here.
That's the same as nearest-neighbor interpolation.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Whos 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by