Skip to content

Commit

Permalink
Update JonesFaithfulTransformation to use sympy
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Horton <mkhorton@users.noreply.github.com>
  • Loading branch information
mkhorton committed Feb 12, 2024
1 parent 12ab947 commit c231cbd
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions pymatgen/symmetry/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from fractions import Fraction

import numpy as np
from sympy import Matrix
from sympy.parsing.sympy_parser import parse_expr

from pymatgen.core.lattice import Lattice
from pymatgen.core.operations import MagSymmOp, SymmOp
Expand Down Expand Up @@ -99,21 +101,29 @@ def parse_transformation_string(
b_change, o_shift = transformation_string.split(";")
basis_change = b_change.split(",")
origin_shift = o_shift.split(",")

# add implicit multiplication symbols
basis_change = [
re.sub(r"(?<=\w|\))(?=\() | (?<=\))(?=\w) | (?<=(\d|a|b|c))(?=([abc]))", r"*", string, flags=re.X)
for string in basis_change
]
# should be fine to use eval here but be mindful for security
# reasons
# see http://lybniz2.sourceforge.net/safeeval.html
# could replace with regex? or sympy expression?
P = np.array([eval(x, {"__builtins__": None}, {"a": a, "b": b, "c": c}) for x in basis_change])
P = P.transpose() # by convention

# basic input sanitation
allowed_chars = "0123456789+-*/.abc()"
basis_change = ["".join([c for c in string if c in allowed_chars]) for string in basis_change]

# requires round-trip to sympy to evaluate
# (alternatively, `numexpr` looks like a nice solution but requires an additional dependency)
basis_change = [
parse_expr(string).subs({"a": Matrix(a), "b": Matrix(b), "c": Matrix(c)}) for string in basis_change
]
# convert back to numpy, perform transpose by convention
P = np.array(basis_change, dtype=float).T[0]

p = [float(Fraction(x)) for x in origin_shift]
return P, p
except Exception:
raise ValueError("Failed to parse transformation string.")
except Exception as exc:
raise ValueError(f"Failed to parse transformation string: {exc}")

@property
def P(self) -> list[list[float]]:
Expand Down

0 comments on commit c231cbd

Please sign in to comment.