I have tabulated data, containing fluid properties, that I want to use for interpolation. The grid itself is not regular on some points, so I want to use scatteredInterpolant
for interpolation.
Unfortunately, on some grid points I have two values that are then automatically removed or collapsed by scatteredInterpolant
. However I want to preserve those as the vertical rise is necessary to maintain. I investigated groupsummary
if this could help but I am not sure how to use it properly.
For me it would be acceptable if I could slightly distance the grid points and use an interpolated value for both grid points, one on the low side, the other on the high side and to have a steep rise instead of a vertical rise but I have no clue how to do it.
The thing is the points where this vertical rise exist are pretty scattered and I have several tables with this so manually it might by a bit hard to do.
Has anybody a good idea how to deal with this?
Example (simplified) of my data:
x y values state
1 2 10 liquid
2 2 11 liquid
3 2 10.5 liquid
3 2 200 gaseous
4 2 202 gaseous
5 2 203 gaseous
1 3 9 liquid
2 3 9.9 liquid
3.1 3 10.8 liquid
3.1 3 195 gaseous
4 3 199 gaseous
5 3 201.5 gaseous
1 4 8.9 liquid
2 4 9.5 liquid
3.3 4 10.2 liquid
3.3 4 185 gaseous
4 4 191 gaseous
5 4 199 gaseous
I have this data in a struct variable, put x
, y
, and v
in an array and tried to interpolate like this:
F = scatteredInterpolant(x,y,v);
For me it would be acceptable to modify the doubling where x
collapses as follows explained for point x1 = 3.1
and y1 = 2
:
I create a point x1.1
at let's say 3.0999
, y1.1 = y1 = 2
and interpolate v1.1
by using as values (2,2)
and (3.1,2)
.
This new point would replace the point (3.1,2,liquid)
.
Any other approach or solution would be fine, too!
Since your x
and y
are sorted in a sensible way, you should just be able to increment x
at all points where the previous x
value was the same, and the previous y
value was the same.
In a loop this would be something like
ofst = 0.0001; % amount to increase duplicate axis values by
for ii = 2:numel(x)
if (x(ii)<=x(ii-1)) && (y(ii)==y(ii-1))
x(ii) = x(ii) + ofst;
end
end
Without a loop it could be something like this, but be wary this wouldn't handle the edge-case where adding the offset could make one x
value larger than the next one. The loop did handle this edge case by using <=
and checking sequentially.
ofst = 0.0001;
bofst = [false; (diff(x)==0) & (diff(y)==0)];
x = x + bofst*ofst;