Source code for innate.regression.methods

import logging
import re
import numpy as np
from .. import _setup_cfg

_logger = logging.getLogger('Innate')


def generate_specific_function(expression, coefficients, variable_names):
    # Define the function to only vary with specified variables
    def specific_function(*variable_values):
        local_vars = coefficients.copy()  # Copy the dictionary of fixed variables
        # Update variable names with values dynamically from the input
        local_vars.update(dict(zip(variable_names, variable_values)))
        local_vars['np'] = np  # Ensure np is available for np.log10 and other operations
        return eval(expression, {}, local_vars)
    # The number of inputs is now the number of variable names provided
    return np.frompyfunc(specific_function, len(variable_names), 1)


def extract_coef_names(expression):
    # Regex to find isolated letters (considered variables)
    pattern = r'\b[a-zA-Z]\b'
    # Find all matches and return as a set to remove duplicates
    matches = set(re.findall(pattern, expression))
    return sorted(matches)


def create_coef_dict (coef_names, coef_values):
    if len(coef_names)==len(coef_values):
       out = dict(zip(coef_names, coef_values))
    else:
        raise TypeError("length of coefficietns names different from the length of coefficients values")
    return(out)


def extract_variables_names(expression, suffix='_range'):
    # Construct the regex pattern dynamically to find words ending with the given suffix
    pattern = rf'\b\w+{re.escape(suffix)}\b'  # Use re.escape to safely include the suffix in the regex
    # Find all matches and return as a set to remove duplicates
    matches = set(re.findall(pattern, expression))
    return sorted(list(matches))  # Return a sorted list of unique matches


[docs] def parse_string_equation(data_label, str_eqn, coeffs_eqn, variable_names): """ Parse a string equation and its coefficients (as float array) to generate its programatic object using numpy. If the equation or coefficients are not provided, it logs a warning message. Parameters ---------- data_label : str The label for the data set. str_eqn : str or None The string representation of the equation. Can be None. coeffs_eqn : dict or None A dictionary containing the coefficients for the equation. Can be None. variable_names : list of str A list of variable names used in the equation. Returns ------- eqn : function or None The generated specific function based on the equation and coefficients. Returns None if the equation or coefficients are missing. coeffs_dict : dict or None A dictionary of coefficients extracted from `coeffs_eqn`. Returns None if the equation or coefficients are missing. Notes ----- If the `str_eqn` or `coeffs_eqn` is None, a warning message is logged specifying which part is missing from the data set configuration. Examples -------- >>> eqn, coeffs_dict = parse_string_equation("example_data", "a*x + b", {"a": 1, "b": 2}, ["x"]) >>> print(eqn) <function ...> >>> print(coeffs_dict) {'a': 1, 'b': 2} """ if (str_eqn is not None) or (coeffs_eqn is not None): coef_names = extract_coef_names(str_eqn) coeffs_dict = create_coef_dict(coef_names, coeffs_eqn) eqn = generate_specific_function(str_eqn, coeffs_dict, variable_names) else: message = f'Data set "{data_label}" is missing:' if str_eqn is None: message += f'\nParametrisation formula ("eqn" key in dataset configuration).' if coeffs_eqn is None: message += f'\nParametrisation coefficients ("eqn_coeffs" key in dataset configuration).' _logger.warning(message) eqn, coeffs_dict = None, None return eqn, coeffs_dict
class Regressor: def __init__(self, grid, technique_list, data_cfg=None): self.eqn = None self.coeffs = None self.techniques = [] # Constrain to regresion techniques algorithms = list(set(_setup_cfg['parameter_labels']['reg'].keys()) & set(technique_list)) # Regular grid Interpolation if 'eqn' in algorithms: self.techniques.append('eqn') # Reconstruct the string equation into a python function self.eqn, self.coeffs = parse_string_equation(grid.label, data_cfg.get('eqn', None), data_cfg.get('eqn_coeffs', None), data_cfg.get('axes', None)) return