counting / maths /calculus /multiple_integral.py
spagestic's picture
feat: simplify descriptions and examples in Gradio interfaces for arithmetic and calculus tools
db31576
Raw History Blame Contribute Delete
4.73 kB
import sympy
from typing import List, Tuple, Union
import gradio as gr
import json
def multiple_integral(expression_str: str, integration_vars: List[Tuple[str, Union[str, float], Union[str, float]]]) -> str:
"""
Computes definite multiple integrals.
Args:
expression_str: The mathematical expression (e.g., "x*y**2").
integration_vars: A list of tuples, where each tuple contains:
(variable_name_str, lower_bound_str_or_float, upper_bound_str_or_float).
Example: [("x", "0", "1"), ("y", "0", "x")] for integral from 0 to 1 dx of integral from 0 to x dy of (x*y**2).
The order in the list is the order of integration (inner to outer).
Returns:
String representation of the integral result or an error message.
"""
try:
present_symbols = {sym.name: sym for sym in sympy.parse_expr(expression_str, transformations='all').free_symbols}
integration_params_sympy = []
for var_name, lower_bound, upper_bound in integration_vars:
var_sym = present_symbols.get(var_name, sympy.Symbol(var_name))
if var_sym.name not in present_symbols:
present_symbols[var_sym.name] = var_sym
lower_s = sympy.sympify(lower_bound, locals=present_symbols)
upper_s = sympy.sympify(upper_bound, locals=present_symbols)
integration_params_sympy.append((var_sym, lower_s, upper_s))
if not integration_params_sympy:
return "Error: No integration variables specified."
expr = sympy.parse_expr(expression_str, local_dict=present_symbols, transformations='all')
integral_val = sympy.integrate(expr, *integration_params_sympy)
return str(integral_val)
except (sympy.SympifyError, TypeError, SyntaxError) as e:
return f"Error parsing expression, bounds, or variables: {e}. Ensure bounds are numbers or valid expressions."
except Exception as e:
return f"An unexpected error occurred during integration: {e}"
def parse_integration_variables(vars_json_str: str):
"""
Parses a JSON string representing a list of integration variables and their bounds.
Expected format: '[["var1", "lower1", "upper1"], ["var2", "lower2", "upper2"]]
"""
try:
parsed_list = json.loads(vars_json_str)
if not isinstance(parsed_list, list):
raise ValueError("Input must be a JSON list.")
integration_vars = []
for item in parsed_list:
if not (isinstance(item, list) and len(item) == 3):
raise ValueError("Each item in the list must be a sub-list of three elements: [variable_name, lower_bound, upper_bound].")
var, low, upp = item
if not isinstance(var, str):
raise ValueError(f"Variable name '{var}' must be a string.")
if not (isinstance(low, (str, int, float))) or not (isinstance(upp, (str, int, float))):
raise ValueError(f"Bounds for variable '{var}' must be numbers or strings. Got '{low}' and '{upp}'.")
integration_vars.append((str(var), str(low), str(upp)))
return integration_vars
except json.JSONDecodeError:
raise gr.Error("Invalid JSON format for integration variables.")
except ValueError as ve:
raise gr.Error(str(ve))
except Exception as e:
raise gr.Error(f"Unexpected error parsing integration variables: {str(e)}")
multiple_integral_interface = gr.Interface(
fn=lambda expr_str, vars_json_str: multiple_integral(expr_str, parse_integration_variables(vars_json_str)),
inputs=[
gr.Textbox(label="Expression (e.g., x*y**2, 1)", value="x*y"),
gr.Textbox(
label="Integration Variables and Bounds (JSON list of [var, low, upp] tuples, inner to outer)",
value='[["y", "0", "x"], ["x", "0", "1"]]',
info="Example: integral_0^1 dx integral_0^x dy (x*y) is [['y', '0', 'x'], ['x', '0', '1']]"
)
],
outputs="text",
title="Definite Multiple Integral Calculator",
description="Compute multiple integrals.\n\n**Description:**\nThis tool computes definite multiple integrals for a given expression and bounds. The order of variables in the list is inner-most integral first.\n\n**Examples:**\n- Expression: x*y, Variables: [[\"y\", \"0\", \"x\"], [\"x\", \"0\", \"1\"]] → Output: 1/6\n- Expression: x**2, Variables: [[\"x\", \"0\", \"2\"]] → Output: 8/3\n- Expression: 1, Variables: [[\"x\", \"0\", \"1\"], [\"y\", \"0\", \"1\"]] → Output: 1",
examples=[["x*y", '[["y", "0", "x"], ["x", "0", "1"]]'], ["x**2", '[["x", "0", "2"]]'], ["1", '[["x", "0", "1"], ["y", "0", "1"]]']],
)