diff --git a/app/math_engine/derivative.py b/app/math_engine/derivative.py index 9b2f72a..67ceb53 100644 --- a/app/math_engine/derivative.py +++ b/app/math_engine/derivative.py @@ -1,9 +1,21 @@ -import sympy as sp +import sympy from sympy import Symbol, Derivative + from app.math_engine.parser import parse_expression -def compute_derivative(expression: str, variable: str, num: int | None = 1) -> sp.Expr: # str输入一个字符串作为需要求导的公式,num不输入则求一阶导数,输入则求对应阶导 - f=parse_expression(expression) - x=Symbol(variable) - d=Derivative(f,x, num) - return d.doit() \ No newline at end of file + +def compute_derivative(expression: str, variable: str, num: int = 1, + x_num: float | None = None) -> sympy.Expr: # str输入一个字符串作为需要求导的公式,num不输入则求一阶导数,输入则求对应阶导 + f = parse_expression(expression) + x = Symbol(variable) + d = Derivative(f, x, num) + d = d.doit() + d_str = str(d) + problematic = ['Derivative', 'nan', 'zoo'] + if any(word in d_str for word in problematic): + return sympy.nan + + if x_num is None: + return d + else: + return d.subs({x: x_num}) diff --git a/app/math_engine/gradient.py b/app/math_engine/gradient.py index f042073..70a6d9b 100644 --- a/app/math_engine/gradient.py +++ b/app/math_engine/gradient.py @@ -1,12 +1,13 @@ -"""Gradient computation placeholder.""" +from typing import Union -from typing import Any +from sympy import Symbol, Derivative +from app.math_engine.parser import parse_expression -def compute_gradient(expression: Any, variables: list[str]) -> Any: - """Compute a future gradient vector for a scalar field. - TODO: Implement with SymPy once scalar field handling is added. - """ +def compute_gradient(expression: Union[str, list[str]], variables: list[str]) -> Union[list, list[list]]: + symbols = [Symbol(v) for v in variables] - raise NotImplementedError("Gradient computation is not implemented yet.") + if isinstance(expression, str): + f = parse_expression(expression) + return [Derivative(f, sym).doit() for sym in symbols] diff --git a/app/math_engine/vector_field.py b/app/math_engine/vector_field.py index 48d1b88..9237b8b 100644 --- a/app/math_engine/vector_field.py +++ b/app/math_engine/vector_field.py @@ -1,16 +1,36 @@ -"""Vector field processing placeholder. +from typing import Any -Future responsibility: -- Validate vector field component count. -- Parse each component into a symbolic expression. -- Normalize vector field data for divergence, curl, and rendering. -""" +from sympy import symbols -from typing import Any +from app.math_engine.parser import parse_expression + + +def parse_vector_field(vector_field: list[str]) -> list[Any]: + return [parse_expression(comp) for comp in vector_field] + + +def evaluate_vector_field(vector_field: list[str], + variables: list[str], point: dict[str, float]) -> list[float]: + components = parse_vector_field(vector_field) + + syms = [symbols(v) for v in variables] + + subs_dict = {syms[i]: point[var] for i, var in enumerate(variables)} + + result = [] + for comp in components: + val = comp.subs(subs_dict) + if val.is_number: + result.append(float(val)) + else: + result.append(val) + return result -def parse_vector_field(vector_field: list[str], variables: list[str]) -> list[Any]: - """Parse vector field components into future symbolic objects.""" - # TODO: Parse each component with parser.parse_expression. - raise NotImplementedError("Vector field parsing is not implemented yet.") +def evaluate_vector_field_multiple(vector_field: list[str], variables: list[str], + points: list[dict[str, float]]) -> list[list[float]]: + results = [] + for point in points: + results.append(evaluate_vector_field(vector_field, variables, point)) + return results \ No newline at end of file