interp2 for values in a matrix with NaN values

52 views (last 30 days)
Background:
I have a matrix with a pattern of:
u_mat =
NaN NaN 6.8447 6.9980 7.0233 NaN NaN
NaN 6.6319 6.6112 6.6561 6.7728 6.7561 NaN
6.2778 6.1201 NaN NaN NaN 6.4740 6.6144
5.8741 5.9870 NaN NaN NaN 6.2162 6.2128
5.7296 5.8258 NaN NaN NaN 6.0798 6.1561
NaN 5.7051 5.8433 5.9018 5.9896 6.0721 NaN
NaN NaN 5.8206 5.8835 6.0262 NaN NaN
(this is intentional since I want my calculation to disregard values that might have appeared in these NaN locations).
I also have x and y matrices (at the same size, without NaN values). for example:
x_mat =
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
y_mat =
800 800 800 800 800 800 800
832 832 832 832 832 832 832
864 864 864 864 864 864 864
896 896 896 896 896 896 896
928 928 928 928 928 928 928
960 960 960 960 960 960 960
992 992 992 992 992 992 992
The problem:
When I try to interpolate the value at an in-between location, the interpolated value sometimes comes out as NaNs. Do you have any idea why? I thought it is probably because of the NaNs in the original u_mat matrix, but then I don't know why will it give me a value at other times. maybe because it's 'linear' default method takes the nearest values, which are NaNs in many cases. But this is why I didn't use the 'nearest' method...
What can I do to solve this? I wish there was an 'omitnan' flag on the interp2() function...
>> u_interp = interp2(x_mat,y_mat,u_mat,[790,760],[820, 805])
u_interp =
6.7576 NaN
What I tryed in order to solve:
  1. I thought about "filling" the missing (NaN) values by interpolating them, and then interpolating the wanted locations by the "filled matrix", maybe as suggested by Stephen Cobeldick, here, but it seems costly in computing, and also I am not sure how physically/mathematically correct it would be.
  2. I tried to use the method suggested by Jan, here, and to "force" the interp2() to take only the non-NaN values. it did not work either, but maybe I miss-used it. If you think this is indeed the way, I would love if you could elaborate and explain it...
  1 Comment
Stephen23
Stephen23 on 9 Nov 2020
Note that Jan's solution does not apply to your case. In that question all of the input X, Y, and Z data were present (i.e. the data is gridded), only the sample points contained some NaN values.
In your case the input data contains NaN values (so you do not have gridded data).

Sign in to comment.

Answers (1)

Stephen23
Stephen23 on 9 Nov 2020
Edited: Stephen23 on 9 Nov 2020
Either way you need to extrapolate scattered data (your data are scattered because the NaN are missing data). This page explains one approach:
x_mat = [...
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896
704 736 768 800 832 864 896];
y_mat = [...
800 800 800 800 800 800 800
832 832 832 832 832 832 832
864 864 864 864 864 864 864
896 896 896 896 896 896 896
928 928 928 928 928 928 928
960 960 960 960 960 960 960
992 992 992 992 992 992 992];
u_mat = [...
NaN NaN 6.8447 6.9980 7.0233 NaN NaN
NaN 6.6319 6.6112 6.6561 6.7728 6.7561 NaN
6.2778 6.1201 NaN NaN NaN 6.4740 6.6144
5.8741 5.9870 NaN NaN NaN 6.2162 6.2128
5.7296 5.8258 NaN NaN NaN 6.0798 6.1561
NaN 5.7051 5.8433 5.9018 5.9896 6.0721 NaN
NaN NaN 5.8206 5.8835 6.0262 NaN NaN];
X = ~isnan(u_mat);
F = scatteredInterpolant(x_mat(X),y_mat(X),u_mat(X),'linear','linear');
F([790,760],[820,805])
ans = 1×2
6.7703 6.8094
"I am not sure how physically/mathematically correct it would be."
Interpolation generates slightly made-up data.
Extrapolation generates completely made-up data.
Extrapolating based on linear models is, just like every other data model, wrong:
Only the person doing that work with their expertise and their a priori knowledge of the underlying system behavior can decide if that particular wrong data model is useful or not.
You could also try inpaint_nans (or similar) to generate gridded data and then use interp2 (or similar) on that. But it would not be any more "correct".
  1 Comment
Maya Eyal
Maya Eyal on 9 Nov 2020
Edited: Maya Eyal on 9 Nov 2020
Thank you very much for your quick and detailed answer!
It is very helpful. not only did your solution solve it, but more importantly, I understand the approach behind it for next time.
I will have to do some homework regarding the statistical meaning of it to the error propagation.
Thanks!

Sign in to comment.

Categories

Find more on Interpolation in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!