====================== pycc.post_processing() ====================== ----- **Symbolic Regression (method=\'SymbR\')** ----------------------------------------- This is a standalone utility function designed for a common post-processing workflow: converting the numerical characteristic curves (``evals``) from a \'NN\', \'Poly\' or other model into explicit symbolic expressions *before* running a simulation. While ``pycc.simulate(method='SymbR')`` can do this on-the-fly, this function allows you to: 1. Run the symbolic regression fit as a separate, explicit step. 2. Inspect, analyze, and save the discovered symbolic functions. 3. Receive plots of the fits to validate their quality. 4. Get a ``models`` dictionary that can be fed into ``pycc.simulate(method='SymbR')``. 5. Get a new, clean ``evals_sr`` list based on the *symbolic* fit, which can be used for fast interpolation-based simulation. **Function Parameters** This function is called as ``pycc.post_processing(equations, method='SymbR', params)``. * ``equations``: (*list[str]*) The list of system equation strings (e.g., ``['x1_dot = x2', 'x2_dot = F_ext - f1(x2) - f2(x1)']``). This is used to automatically find the names of the functions to fit (e.g., ``'f1'``, ``'f2'``). * ``params``: (*dict*) A dictionary containing the following keys: * ``'evals'``: (*list, required*) The `evals` flat list (e.g., ``[x_f1, y_f1, x_f2, y_f2, ...]``) returned from a ``pycc.train()`` run (e.g., from `method='NN'`). * ``'pysr'``: (*dict, required*) A dictionary of keyword arguments that are passed directly to the ``PySRRegressor``. This is the primary way to control the symbolic regression process. See the `PySR documentation `_ for all options. **Example:** .. code-block:: python pysr_settings = { 'niterations': 500, 'populations': 20, 'binary_operators': ["+", "*", "-"], 'unary_operators': ["tanh", "sin", "cos"], 'maxsize': 20, 'verbosity': 0 } * ``'plot'``: (*bool, optional*) If ``True``, the function will display a Matplotlib plot for each function, showing the original ``evals`` data points and the resulting symbolic fit. **Default: True**. * ``'n_eval'``: (*int, optional*) The number of points to use for generating the new, smooth characteristic curves in the ``evals_sr`` output. **Default: 200**. **Return Value** This function returns a tuple of two variables: ``(models_sr, evals_sr)``. * ``models_sr``: (*dict*) A dictionary containing the symbolic regression results, formatted to be used directly by the simulation function. Its structure is: .. code-block:: python { 'f1': { 'expr': '0.5*x0 + 0.1*x0**3', # The symbolic expression 'func': , # A python function of the expression 'pysr_model': # The full trained model }, 'f2': { ... } } This dictionary can be passed directly to ``pycc.simulate`` as the ``'models'`` parameter. * ``evals_sr``: (*list*) A new, flat list of NumPy arrays ``[x_f1_new, y_f1_new, x_f2_new, y_f2_new, ...]``. This list contains the *discovered symbolic functions* evaluated at ``n_eval`` points over their original domain. This is useful for plotting or for use with ``pycc.simulate(method='Interp')``. **Workflow Example** Here is the complete workflow: 1. **Train** a model (like 'NN') to get numerical `evals`. 2. **Post-process** the `evals` with `post_processing_SymbR` to get symbolic `models_sr`. 3. **Simulate** using either the new `models_sr` (symbolic) or `evals_sr` (interpolation). .. code-block:: python import pycc import numpy as np # --- Assume 'eqs', 'df_data', 't_span', 'y0', etc. are defined --- # --- 1. Train an NN model to get 'evals' --- nn_params = {'epochs': 2000, 'lr': 1e-3, ...} models_nn, evals_nn, coefs_nn = pycc.train(df_data, eqs, method='NN', params=nn_params) # --- 2. Post-process 'evals_nn' to get symbolic models --- # Define settings for the new PySR fit pysr_settings = { 'niterations': 500, 'populations': 20, 'binary_operators': ['+', '*', '-'], 'unary_operators': ['tanh', 'sin','cos'], 'maxsize': 20 } # Define the 'params' dictionary for the post-processing function post_process_params = { 'evals': evals_nn, 'pysr': pysr_settings, 'plot': True, # This will show the plots of the fits 'n_eval': 200, # Generate 200 points for the new evals_sr } # Run the post-processing # This will print the fits and show plots models_sr, evals_sr = pycc.post_processing(eqs, method='SymbR', params=post_process_params) # `models_sr` now contains the symbolic functions # `evals_sr` now contains the smooth curves from those functions # --- 3. Simulate using the new symbolic models --- # Assume 'F_ext_func', 't_eval', 'y0' are defined # Option A: Simulate using the standard 'SymbR' method sim_params = { 'models': models_sr, # Use the new symbolic models 'obtained_coefs': coefs_nn, # Use the scalars from the NN fit 'local_funcs': {'F_ext': F_ext_func}, 't_span': t_span, 'y0': y0, 't_eval': t_eval, } sol, derivs = pycc.simulate(eqs, method='SymbR', params=sim_params) # Option B (Faster): Simulate by interpolating the new symbolic evals sim_params_interp = { 'evals': evals_sr, # Use the new symbolic evals 'obtained_coefs': coefs_nn, # ai coefficients obtained from training method 'local_funcs': {'F_ext': F_ext_func}, 't_span': t_span, 'y0': y0, 't_eval': t_eval, 'interp_method': 'pchip' } sol_interp, derivs_interp = pycc.simulate(eqs, method='Interp', params=sim_params_interp) .. raw:: html