Android Question Exponential smoothing code for 1D int array

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Does anybody have code to smooth out a 1D int array holding satellite altitude data?
I have seen code from Klaus but that deals with smoothing out graphs.
I would like to just pass the array and get an altered array (may have double values) back.

RBS
 

William Lancee

Well-Known Member
Licensed User
Longtime User
Here is a simple approach that works with any sequence of points.
A point has an x,y. Your y is the altitude. Your x = 0,1,2,3,4,5,... Or perhaps 'time'

The "feature" of this approach is that the resulting line is smooth and is not constrained to fit through any particular point - except start and end point.

https://www.b4x.com/android/forum/t...h-curved-line-to-a-sequence-of-points.143178/

You can also try various averaging techniques. A running average of 3 or 5 points, smooths points well depending how large outliers are.
new P(i) = [p(i-2) + p(i-1) + p(i) + p(i+1) + p(i+2)] / 5 At the boundaries just adjust that formula: p(0) = p(1)+ p(2) /2 etc.

By weighting each term, you can achieve good results, depending on the data.

Another common smoothing approach is the the use of cubic splines or Bezier curves.

If you are using this data where you have to communicate with others about your curves, you need to check the literature to see what acceptable techniques are being used for you kind of data. What methods are commonly used for smoothing altitude data? I googled and here are some suggestion, even an algorithm.

 
Upvote 0

emexes

Expert
Licensed User
Does anybody have code to smooth out a 1D int array holding satellite altitude data?
I would like to just pass the array and get an altered array (may have double values) back.

The code would usually look like:

B4X:
Dim HistoryProportion As Double = 0.5    '0 (no history, only current value ie no smoothing) to 1 (all history, no current value) (ie too much of a good thing)

If NumAltitudes > 0 Then
    Dim Smoothed(NumAltitudes) As Double
    Smoothed(0) = Altitude(0)
    For I = 1 To NumAltitudes - 1
        Smoothed(I) = Smoothed(I - 1) * HistoryProportion + Altitude(I) * (1 - HistoryProportion)
    Next
End If

but some people (me included) prefer it from the other perspective:

B4X:
Dim HistoryWeight As Int = 1    '0 = no smoothing, larger values = more smoothing

If NumAltitudes > 0 Then
    Dim Smoothed(NumAltitudes) As Double
    Smoothed(0) = Altitude(0)
    For I = 1 To NumAltitudes - 1
        Smoothed(I) = (Smoothed(I - 1) * HistoryWeight + Altitude(I)) / (HistoryWeight + 1)
    Next
End If
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Does anybody have code to smooth out a 1D int array holding satellite altitude data?
I would like to just pass the array and get an altered array (may have double values) back.

Sorry, I just noticed that the input is Int and that you seem amenable to the output being Int too, so with Int math only then maybe:

B4X:
Dim HistoryWeight As Int = 1    '0 = no smoothing, larger values = more smoothing
Dim HistoryWeightRounding As Int = (HistoryWeight + 1) / 2    'for rounding, assuming Int division truncates

If NumAltitudes > 0 Then
    Dim Smoothed(NumAltitudes) As Int
    Smoothed(0) = Altitude(0)
    For I = 1 To NumAltitudes - 1
        Smoothed(I) = (Smoothed(I - 1) * HistoryWeight + Altitude(I) + HistoryWeightRounding) / (HistoryWeight + 1)
    Next
End If
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Here is a simple approach that works with any sequence of points.
A point has an x,y. Your y is the altitude. Your x = 0,1,2,3,4,5,... Or perhaps 'time'

The "feature" of this approach is that the resulting line is smooth and is not constrained to fit through any particular point - except start and end point.

https://www.b4x.com/android/forum/t...h-curved-line-to-a-sequence-of-points.143178/

You can also try various averaging techniques. A running average of 3 or 5 points, smooths points well depending how large outliers are.
new P(i) = [p(i-2) + p(i-1) + p(i) + p(i+1) + p(i+2)] / 5 At the boundaries just adjust that formula: p(0) = p(1)+ p(2) /2 etc.

By weighting each term, you can achieve good results, depending on the data.

Another common smoothing approach is the the use of cubic splines or Bezier curves.

If you are using this data where you have to communicate with others about your curves, you need to check the literature to see what acceptable techniques are being used for you kind of data. What methods are commonly used for smoothing altitude data? I googled and here are some suggestion, even an algorithm.

Thanks for all the replies and will start with the simplest approach something like this:

B4X:
Dim HistoryWeight As Int = 1    '0 = no smoothing, larger values = more smoothing

If NumAltitudes > 0 Then
    Dim Smoothed(NumAltitudes) As Double
    Smoothed(0) = Altitude(0)
    For I = 1 To NumAltitudes - 1
        Smoothed(I) = (Smoothed(I - 1) * HistoryWeight + Altitude(I)) / (HistoryWeight + 1)
    Next
End If

As posted by Exemes.

There some other things to look at with this specific altitude date, eg to look at the distance between 2 map points (currently obtained from sat readings
every 3 seconds). If for example the altitude at x is different than the altitude at x - 1 and the distance between those points is less than z meters than perhaps
that altitude reading should be ignored or instead the reading at x - 1 should be taken or the reading at x + 1.
All adding to the complexity.

RBS
 
Upvote 0
Top