MATLAB and averaging without NaN

  • Context: MATLAB 
  • Thread starter Thread starter member 428835
  • Start date Start date
  • Tags Tags
    Matlab
Click For Summary

Discussion Overview

The discussion revolves around implementing a MATLAB algorithm to identify and handle outliers in a numerical vector by calculating the magnitude of derivatives and setting certain elements to NaN based on specified criteria. The focus is on coding techniques and logic for processing data, with an emphasis on smoothing outliers and ensuring the algorithm functions correctly.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Homework-related

Main Points Raised

  • One participant describes a method for calculating the derivative of elements in a vector and setting elements to NaN if the derivative exceeds a threshold.
  • Another participant suggests using print statements to debug the code and verify its functionality at each iteration.
  • A third participant provides a modified solution that includes a critical slope filter and a method for rewriting NaN values as the previous non-NaN value.
  • Some participants express curiosity about how others figured out their coding issues, indicating a collaborative troubleshooting approach.
  • One participant notes that their solution emerged from extensive thinking and experimentation, rather than finding a direct reference online.

Areas of Agreement / Disagreement

Participants share various approaches to the problem, with no consensus on a single solution. There are multiple proposed methods for handling NaN values and calculating derivatives, indicating differing perspectives on the best approach.

Contextual Notes

Some limitations include the assumption that the first data point is not an outlier and the potential dependency on the definition of the critical slope. The discussion does not resolve all mathematical steps or conditions for the algorithm's implementation.

member 428835
Hi PF!

Let's say we have a vector ##x = [1, \,2,\, 3, \,20,\, 4,\, 5,\, 30,\, 6]##. I am trying to loop through and find the magnitude of the derivative of each ##i^{th}## element with unitary spacing, and if that derivative is sufficiently high, I make that element NaN and continue.

Example: Let's call the derivative of the ##i^{th}## element ##d_i\equiv|d_{i-1}-d_{i+1}|/2##. Then ##d_2 = |3-1|/2=1##. Similarly, ##d_3=|20-2|/2=9##. However, if ##d_i## is greater than, say ##5##, I want to make ##x_{i+1}=NaN## and recalculate the derivative using now ##x_{i-1}## and the next non-NaN number. So, as a first loop through ##d_3=|20-2|/2=9## which is above 5, so ##x_4=NaN## and thus ##x = [1, \,2,\, 3, \,NaN,\, 4,\, 5,\, 30,\, 6]##. Then recalculating ##d_3=|4-2|/2=1##. Then ##d_4=|4-3|/2=1/2##. Also, ##d_5=|3-5|/2=2##.

If we continue ##x = [1, \,2,\, 3, \,NaN,\, 4,\, 5,\, NaN,\, 6]##. So far what I have is
Matlab:
x = [1 2 3 20 4 5 30 6];
for i = 2:length(x)-1
        if isnan(x(i-1))==0
            d(i) = abs(x(i+1)-x(i-1))/2;
            if d(i) > 5
                x(i+1) = NaN;
            end
        else
            ?
        end
end
I don't know how to write what I've described above, and I could be way off here. Any help would be so awesome!
 
Last edited by a moderator:
Physics news on Phys.org
I would put print statements in the iteration and step through your code and at each step you can verify whether MATLAB is doing what you want if not then you know right where to fix it.
 
  • Like
Likes   Reactions: stoomart
My solution for sake of others:
Matlab:
    %% smooths outliers to avoid clusters
    critslope = 3;% critical slope filter
    for i = 2:length(x)-1
        if isnan(x(i-1))==0
            slope(i) = abs(x(i+1)-x(i-1))/(2*dz);
            if slope(i) >= critslope
                x(i+1) = NaN;
            end
        count = 1;% reset count in case multiple NaN packets
        else
            count = count+1;% increase count since NaN detected
            slope(i) = abs(x(i+1)-x(i-count))/(2*dz);
            if slope(i) >= critslope
                x(i+1) = NaN;
            end
        end
    end
 
    %% rewrite NaN as previous value
    for i = 2:length(x)-1
        if isnan(x(i))==1
            x(i)=x(i-1);
        end
    end
 
Last edited by a moderator:
How did you figure out what was wrong?
 
jedishrfu said:
How did you figure out what was wrong?
It's not so much what was wrong, it was more just trying to get something in the "?" statement of my first post. After lot's of thinking about it the above is what came out. I googled and googled but didn't find anything, else I'd post a link.

I definitely followed your advice and printed the final ##x## results of the simple vector above, knowing exactly what the result should look like, and modified the conditions and the "count" until it worked.

At any rate, this should smooth data assuming the first data point is not an outlier.
 
  • Like
Likes   Reactions: jedishrfu

Similar threads

  • · Replies 2 ·
Replies
2
Views
1K
  • · Replies 10 ·
Replies
10
Views
4K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 3 ·
Replies
3
Views
5K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 6 ·
Replies
6
Views
4K
  • · Replies 1 ·
Replies
1
Views
3K