Finding smaller and larger values than user's input for 2D interpolation

Hi,
I have the following 3 matrices:
r_sp [1000x360]
theta_sp [1000x360]
Dose_alpha_total [1000x360]
Given a specific r and theta, the 3rd matrix (Dose_alpha_total) should output the matching dose.
Say there's this user's input: (r_in, theta_in)=(0.25, 90), which doesnt exist in r_sp & theta_sp (however, there are many other values which are really close to this given input).
The user must receive the dose at the inesrted point exactly - Dose_alpha_total(0.25,90).
In order to solve this, I was thinking of the following:
  • Find the closest points to the user's input, then find the corresponding dose (for instance, dose1 and dose2, matching to r=0.2493 & theta=89.92 and r=0.2494 & theta=89.93 respectively (which exist in my matrices))
  • Interpolate dose1 and dose2 to the exact same value the user asked for
So, for the first bullet, I wrote:
r_diff=abs((r_sp- r_in)./r_sp);
theta_diff=abs((theta_sp -theta_in)./theta_sp);
add=r_diff+theta_diff;
[M,I] = min(add(:));
[I_row1, I_col1] = ind2sub(size(add),I);
dose1=Dose_alpha_total(I_row1,I_col1);
theta_sp(I_row1,I_col1)=999; % "ruin" the index of the smallest value found with a different, very large value, in order to be able to find the 2nd smallest
r_sp(I_row1,I_col1)=999; % like above
r_diff=abs((r_sp- r_in)./r_sp);
theta_diff=abs((theta_sp -theta_in)./theta_sp);
add=r_diff+theta_diff;
[M,I] = min(add(:));
[I_row2, I_col2] = ind2sub(size(add),I);
dose2=Dose_alpha_total(I_row2,I_col2);
However, in order to be able to interpolate, I must have one point which is smaller than of the user's input and a second point which is larger.
The above code doesnt neccesairly meet this criteria. On the contrary - both the r's & theta's I got, were smaller than the user's input, hence not allowing me to perform the inerpolation.
Any clues of how to proceed?
In addition, as I'm quite new to matlab, I'm so not sure I fully understood how to use the built-in interpolation functions available. So when I'm past the first issue, how can I perform the interpolation? should I use interp2 function with these parameters:?
interp2(X,Y,V,Xq,Yq)
where: X = [I_row1, I_col1] ---> it should be a single value though, not a 1x2 array... right?
Y = [I_row2, I_col2] ---> likewise?
V=[Dose_alpha_total(I_row1, I_col1), Dose_alpha_total(I_row2, I_col2)]
Xq = ?
Yq =?
Thanks a lot :)

2 Comments

You might get more answers if you attached your data so we had something to work with and give you once we've solved it. In the meantime, see my demo for scatteredInterpolant().
Attached.
BTW, for some reason, my code doesnt seem to work for the extreme cases, where, for instance, the user's input is theta_in = 0.

Sign in to comment.

Answers (2)

Is your data gridded or scattered? If it's gridded, scroll down to the "Interpolation with the interp Family of Functions" section on the page discussing interpolating gridded data linked from that "gridded or scattered" page.
Have a look at the help and documentation for the functions interp2 and scatteredInterpolant. Either of those two functions will help you get this task solved. The first is preferable for the case where your independent variables r_sp and theta_sp are on a regular, plaid grid. Then everything is simple. If those variables are scattered then you will have to resort to scatteredInterpolant, that function handles that case.
HTH

8 Comments

The data is scattered.
However, I'm not sure I'm already at the 2nd bullet of my solving-plan, as I couldn't locate 2 nearest points.
Unless, scatteredInterpolant also takes care of this task (finding the 2 closest values to the user's input, one bigger than it and one smaller than it).
Also, the scatteredInterpolant seems to get only functions? whereas in my case the functions were pre-calcualted, and I need to interpolate over given matrices. Not sure how to do the right adjustments for my case.
If you read the help and documentation for scatteredInterpolant you will see how to use the function. This is how I would do this:
f_DOSE = scatteredInterpolant(r_sp(:),theta_sp(:),Dose_alpha_total(:));
r_in = 0.25;
theta_in = 90;
DOSE_in = f_DOSE(r_in,theta_in);
First a scatteredInterpolant-function-object is created. The (:) is to convert the 2-D arrays to 1-D column-arrays which is what scatteredInterpolant expects.
Then we calculate the dose at the point you need.
HTH
I did read the documentation.
I guess you mean:
f_DOSE = scatteredInterpolant(r_sp(:),theta_sp(:),Dose_alpha_total(:));
I tried that as well before posting my comment, but it doesn't give off the right value; instead of 21.9310 it gives 21.7826. Plus, it doesn't work for extreme cases, for example, for theta_in = 0, it gives a minus value...
Yes, I did.
Before you continue with this type of analysis you first have to look at your data. This is imperative. So before doing anything else do this:
scatter(r_sp(:),theta_sp(:),23,Dose_alpha_total(:),'filled')
This should give you some sense of where you have what data. You can onle expect reasonable interpolation-results inside the convex hull of your data-points. Outside that region you do extrapolation and that's always a dangerous operation.
Then you should try this too:
tri = delaunay(r_sp(:),theta_sp(:));
trisurf(tri,r_sp(:),theta_sp(:),23,Dose_alpha_total(:))
That will give you some sense of how well you can expect the interpolation to work.
If you have some peculiar scaling of you Dose_alpha_total, you might get better results doing the interpolation on the logarithm of the dose:
logf_DOSE = scatteredInterpolant(r_sp(:),theta_sp(:),log(Dose_alpha_total(:)));
r_in = 0.25;
theta_in = 90;
DOSE_in = exp(logf_DOSE(r_in,theta_in));
Thanks for the tips.
My data looks quite weird, when I run the scatter plot:
Not sure what is that (1000,1000) point.
Also, the trisurf doesn't work, I get this error:
Error using horzcat
Dimensions of arrays being concatenated are not consistent.
Error in trisurf (line 91)
h = patch('faces',trids,'vertices',[x(:) y(:) z(:)],'facevertexcdata',c(:),...
Which is weird, as all of the arrays there seem to have the same dimension.
Look at your data.
Plot your r_sp and theta_sp:
subplot(2,1,1)
plot(theta_sp,'.-')
subplot(2,1,2)
plot(r_sp,'.-')
Does it look as if you have one single outlier? Does it look like you have multiple outliers? You have to know these things.
Stupid me.
Of course it has this outlier, as I artifically put the values of 999 in order to find the 2nd most minimal value (see the code on my main question). This was before I knew that scatteredInterpolant deals with this issue in the background.
So I've deleted those funky lines, and now the scatter plot looks like so:
But the lines:
f_DOSE = scatteredInterpolant(r_sp(:),theta_sp(:),Dose_alpha_total(:),'linear');
DOSE_in = f_DOSE(r_in,theta_in);
Still dont give off good results, let alone for the extreme cases.. (and trisurf still gives the same error as before)
Put a colour-bar on that scatter-plot, then plot the points you want to interpolate to:
colorbar
hold on
plot(r_i,theta_i,'r*')
If your interpolation-points are inside the "naturally coloured area then you should be able to do a natural sanity-check of the value you get for DOSE_in. In order to extend that value into the blue region you can always modify the limits of the colour-scale:
caxis([0 12]) % or whatever are a suitable lower and upper boundaries.

Sign in to comment.

Categories

Find more on Interpolation in Help Center and File Exchange

Asked:

on 24 Jan 2021

Commented:

on 25 Jan 2021

Community Treasure Hunt

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

Start Hunting!