73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Compare two OpticsFEM COO exports (Ai/Aj/Av, Bv_real/Bv_imag)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
import numpy as np
|
|
from scipy import sparse
|
|
|
|
|
|
def load_coo(prefix: Path) -> tuple[sparse.csr_matrix, np.ndarray]:
|
|
ai = np.loadtxt(prefix / "Ai.txt", dtype=np.int64)
|
|
aj = np.loadtxt(prefix / "Aj.txt", dtype=np.int64)
|
|
av: list[complex] = []
|
|
for line in (prefix / "Av.txt").read_text(encoding="utf-8", errors="ignore").splitlines():
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
if line.startswith("(") and line.endswith(")"):
|
|
re_s, im_s = line[1:-1].split(",")
|
|
av.append(complex(float(re_s), float(im_s)))
|
|
else:
|
|
av.append(complex(float(line)))
|
|
a = sparse.coo_matrix((np.asarray(av), (ai, aj))).tocsr()
|
|
br = np.loadtxt(prefix / "Bv_real.txt")
|
|
bi = np.loadtxt(prefix / "Bv_imag.txt")
|
|
b = br + 1j * bi
|
|
return a, b
|
|
|
|
|
|
def main() -> int:
|
|
ap = argparse.ArgumentParser(description=__doc__)
|
|
ap.add_argument("ref", type=Path, help="reference directory (e.g. MATLAB OutFile_fem4_ab)")
|
|
ap.add_argument("other", type=Path, help="other directory (e.g. C++ OutFile)")
|
|
args = ap.parse_args()
|
|
|
|
a_ref, b_ref = load_coo(args.ref)
|
|
a_other, b_other = load_coo(args.other)
|
|
|
|
print(f"ref: n={a_ref.shape[0]} nnz={a_ref.nnz} |b|={np.linalg.norm(b_ref):.6g}")
|
|
print(f"other: n={a_other.shape[0]} nnz={a_other.nnz} |b|={np.linalg.norm(b_other):.6g}")
|
|
|
|
if a_ref.shape != a_other.shape:
|
|
print("[FAIL] matrix shape mismatch")
|
|
return 1
|
|
if b_ref.size != b_other.size:
|
|
print("[FAIL] b length mismatch")
|
|
return 1
|
|
|
|
d = a_ref - a_other
|
|
max_abs = abs(d).max()
|
|
nnz_diff = d.nnz
|
|
rel = max_abs / max(abs(a_ref).max(), 1e-30)
|
|
print(f"A max|diff|={max_abs:.6g} rel={rel:.6g} nnz(diff)={nnz_diff}")
|
|
|
|
b_diff = np.max(np.abs(b_ref - b_other))
|
|
print(f"b max|diff|={b_diff:.6g}")
|
|
|
|
if max_abs < 1e-9 and b_diff < 1e-9:
|
|
print("[OK] matrices match within 1e-9")
|
|
return 0
|
|
if max_abs < 1e-6 and b_diff < 1e-6:
|
|
print("[WARN] close but not identical")
|
|
return 0
|
|
print("[FAIL] significant difference")
|
|
return 2
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|