A way to speed up my custom interpolation algorithm?

4 visualizzazioni (ultimi 30 giorni)
I'm writing a simulation program which often has to read out data from small data tables.
The x and y values are provided as 1xn arrays:
x = [0, 2, 5, 9, 14, 67];
y = [0, 3, 8, 2, 45, 324];
The interpolation scheme i need is equivalent to
interp1(x,y,4,'previous','extrap');
But as interp1 is very slow i wrote my own function. According to Matlab Profiler it is 5x faster but still takes up 80% of my code runtime.
function y = table_lookup(x,table_y,table_x)
% Check if lookup tables are of the same length
assert(length(table_y) == length(table_x))
% initialize y
y = NaN;
% Iterate over lookup table
i = 1;
while i <= length(table_x)
% If x value is exactly in the x_table assign corresponding y value
if table_x(i) == x
y = table_y(i);
break;
% If x value is grater than x value assign previous y value
elseif table_x(i) > x && i ~= 1
y = table_y(i-1);
break;
end
i = i + 1;
end
% If the iteration completed over the whole table assign the last y value
if i > length(table_x)
y = table_y(end);
end
end
Maybe someone has a suggestion for possible optimizations?
  2 Commenti
valnim
valnim il 8 Mag 2023
Thank you.
yq = y(find(x <= xq, 1, 'last'))
is about 10% faster than my function.

Accedi per commentare.

Risposta accettata

valnim
valnim il 9 Mag 2023
I found
yq = y(find(x <= xq, 1, 'last'))
proposed by @Jonas works best for my usecase.
  2 Commenti
Jon
Jon il 9 Mag 2023
If @Jonas method worked the best for you, then you should accept his answer, rather than putting what should be a comment on your thread as an answer, and then accepting that as an answer. Note you can unaccept an answer and then pick a new one if you want to correct this.
Also, how did my approach using just logical indices compare to the find used by @Jonas. i had the impression that find could be a little slower if not needed but would be interested to if that were actually the case.
Jon
Jon il 9 Mag 2023
Oh I see that @Jonas never posted an answer only a comment, so you couldn't accept his answer. Sorry

Accedi per commentare.

Più risposte (1)

Jon
Jon il 8 Mag 2023
You could try benchmarking this way too for comparison
xe = [x inf]
yq = y(xq >= xe(1:end-1) & xq <xe(2:end))
This returns empty if xq is less than the first element in x, not sure if you need to handle this edge case.
  3 Commenti
valnim
valnim il 16 Mag 2023
The solution by @Jonas was on average three times faster than your solution.
For 1e5 iterations on 1x5 array's @Jonas's solution took 0.15 s and @Jon's solution took 0.45 s.
Jon
Jon il 16 Mag 2023
That's interesting. Thanks for checking it out. I had thought that perhaps the "find" function would be relatively expensive compared to just using logical indexing. Good to know that "find" is so efficient!

Accedi per commentare.

Prodotti


Release

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by