概要
小ネタです。
今回作成するpythonの関数を使うと
CalcOuterRange([-0.1234, 0.4321]) # 出力:[-0.2, 0.5]
CalcOuterRange([-0.1234, 0.4321], -1) # 出力:[-0.13, 0.44]
CalcOuterRange([-1234, 4321]) # 出力:[-2000.0, 5000.0]
CalcOuterRange([-1234, 4321], -1) # 出力:[-1300.0, 4400.0]
というように少し外側のキリのいい数値を得られます。
はじめに
測定データの処理で、グラフの表示範囲やパラメータの探索範囲などを自動で設定させるとき、
「この計算値とこの計算値のちょっと外側」
にしておきたいということがあります。
簡単なやり方としては、計算で得た範囲の小さい方が$s_1$で、大きい方が$s_2$なら、
「$0.9 \times s_1$ ~ $1.1 \times s_2$」
というようにして設定範囲を求めます。
しかし、これでは$s_1$や$s_2$が負だと困りますし、2.38472...とかの小数だったりすると結果をレポートするときに「この変な値はなんだ?」と突っ込みが入るのが困りものです。
そこで、ちょっと外側だけどキリのいい数値を自動で求めてしまおうという方法です。
方法
まずは数値のオーダーが必要です。
自動化をしたいので、単純に「0.9かけて四捨五入すればいいでしょ」とはなりません。
温度計だったりマイクロメータだったりといろいろなオーダー感の測定器からのデータへの対応が必要です。
数値のオーダーといえば対数です。
そこで、$log_{10}(s_2 - s_2)$を求めて四捨五入することにします。
この結果を使って10の累乗を計算(これに「解像度」と勝手に名前をつけました)し、それで$s_1$の商を求めて「解像度」を掛け戻してやると、「ちょっと小さくてキリのいい値」が求まります。
「ちょっと大きくてキリのいい値」は、同様に$s_2$の商を求めた後に1を足してから「解像度」を掛け戻すことで求めることができます。
問題は、「ちょっと」の程度をどうするかです。
$s_1 = -0.1234, s_2 = 0.4321$だったとき、「-0.2~0.6」にするのか「-0.13~0.44」にするのかは、その人の感性や置かれた状況によります。(「-1~1」がいいという人もいるかもしれない?)
これは四捨五入する相対的な桁の調整ですので、「解像度」の調整用にパラメータを入力できるようします。
そして、できたのが次の関数です。
python関数
numpyを import numpy as np
として読み込んでおいてください。
# ====================================
# CalcOuterRange
# 範囲のちょっと外側の値を返す関数
# 引数:
# listX: 範囲の下と上の値を含む数値リスト
# param: 解像度調整用パラメータ(デフォルト:0)
# 返り値:
# 少し外側の値のリスト(少し小さな値,少し大きな値)
# ====================================
def CalcOuterRange(listX, param=0):
S1 = min(listX) # 範囲の下の値
S2 = max(listX) # 範囲の上の値
dS = S2 - S1 # 上と下の差
SOrder = np.round(np.log10(dS),0) # 差のオーダーを求める
SRate = 10**(SOrder-1 + param) # 解像度を計算
r1 = (S1 // SRate - 0.) * SRate # 少し小さな値
r2 = (S2 // SRate + 1.) * SRate # 少し大きな値
return [r1,r2]
入力する際に、「一番目が上だっけ?下だっけ?」とか「リストからいちいち最大値と最小値をとるのが面倒くさい」とかという人(私だ…)のために、リストで入力を受けるようにしました。
付記
浮動小数点数の宿命として、「0.6000000000000001」といった半端がついた値が返ってくることがあります。
これは、簡単に言えば、「0.6が表示上そうなっているだけ」ですので、半端は無視してください。
(詳細は浮動小数点数が解説されているサイトを参照してください。
例:「浮動小数点って何?」)