Skip to content

ProGED

SRToolkit.approaches.ProGED

ProGED approach — probabilistic grammar-based equation discovery by Brence et al.

ProGEDConfig dataclass

ProGEDConfig(
    name: str = "ProGED",
    approach_class: str = "",
    grammar: Optional[str] = None,
)

Bases: ApproachConfig

Configuration dataclass for the ProGED approach.

Examples:

>>> cfg = ProGEDConfig()
>>> cfg.name
'ProGED'
>>> d = cfg.to_dict()
>>> ProGEDConfig.from_dict(d).grammar

ProGED

ProGED(grammar: Optional[str] = None)

Bases: SR_approach

A slimmed-down version of ProGED — probabilistic grammar-based equation discovery.

Randomly samples expressions from a probabilistic context-free grammar (PCFG) and evaluates them using the provided evaluator. The full version of the approach is available at https://github.com/brencej/ProGED; see also Brence et al. (2021), https://doi.org/10.1016/j.knosys.2021.107077.

Examples:

>>> from SRToolkit.dataset import Feynman
>>> benchmark = Feynman()
>>> dataset = benchmark.create_dataset('I.16.6')
>>> dataset.max_evaluations = 100
>>> model = ProGED()
>>> model.adapt(dataset.X, dataset.symbol_library) # Since we don't put a custom grammar into ProGED we will need an automatically created PCFG.
>>> results = dataset.evaluate_approach(model, num_experiments=1, initial_seed=18, verbose=False)
>>> r = results[0]
>>> r.dataset_name
'I.16.6'
>>> r.approach_name
'ProGED'
>>> r.best_expr
'C*X_0'
>>> r.num_evaluated
74
>>> bool(r.success)
False

Parameters:

Name Type Description Default
grammar Optional[str]

Grammar used for sampling. Either a SymbolLibrary (grammar is derived automatically) or a custom grammar string.

None
Source code in SRToolkit/approaches/ProGED.py
def __init__(self, grammar: Optional[str] = None) -> None:
    r"""
    A slimmed-down version of ProGED — probabilistic grammar-based equation discovery.

    Randomly samples expressions from a probabilistic context-free grammar (PCFG) and evaluates
    them using the provided evaluator. The full version of the approach is available at
    https://github.com/brencej/ProGED; see also Brence et al. (2021),
    https://doi.org/10.1016/j.knosys.2021.107077.

    Examples:
        >>> from SRToolkit.dataset import Feynman
        >>> benchmark = Feynman()
        >>> dataset = benchmark.create_dataset('I.16.6')
        >>> dataset.max_evaluations = 100
        >>> model = ProGED()
        >>> model.adapt(dataset.X, dataset.symbol_library) # Since we don't put a custom grammar into ProGED we will need an automatically created PCFG.
        >>> results = dataset.evaluate_approach(model, num_experiments=1, initial_seed=18, verbose=False)
        >>> r = results[0]
        >>> r.dataset_name
        'I.16.6'
        >>> r.approach_name
        'ProGED'
        >>> r.best_expr
        'C*X_0'
        >>> r.num_evaluated
        74
        >>> bool(r.success)
        False

    Args:
        grammar: Grammar used for sampling. Either a
            [SymbolLibrary][SRToolkit.utils.symbol_library.SymbolLibrary] (grammar is derived
            automatically) or a custom grammar string.
    """
    grammar_str = grammar if isinstance(grammar, str) else None
    super().__init__(ProGEDConfig(grammar=grammar_str))
    self.grammar: Optional[Union[str, SymbolLibrary]] = grammar

prepare

prepare() -> None

ProGED is stateless — this method does nothing.

Returns:

Type Description
None

None

Source code in SRToolkit/approaches/ProGED.py
def prepare(self) -> None:
    """
    ProGED is stateless — this method does nothing.

    Returns:
        None
    """
    pass

search

search(sr_evaluator: SR_evaluator, seed: Optional[int] = None) -> None

Randomly sample expressions from the grammar and evaluate them until the budget is exhausted or the success threshold is reached.

Parameters:

Name Type Description Default
sr_evaluator SR_evaluator

SR_evaluator used to score candidate expressions.

required
seed Optional[int]

Optional random seed for reproducible sampling.

None

Returns:

Type Description
None

None

Source code in SRToolkit/approaches/ProGED.py
def search(self, sr_evaluator: SR_evaluator, seed: Optional[int] = None) -> None:
    """
    Randomly sample expressions from the grammar and evaluate them until the budget is exhausted
    or the success threshold is reached.

    Args:
        sr_evaluator: [SR_evaluator][SRToolkit.evaluation.sr_evaluator.SR_evaluator] used to
            score candidate expressions.
        seed: Optional random seed for reproducible sampling.

    Returns:
        None
    """
    np.random.seed(seed)
    while not sr_evaluator.should_stop:
        if self.grammar is not None:
            expr = generate_n_expressions(self.grammar, 1, verbose=False)[0]
            _ = sr_evaluator.evaluate_expr(expr)
        else:
            raise RuntimeError("ProGED.search() must be called after adapt() if grammar is not provided.")