Last active
April 23, 2018 01:59
-
-
Save KatsuhiroMorishita/403a4e2e03f3c6b17eb86db53c981749 to your computer and use it in GitHub Desktop.
文字列やベクトルや行列を含む配列の一致を判定する関数です。Pythonで行った数値計算の試験の解答用に開発しました。
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
# 不定形のベクトルの一致を判定する | |
# 数値計算の試験の解答用に開発した。 | |
# author: Katsuhiro Morishita | |
# created: 2018-02 | |
# lisence: MIT | |
import numpy as np | |
import collections | |
def flatten(foo): | |
""" 多次元配列を1次元配列に変換する | |
setや辞書には対応していない。 | |
""" | |
if isinstance(foo, np.matrixlib.defmatrix.matrix): # matrixはndarrayに変換しておかないと、中身を取り出せない | |
foo = np.array(foo) | |
series = [] | |
for mem in foo: | |
if isinstance(mem, collections.Iterable) and not isinstance(mem, str): | |
bar = flatten(mem) | |
series += bar | |
elif isinstance(mem, complex): | |
series.append(mem.real) | |
series.append(mem.imag) | |
else: | |
#print(mem) | |
series.append(mem) | |
return series | |
def check(o, t, th=0.001): | |
""" 2つのベクトルの中身が数値計算的に等しいかどうか確認する | |
return | |
True: 等しい | |
False: 等しくない | |
""" | |
# 入れ子構造の変数を1次元に変換 | |
o = flatten([o]) | |
t = flatten([t]) | |
# 次元数の確認 | |
if len(o) != len(t): | |
print("--0--, length not match") | |
return False | |
# intをfloatに変更 | |
_o = [float(x) if isinstance(x, int) else x for x in o] | |
_t = [float(y) if isinstance(y, int) else y for y in t] | |
_o = [float(x) if isinstance(x, np.int16) else x for x in _o] | |
_t = [float(y) if isinstance(y, np.int16) else y for y in _t] | |
_o = [float(x) if isinstance(x, np.int32) else x for x in _o] | |
_t = [float(y) if isinstance(y, np.int32) else y for y in _t] | |
_o = [float(x) if isinstance(x, np.int64) else x for x in _o] | |
_t = [float(y) if isinstance(y, np.int64) else y for y in _t] | |
_o = [float(x) if isinstance(x, np.float32) else x for x in _o] | |
_t = [float(y) if isinstance(y, np.float32) else y for y in _t] | |
_o = [float(x) if isinstance(x, np.float64) else x for x in _o] | |
_t = [float(y) if isinstance(y, np.float64) else y for y in _t] | |
# 型をチェック 一方がNoneでもFalseとなる | |
c = [type(x) == type(y) for x,y in zip(_o, _t)] | |
if False in c: | |
print("--1--") | |
print(_o, _t, c) | |
return False | |
# 完全一致だとTrue NoneでもOK 数値は処理したくない | |
__o = [True if x == y or x is y else x for x,y in zip(_o, _t)] # 文字列の一致もここでチェックできる | |
__t = [True if x == y or x is y else y for x,y in zip(_o, _t)] | |
# 文字列の不一致を数値化 | |
_o = [0 if isinstance(x, str) else x for x,y in zip(__o, __t)] # 文字角不一致があれば、それを0と1(ベクトル的には直交)で表現する | |
_t = [1 if isinstance(x, str) else y for x,y in zip(__o, __t)] | |
#print("--2--", _o, _t) | |
# ベクトル内の数値の要素を個別にチェック(Trueは1、Falseは0として扱われる) | |
for i in range(len(_o)): # 0での除算を避けるための処理 | |
x, y = _o[i], _t[i] | |
m = max(x, y) | |
if m == 0.0: | |
_o[i] = 0.0000001 | |
ans = [abs((x - y) / max(x, y)) < th for x,y in zip(_o, _t)] | |
print("--3--", ans) | |
return False not in ans | |
def main(): | |
a = [10.1, "解なし", False, [10, "解なし", 45, [10, 20, 30]]] | |
#a = [10.1, "解なし", False, [10, 0.001, 45, [10, 20, 10+3j]]] | |
b = [10.11, "解なし", False, [10, 0.001, 45, [10, 20, 10+3j]]] | |
#b = [10, "解あり", True, [10, 20, 30, [10, 20, 30-23j]]] | |
print(check(a, b)) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment