Determine if a range of values is linear
Posted: Wed Jan 18, 2017 2:59 pm
I was playing around with Lunasole's graph and it made me wonder: how do you determine how linear a range of values is? Where for example 0.0 is perfectly linear (2,4,6,8,10 or 10,8,6,4,2 or 5,5,5,5,5 etc) and 1.0 is 'extreme sawtooth' (255,0,255,0,255).
But then there's ones like 2,4,8,10,8,4,2 in a "/\" shape ... = 0.5 maybe?!?
I've come up with a couple of methods which are in the ballpark but clearly missing the mark!
does anyone know of any ways? sad to say my googling for this was fruitless
But then there's ones like 2,4,8,10,8,4,2 in a "/\" shape ... = 0.5 maybe?!?
I've come up with a couple of methods which are in the ballpark but clearly missing the mark!
does anyone know of any ways? sad to say my googling for this was fruitless
Code: Select all
Procedure.d Linearity(*buf.Ascii, len)
Protected totdev.d, max.d, expdev.d, *p.Ascii = *buf, exp.d
min = 255+1: minpos=1
For i = 1 To len
If *p\a > max: max = *p\a: maxpos=i: EndIf
If *p\a < min: min = *p\a: minpos=i: EndIf
*p+1
Next i
If maxpos => minpos: direction=1: Else: direction=-1: EndIf
expdev.d = ((max-min) / (len-1)) * direction
If direction = -1: exp=max: Else: exp=min: EndIf
*p = *buf
For i = 1 To len ;+ 1
totdev + Abs(exp - *p\a)
;Debug Str(i) + " Expected " + exp + " but actually " + Str(*p\a) + ", diff=" + Str(Abs(exp - *p\a))
exp + expdev
*p+1
Next i
ProcedureReturn totdev/len
EndProcedure
Procedure.d Linearity2(*buf.Ascii, len)
Protected totdev.d, max.d, expdev.d, *p.Ascii = *buf, exp.d
*p = *buf
For i = 1 To len ;+ 1
delta = *p\a - lastdelta
deltadiff = Abs(lastdelta - delta)
totdev + deltadiff
lastdelta = delta
*p+1
Next i
ProcedureReturn totdev/len
EndProcedure
#NUMVALS=10
Debug Linearity(?X1, #NUMVALS)
Debug Linearity(?X2, #NUMVALS)
Debug Linearity(?X3, #NUMVALS)
Debug Linearity(?X4, #NUMVALS)
Debug Linearity(?X5, #NUMVALS)
Debug Linearity(?X6, #NUMVALS)
DataSection
X1:
Data.a 0,255,0,255,0,255,0,255,0,255 ;= "0.0"
X2:
Data.a 2,4,6,8,10,12,14,16,18,20 ;= "1.0"
X3:
Data.a 20,18,16,14,12,10,8,6,4,2 ;= "1.0"
X4:
Data.a 2,4,6,8,10,11,12,16,18,20 ;= ?
X5:
Data.a 2,4,6,8,10,17,17,16,18,20 ;= ?
X6:
Data.a 2,4,6,8,10,10,8,6,4,2 ;= ~0.5?
EndDataSection