Extracting near constant elements from an array

15 views (last 30 days)
I have a vector 'data(1).IAS' , which looks like as follows.
data(1).IAS
ans =
288
294
296
294
.
. % length(data(1).IAS) = 153.
I am trying to extract the near constant elements from a vector as shown in the figure (The figure is IAS plotted against its index number).
The problem is that my data.IAS has 693 arrays and it is not possible to do it one by one. Does anyone have any idea how to extract the only near constant parts?
Thanks.
UPDATE: Code
data = load('SSR_20140103.mat'); % Variable name is 'data' with various fields.
newData = data.data;
for i = 1: length(data.data)
x = data.data(i).IAS;
h = [1 1 1 1 1 1 1 1 1 1];
if(length(x)>1)
x1 = [ones(length(h),1)*x(1);x];
x2 = filter(h,1,x1)/length(h);
x2 = x2(length(h):length(x2)-1);
diffx2 = diff(x2);
diffx2 = [ones(length(h),1)*diffx2(1);diffx2];
meandiffx2 = filter(h,1,diffx2)/length(h);
meandiffx2 = abs(meandiffx2(length(h):length(meandiffx2)));
constantIndex = find(meandiffx2<0.25);
constantData.index = constantIndex;
constantData.data = x(constantIndex);
constantValues(i) = {constantData};
newData(i).time = data.data(i).time(constantIndex);
newData(i).lat = data.data(i).lat(constantIndex);
newData(i).lng = data.data(i).lng(constantIndex);
newData(i).altitude = data.data(i).altitude(constantIndex);
newData(i).selected_altitude = data.data(i).selected_altitude(constantIndex);
newData(i).BPS = data.data(i).BPS(constantIndex);
newData(i).RA = data.data(i).RA(constantIndex);
newData(i).TTA = data.data(i).TTA(constantIndex);
newData(i).GS = data.data(i).GS(constantIndex);
newData(i).TAR = data.data(i).TAR(constantIndex);
newData(i).TAS = data.data(i).TAS(constantIndex);
newData(i).heading = data.data(i).heading(constantIndex);
newData(i).IAS = data.data(i).IAS(constantIndex);
newData(i).Mach = data.data(i).Mach(constantIndex);
newData(i).BAR = data.data(i).BAR(constantIndex);
newData(i).IVV = data.data(i).IVV(constantIndex);
end
end

Accepted Answer

Star Strider
Star Strider on 10 Jul 2015
Your airplane appears to be a jet flying a STAR. When it enters Class C airspace, it is told to slow to 250 kts, then is cleared for the approach and flies the approach at 130 kts.
I didn’t run the code, however it seems to be two 10-element moving average filters to create first ‘x2’ and then ‘meandiffx2’. It then thresholds ‘meandiffx2’ and returns the indices of those values that are <0.25 to ‘constantIndex’. (If it doesn’t find any, the find function will return an empty value. This usually throws an error when concatenated with an existing vector, and will obviously not function as an index in the next line, so I don’t know how the code handles this when it does the ‘constantData.index’ and constantData.data assignments.) It then stores the associated values in the designated structures.
This is a powerful argument for documenting code with comments.
  4 Comments
bio lim
bio lim on 10 Jul 2015
Yeah, I was guessing it was a moving average filter but now thanks to you at least I am certain it is indeed moving average filter. If the rest is mystifying to an expert, then it makes sense that I don't understand it, haha. Anyway, thanks!
Star Strider
Star Strider on 10 Jul 2015
My pleasure!
I’m knowledgeable and experienced in certain aspects of MATLAB but I’d not consider myself an ‘expert’, except in certain very restrictive applications (medicine, biomedical engineering, aviation).

Sign in to comment.

More Answers (2)

Thorsten
Thorsten on 10 Jul 2015
Edited: Thorsten on 10 Jul 2015
First who have to define an formal criterion of what you consider "near constant". For example, more than 20 points that vary my less than 15 units. Than you loop through your data:
pseudo code:
i_start = 1, i_end = i_end + 20
if the range of values(i_start:i_end) < 15?
then increment i_end
until the range is > 15:
1. you've found a constant area from i_start:i_end
2. continue checking with i_start = i_end+1
else
continue checking with i_start = i_start + 1
If you post your data and define your criteria, we could provide further help.
  1 Comment
bio lim
bio lim on 10 Jul 2015
Edited: bio lim on 10 Jul 2015
Hi. I actually already have a solution, however I do not understand the algorithm or the method used behind this. If you could explain me the following code, that would be great! (I will take it as the answer of the question.) I will post the code in the original question. I have also attached my .mat file.

Sign in to comment.


Image Analyst
Image Analyst on 10 Jul 2015
You can use stdfilt() in the Image Processing Toolbox. It will work on a 1-D signal. Basically it scans the array computing the standard deviation in a moving window. If the values don't vary much in the window, then the stdev will be low and if they change a lot the stdev will be high.
Alternatively you can scan the signal and call polyfit() from each point onwards. Fit a line and if the slope is reasonably low, like 0 to 0.2 or whatever, then the portion is fairly flat. If the slope is higher, then trending up or down.

Products

Community Treasure Hunt

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

Start Hunting!