Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
interpolating part of an array.

Subject: interpolating part of an array.

From: Bruce Bowler

Date: 30 Aug, 2013 19:59:05

Message: 1 of 6

It's been a long week (and this is probably a "d'oh accompanied by the
sound of ones palm slapping ones forehead" question)...

I have 2 vectors, let's call them 'time' and 'temperature'. The time
vector is always "correct". The temperature detector occasionally returns
a bad value - rarely, but occasionally, multiple times in a row. In
either case it's reasonable and acceptable to do a simple linear
interpolation to fill in the missing values.

It's relatively easy to do it in a loop, but that seems 'dirty'. I
haven't been able to wrap by brain around a more matlab-like strategy.

I could do something like this

ix = find(temperature == -99);
for iy = 1:numel(ix)
  iz = ix(iy);
  temperature(iz) = interp1([time(iz-1) time(iz+1)], ...
    [temperature(iz-1) temperature(iz+1)],...
    time(iz));
end

but that still seems too 'weird' to me and doesn't handle the case of
multiple bad readings in a row (or first and last element failures either,
but those 2 cases should probably remain 'bad').

Anyone have a better way?

TIA,
Bruce

Subject: interpolating part of an array.

From: dpb

Date: 30 Aug, 2013 20:32:54

Message: 2 of 6

On 8/30/2013 2:59 PM, Bruce Bowler wrote:
> It's been a long week (and this is probably a "d'oh accompanied by the
> sound of ones palm slapping ones forehead" question)...
>
> I have 2 vectors, let's call them 'time' and 'temperature'. The time
> vector is always "correct". The temperature detector occasionally returns
> a bad value - rarely, but occasionally, multiple times in a row. In
> either case it's reasonable and acceptable to do a simple linear
> interpolation to fill in the missing values.
>
> It's relatively easy to do it in a loop, but that seems 'dirty'. I
> haven't been able to wrap by brain around a more matlab-like strategy.
>
> I could do something like this
>
> ix = find(temperature == -99);
> for iy = 1:numel(ix)
> iz = ix(iy);
> temperature(iz) = interp1([time(iz-1) time(iz+1)], ...
> [temperature(iz-1) temperature(iz+1)],...
> time(iz));
> end
...

> Anyone have a better way?
...

Close... :) Since find() returns ordered from start to end, just use
those points and pick up the subvector length from it--

i1=ix(1)-1; i2=ix(end)+1; % the points bounding the missing ones
t(ix)=interp1(time(i1:i2),temp(i1:i2),time(ix)); % fill in the misses

Just put the error checking to catch the endpoints if bad for the i1:i2
values as you say...

--

Subject: interpolating part of an array.

From: John D'Errico

Date: 31 Aug, 2013 00:02:18

Message: 3 of 6

Bruce Bowler <bbowler@bigelow.org> wrote in message <b8cbs9Fkt0sU1@mid.individual.net>...
> It's been a long week (and this is probably a "d'oh accompanied by the
> sound of ones palm slapping ones forehead" question)...
>
> I have 2 vectors, let's call them 'time' and 'temperature'. The time
> vector is always "correct". The temperature detector occasionally returns
> a bad value - rarely, but occasionally, multiple times in a row. In
> either case it's reasonable and acceptable to do a simple linear
> interpolation to fill in the missing values.
>
> It's relatively easy to do it in a loop, but that seems 'dirty'. I
> haven't been able to wrap by brain around a more matlab-like strategy.
>
> I could do something like this
>
> ix = find(temperature == -99);
> for iy = 1:numel(ix)
> iz = ix(iy);
> temperature(iz) = interp1([time(iz-1) time(iz+1)], ...
> [temperature(iz-1) temperature(iz+1)],...
> time(iz));
> end
>
> but that still seems too 'weird' to me and doesn't handle the case of
> multiple bad readings in a row (or first and last element failures either,
> but those 2 cases should probably remain 'bad').
>
> Anyone have a better way?

The obvious seems to be to replace the bad readings with
NaN. That takes one line.

  temperature(temperature == -99) = nan;

Then call inpaint_nans to do the interpolation in one
step. No muss, no fuss. Find inpaint_nans on the file
exchange.

John

Subject: interpolating part of an array.

From: TideMan

Date: 31 Aug, 2013 06:08:05

Message: 4 of 6

On Saturday, August 31, 2013 7:59:05 AM UTC+12, Bruce Bowler wrote:
> It's been a long week (and this is probably a "d'oh accompanied by the
>
> sound of ones palm slapping ones forehead" question)...
>
>
>
> I have 2 vectors, let's call them 'time' and 'temperature'. The time
>
> vector is always "correct". The temperature detector occasionally returns
>
> a bad value - rarely, but occasionally, multiple times in a row. In
>
> either case it's reasonable and acceptable to do a simple linear
>
> interpolation to fill in the missing values.
>
>
>
> It's relatively easy to do it in a loop, but that seems 'dirty'. I
>
> haven't been able to wrap by brain around a more matlab-like strategy.
>
>
>
> I could do something like this
>
>
>
> ix = find(temperature == -99);
>
> for iy = 1:numel(ix)
>
> iz = ix(iy);
>
> temperature(iz) = interp1([time(iz-1) time(iz+1)], ...
>
> [temperature(iz-1) temperature(iz+1)],...
>
> time(iz));
>
> end
>
>
>
> but that still seems too 'weird' to me and doesn't handle the case of
>
> multiple bad readings in a row (or first and last element failures either,
>
> but those 2 cases should probably remain 'bad').
>
>
>
> Anyone have a better way?
>
>
>
> TIA,
>
> Bruce

Replace -99 with NaN:
temperature(temperature<=-99)=NaN;
then use this elegant routine from Pawlowicz's t_tide package:

function y=fixgaps(x);
% FIXGAPS Linearly interpolates gaps in a time series
% YOUT=FIXGAPS(YIN) linearly interpolates over NaN
% in the input time series (may be complex), but ignores
% trailing and leading NaN.
%

% R. Pawlowicz 6/Nov/99

y=x;

bd=isnan(x);
gd=find(~bd);

bd([1:(min(gd)-1) (max(gd)+1):end])=0;


y(bd)=interp1(gd,x(gd),find(bd));

Subject: interpolating part of an array.

From: Steven_Lord

Date: 3 Sep, 2013 15:51:15

Message: 5 of 6



"Bruce Bowler" <bbowler@bigelow.org> wrote in message
news:b8cbs9Fkt0sU1@mid.individual.net...
> It's been a long week (and this is probably a "d'oh accompanied by the
> sound of ones palm slapping ones forehead" question)...
>
> I have 2 vectors, let's call them 'time' and 'temperature'. The time
> vector is always "correct". The temperature detector occasionally returns
> a bad value - rarely, but occasionally, multiple times in a row. In
> either case it's reasonable and acceptable to do a simple linear
> interpolation to fill in the missing values.
>
> It's relatively easy to do it in a loop, but that seems 'dirty'. I
> haven't been able to wrap by brain around a more matlab-like strategy.
>
> I could do something like this
>
> ix = find(temperature == -99);
> for iy = 1:numel(ix)
> iz = ix(iy);
> temperature(iz) = interp1([time(iz-1) time(iz+1)], ...
> [temperature(iz-1) temperature(iz+1)],...
> time(iz));
> end
>
> but that still seems too 'weird' to me and doesn't handle the case of
> multiple bad readings in a row (or first and last element failures either,
> but those 2 cases should probably remain 'bad').
>
> Anyone have a better way?

% Generate sample data with invalid times. Note that if your invalid value
is NaN, define validTempLoc differently!
invalid = -99;
time = 1:10;
temp = time.^2;
temp([3 4 8]) = invalid;

% Locate the valid times
validTempLoc = temp ~= invalid;
% if invalid is NaN
% validTempLoc = ~isnan(temp);

% Retrieve just the "good" times and temperatures, and identify the times
corresponding to invalid temps
validTime = time(validTempLoc);
validTemp = temp(validTempLoc);
invalidTime = time(~validTempLoc);

% Interpolate
v = interp1(validTime, validTemp, invalidTime, 'cubic')

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: interpolating part of an array.

From: Bruce Bowler

Date: 3 Sep, 2013 18:05:33

Message: 6 of 6

On Sat, 31 Aug 2013 00:02:18 +0000, John D'Errico wrote:

> The obvious seems to be to replace the bad readings with NaN. That takes
> one line.
>
> temperature(temperature == -99) = nan;
>
> Then call inpaint_nans to do the interpolation in one step. No muss, no
> fuss. Find inpaint_nans on the file exchange.
>
> John

Works like a champ. Thanks!

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us