Created
January 6, 2016 18:08
-
-
Save WeatherGod/272f4022bf7a8ca12ff4 to your computer and use it in GitHub Desktop.
Common Sigs attempt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import math | |
def CalcOffset(a, oom) : | |
if np.isinf(oom) : | |
return np.nan | |
minval = a.min() | |
if minval < 0.0 : | |
big_offset = math.ceil(minval/10**oom)*10**oom | |
else : | |
big_offset = math.floor(minval/10**oom)*10**oom | |
# We want the smallest possible OoM, so subtract the big offset | |
# so that we have a set of value differences. This will help | |
# in identifying situations like '[15.99, 16.01]' because the | |
# data difference has no common OoM. | |
# Meanwhile, '[12331.4, 12350.5]' will find 12300 as the final | |
# offset. | |
diff_oom = common_sigdigs(a - big_offset) | |
# If subtracting the big offset resulted in values that did not | |
# have the same OoM, then the big offset is the offset we want. | |
if np.isinf(diff_oom) : | |
diff_oom = oom | |
# I want to use math.trunc(), but there seems to be a difference in domain | |
# for it and for math.ceil() and math.floor()... | |
if a.min() < 0.0 : | |
return math.ceil(a.min()/10**diff_oom)*10**diff_oom | |
else : | |
return math.floor(a.min()/10**diff_oom)*10**diff_oom | |
def common_sigdigs(a) : | |
# Absolute value to allow zero-crossing | |
a = np.abs(np.asanyarray(a)) | |
valmax = a.max() | |
valmin = a.min() | |
if valmin == valmax : | |
# Same absolute values, so same sig digs, so return 0.0 | |
return 0.0 | |
# Avoid log10 domain error | |
if valmin > 0.0 : | |
if math.floor(math.log10(valmax)) == math.floor(math.log10(valmin)) : | |
return math.ceil(math.log10(valmax - valmin)) | |
else : | |
# Assume that 0.0 has an OoM of 0. | |
if math.floor(math.log10(valmax)) == 0.0 : | |
return 0.0 | |
# If they aren't of the same OoM, then return -inf so that | |
# a calculated offset will be zero. | |
return -np.inf | |
def CalcOffset_brute(a) : | |
if len(a) == 0 : | |
return np.nan | |
comp_str = "%25.10f" % abs(a[0]) | |
a_str = [("%25.10f" % abs(b)) for b in a[1:]] | |
decpoint_loc = comp_str.find('.') | |
if decpoint_loc == -1 : | |
decpoint_loc = len(comp_str) | |
index = 0 | |
while index < len(comp_str) : | |
if any((b[index] != comp_str[index]) for b in a_str) : | |
break | |
index += 1 | |
try : | |
val = math.copysign(float(comp_str[:index]), min(a)) | |
if comp_str[:index].find('.') == -1 : | |
val *= 10**(decpoint_loc - index) | |
return val if val != 0.0 else np.nan | |
except : | |
return np.nan | |
if __name__ == '__main__' : | |
testdata = ([ 0.4538, 0.4559, 0.4553, 0.4578], | |
[ 3789.12, 3782.89, 3783.1 ], | |
[ 45124.3, 45831.34, 45831.75], | |
[ 0.000721, 0.0007283, 0.0007243], | |
[ 12592.82, 12599.1, 12593.5, 12591.43], | |
[ 9., 10., 11., 12.], | |
[ 900., 1000., 1100., 1200.], | |
[ 1900., 1000., 1100., 1200.], | |
[ 0.99, 1.01], | |
[ 9.99, 10.01], | |
[ 99.99, 100.01], | |
[ 5.99, 6.01], | |
[ 15.99, 16.01], | |
[-0.452, -0.4, 0.411, 0.492], | |
[-0.492, -0.452, 0.411, 0.4, 0.492], | |
[12331.4, 12394.102, 12350.5], | |
[-12335.3, -12310.4, 12310.2, 12335.3]) | |
for a in testdata : | |
a = np.array(a) | |
common_oom = common_sigdigs(a) | |
offset = CalcOffset(a, common_oom) | |
offset_brute = CalcOffset_brute(a) | |
ismatch = ((offset == offset_brute) or (np.isnan(offset) and | |
np.isnan(offset_brute))) | |
print a, '\t', common_oom, offset, offset_brute, \ | |
('PASS' if ismatch else 'FAIL') | |
if np.isfinite(offset) : | |
print a - offset | |
common_oom = common_sigdigs(-a) | |
offset = CalcOffset(-a, common_oom) | |
offset_brute = CalcOffset_brute(-a) | |
ismatch = ((offset == offset_brute) or (np.isnan(offset) and | |
np.isnan(offset_brute))) | |
print -a, '\t', common_oom, offset, offset_brute, \ | |
('PASS' if ismatch else 'FAIL') | |
if np.isfinite(offset) : | |
print (-a) - offset | |
print ' ' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment