Spaces:
Running
Running
import sympy as sp | |
from sympy.parsing.sympy_parser import parse_expr, standard_transformations, implicit_multiplication_application | |
from sympy.solvers import solve | |
from sympy import integrate, diff, latex,simplify, expand, log, exp, sin, cos, tan, asin, acos, atan, Symbol, factorial, laplace_transform | |
import re | |
def format_expression(expr): | |
latex_expr = latex(expr) | |
replacements = { | |
'**': '^', # Power notation | |
'*x': 'x', # Remove unnecessary multiplication signs | |
'*(': '(', # Remove multiplication before parentheses | |
'exp': 'e^', # Exponential notation | |
'sqrt': '√', # Square root | |
'factorial': '!', # Factorial symbol | |
'gamma': 'Γ', # Gamma function | |
'Gamma': 'Γ', # Sometimes SymPy capitalizes it | |
'fresnels': 'S', # Fresnel S integral | |
'fresnelc': 'C', # Fresnel C integral | |
'hyper': '₁F₂', # Generalized hypergeometric function | |
'log': 'ln', # Natural logarithm | |
'oo': '∞', # Infinity symbol | |
'pi': 'π', # Pi symbol | |
'E': 'ℯ', # Euler's constant | |
'I': '𝒊', # Imaginary unit | |
'Abs': '|', # Absolute value | |
'Integral': '∫', # Integral symbol | |
'Derivative': 'd/dx', # Differentiation | |
'Sum': 'Σ', # Summation symbol | |
'Product': '∏', # Product symbol | |
'sin': 'sin', 'cos': 'cos', 'tan': 'tan', # Trig functions (unchanged) | |
'asin': 'sin⁻¹', 'acos': 'cos⁻¹', 'atan': 'tan⁻¹', # Inverse trig | |
'sinh': 'sinh', 'cosh': 'cosh', 'tanh': 'tanh', # Hyperbolic trig | |
'asinh': 'sinh⁻¹', 'acosh': 'cosh⁻¹', 'atanh': 'tanh⁻¹', # Inverse hyperbolic trig | |
'diff': 'd/dx', # Derivative notation | |
'integrate': '∫', # Integral notation | |
'Limit': 'lim', # Limit notation | |
'floor': '⌊', # Floor function | |
'ceiling': '⌈', # Ceiling function | |
'mod': 'mod', # Modulus (unchanged) | |
'Re': 'ℜ', # Real part | |
'Im': 'ℑ' # Imaginary part | |
} | |
for old, new in replacements.items(): | |
latex_expr = latex_expr.replace(old, new) | |
return f"$$ {latex_expr} $$" | |
def preprocess_equation(equation_str): | |
"""Convert user-friendly equation format to SymPy format.""" | |
try: | |
# Replace common mathematical notations | |
replacements = { | |
'^': '**', | |
'sin⁻¹': 'asin', | |
'cos⁻¹': 'acos', | |
'tan⁻¹': 'atan', | |
'e^': 'exp', | |
'ln': 'log', # Convert ln to log (SymPy default) | |
'√': 'sqrt', # Convert square root symbol to sqrt() | |
'!': '.factorial()', # Convert factorial to function call | |
} | |
for old, new in replacements.items(): | |
equation_str = equation_str.replace(old, new) | |
equation_str = re.sub(r'(\d+)!', r'factorial(\1)', equation_str) | |
# Handle exponential expressions | |
if 'exp' in equation_str: | |
parts = equation_str.split('exp') | |
for i in range(1, len(parts)): | |
if parts[i] and parts[i][0] != '(': | |
parts[i] = '(' + parts[i] | |
if '=' in parts[i]: | |
exp_part, rest = parts[i].split('=', 1) | |
parts[i] = exp_part + ')=' + rest | |
else: | |
parts[i] = parts[i] + ')' | |
equation_str = 'exp'.join(parts) | |
# Add multiplication symbol where needed | |
processed = '' | |
i = 0 | |
while i < len(equation_str): | |
if i + 1 < len(equation_str): | |
if equation_str[i].isdigit() and equation_str[i+1] == 'x': | |
processed += equation_str[i] + '*' | |
i += 1 | |
continue | |
processed += equation_str[i] | |
i += 1 | |
return processed | |
except Exception as e: | |
raise Exception(f"Error in equation format: {str(e)}") | |
def process_expression(expr_str): | |
"""Process mathematical expressions without equations.""" | |
try: | |
processed_expr = preprocess_equation(expr_str) | |
x = Symbol('x') | |
if expr_str.startswith('∫'): # Integration | |
expr_to_integrate = processed_expr[1:].strip() | |
expr = parse_expr(expr_to_integrate, transformations=(standard_transformations + (implicit_multiplication_application,))) | |
result = integrate(expr, x) | |
return f"∫{format_expression(expr)} = {format_expression(result)}" | |
elif expr_str.startswith('d/dx'): # Differentiation | |
expr_to_diff = processed_expr[4:].strip() | |
if expr_to_diff.startswith('(') and expr_to_diff.endswith(')'): | |
expr_to_diff = expr_to_diff[1:-1] | |
expr = parse_expr(expr_to_diff, transformations=(standard_transformations + (implicit_multiplication_application,))) | |
result = diff(expr, x) | |
return f"d/dx({format_expression(expr)}) = {format_expression(result)}" | |
elif 'factorial' in processed_expr: # Factorial case | |
expr = parse_expr(processed_expr, transformations=(standard_transformations + (implicit_multiplication_application,))) | |
result = expr.doit() # Compute the factorial correctly | |
return f"{format_expression(expr)} = {result}" | |
elif '/' in expr_str: # Handle fractions and return decimal | |
expr = parse_expr(processed_expr, transformations=(standard_transformations + (implicit_multiplication_application,))) | |
simplified = simplify(expr) | |
decimal_value = float(simplified) | |
return f"Simplified: {format_expression(simplified)}\nDecimal: {decimal_value}" | |
else: # Regular expression simplification | |
expr = parse_expr(processed_expr, transformations=(standard_transformations + (implicit_multiplication_application,))) | |
simplified = simplify(expr) | |
expanded = expand(simplified) | |
return f"Simplified: {format_expression(simplified)}\nExpanded: {format_expression(expanded)}" | |
except Exception as e: | |
raise Exception(f"Error processing expression: {str(e)}") | |
except Exception as e: | |
raise Exception(f"Error processing expression: {str(e)}") | |
def to_latex(expr): | |
"""Converts a SymPy expression into LaTeX format.""" | |
return f"$$ {sp.latex(expr)} $$" | |
def solve_equation(equation_str): | |
"""Solves an equation and returns a detailed LaTeX-formatted step-by-step solution.""" | |
try: | |
if '=' not in equation_str: | |
return process_expression(equation_str) | |
left_side, right_side = [side.strip() for side in equation_str.split('=')] | |
transformations = standard_transformations + (implicit_multiplication_application,) | |
left_expr = sp.parse_expr(left_side, transformations=transformations) | |
right_expr = sp.parse_expr(right_side, transformations=transformations) | |
equation = left_expr - right_expr | |
x = Symbol('x') | |
solutions = solve(equation, x) | |
steps = [] | |
steps.append(f"**Step 1:** Original equation: \n{to_latex(left_expr)} = {to_latex(right_expr)}") | |
steps.append(f"**Step 2:** Move all terms to one side: \n{to_latex(equation)} = 0") | |
factored = sp.factor(equation) | |
if factored != equation: | |
steps.append(f"**Step 3:** Factorizing the equation: \n{to_latex(factored)} = 0") | |
steps.append(f"**Step 4:** Solving for x:") | |
for sol in solutions: | |
steps.append(f" x = {to_latex(sol)}") | |
steps.append("**Step 5:** Verification:") | |
for sol in solutions: | |
verification = equation.subs(x, sol) | |
steps.append(f" When x = {to_latex(sol)}, the equation evaluates to {to_latex(verification)}") | |
return "\n".join(steps) | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def integrate_expression(expression_str): | |
"""Computes the integral of a given expression and provides detailed LaTeX-formatted steps.""" | |
try: | |
x = Symbol('x') | |
expr = sp.parse_expr(expression_str, transformations=standard_transformations + (implicit_multiplication_application,)) | |
steps = [] | |
steps.append(f"**Step 1:** Original integral: \n$$ \\int {sp.latex(expr)} \\,dx $$") | |
if '^' in expression_str: | |
steps.append("**Step 2:** Checking if substitution is needed.") | |
result = integrate(expr, x) | |
steps.append(f"**Step 3:** Applying integration formula(s):") | |
steps.append(f"$$ \\int f(x) \\,dx = F(x) + C $$") | |
steps.append(f"**Step 4:** Solution: \n$$ {sp.latex(result)} + C $$") | |
return "\n".join(steps) | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def laplace_transform_expression(expression_str): | |
"""Computes the Laplace transform of a given expression with LaTeX-formatted steps.""" | |
try: | |
t, s = sp.symbols('t s') | |
expr = sp.parse_expr(expression_str, transformations=standard_transformations + (implicit_multiplication_application,)) | |
steps = [] | |
steps.append(f"**Step 1:** Original function: \n$$ \\mathcal{L}\\{{ {sp.latex(expr)} \\}}(t) $$") | |
L_transform = laplace_transform(expr, t, s, noconds=True) | |
steps.append(f"**Step 2:** Applying Laplace Transform:") | |
steps.append("$$ \\mathcal{L}\\{ f(t) \\} = \\int_{0}^{\\infty} e^{-st} f(t) \\,dt $$") | |
steps.append(f"**Step 3:** Solution: \n$$ {sp.latex(L_transform)} $$") | |
return "\n".join(steps) | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def process_input(equation): | |
"""Determine whether the input is an equation, an integral, or a Laplace transform.""" | |
try: | |
if "laplace" in equation.lower(): | |
solution = laplace_transform_expression(equation) | |
elif "integrate" in equation.lower(): | |
solution = integrate_expression(equation) | |
else: | |
solution = solve_equation(equation) | |
return solution | |
except Exception as e: | |
return f"Error processing input: {str(e)}" |