Aetherius / services /math_kernel.py
KingOfThoughtFleuren's picture
Update services/math_kernel.py
7a36c05 verified
raw
history blame
2.06 kB
# services/math_kernel.py
from typing import Dict, Any, List, Optional
import sympy as sp
from sympy.parsing.sympy_parser import (
parse_expr, standard_transformations, convert_xor, implicit_multiplication_application
)
TRANSFORMS = standard_transformations + (convert_xor, implicit_multiplication_application)
SAFE_FUNCS = {
"sin": sp.sin, "cos": sp.cos, "tan": sp.tan, "exp": sp.exp, "log": sp.log,
"sqrt": sp.sqrt, "Eq": sp.Eq, "diff": sp.diff, "integrate": sp.integrate,
"Symbol": sp.Symbol
}
def _parse(s: str):
return parse_expr(s, local_dict=SAFE_FUNCS, transformations=TRANSFORMS)
def compute(task: str, expr: str, solve_for: Optional[List[str]] = None, subs: Optional[Dict[str, Any]] = None):
"""
task: 'symbolic' | 'numeric'
expr: SymPy string or Eq(...)
solve_for: symbols to solve for
subs: dict like {"M":"1.0", "r":"4"} (strings parsed via SymPy)
"""
out = {"steps": [], "symbolic": None, "numeric": None, "interpretation": ""}
try:
e = _parse(expr)
out["steps"].append(f"Parsed: {e}")
if subs:
sdict = {sp.Symbol(k): (_parse(v) if isinstance(v, str) else v) for k, v in subs.items()}
e = e.subs(sdict)
out["steps"].append(f"Substitutions: {sdict}")
if task == "symbolic":
if solve_for:
syms = [sp.Symbol(n) for n in solve_for]
sol = sp.solve(e, *syms, dict=True)
out["symbolic"] = str(sol)
out["interpretation"] = "Solved symbolically."
else:
out["symbolic"] = str(sp.simplify(e))
out["interpretation"] = "Simplified symbolically."
elif task == "numeric":
val = float(e.evalf())
out["numeric"] = {"value": val}
out["interpretation"] = "Numeric evaluation complete."
else:
out["interpretation"] = "Unknown task."
return out
except Exception as err:
out["interpretation"] = f"Error: {err}"
return out