API Reference#
This page collects the public nd2py API in one searchable document. Use the right-hand table of contents, the global search box, or your browser’s page search to find an object or option.
Symbolic engine#
Symbol user API#
The following methods are available on every concrete Symbol, including
Variable, Number, operators, and complete expressions.
- class nd2py.core.symbols.symbol.Symbol(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
NetTypeMixin,TreeMixin,SymbolAPIMixin- __init__(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Initialize a Symbol node.
This constructor sets the nettype, sanitizes and attaches child operands, and then triggers a nettype inference pass on the whole expression tree.
- Parameters:
*operands – Child operands of this symbol. The number of operands must match
n_operandsof the concrete subclass. Non-symbol scalar values are automatically wrapped asNumbersymbols.nettype (Optional[NetType | Set[NetType]]) – Nettype constraint for this symbol, such as
"node","edge", or"scalar", or a set of allowed nettypes. If provided, it is propagated through the tree byinfer_nettype().
Examples
Concrete symbols are normally composed through the public operator classes and Python operators:
>>> import nd2py as nd >>> x = nd.Variable("x") >>> expression = nd.sin(x) + 1 >>> float(expression.eval({"x": 0.0})) 1.0
- copy()[source]#
Return a deep copy of this symbol.
The copied symbol has the same tree structure and values as the original but does not share
parentlinks, so it can be safely inserted into a different expression tree.- Returns:
A deep copy of the current symbol.
- Return type:
- get_numbers(fitable_only: bool = False, float_only: bool = False, scalar_only: bool = False) List[Number][source]#
Collect all
Numbernodes contained in this symbol.Traverses the expression tree in preorder and returns all numeric nodes that satisfy the given filters.
- Parameters:
fitable_only (bool, optional) – If True, return only numbers marked as fitable (trainable) parameters. Defaults to False.
float_only (bool, optional) – If True, exclude integer-like values (for example exponents that should remain fixed). Defaults to False.
scalar_only (bool, optional) – If True, only consider scalar numbers (nettype
"scalar"). Defaults to False.
- Returns:
List of numeric symbol nodes that match the filters.
- Return type:
List[Number]
- get_parameters(fitable_only: bool = False, float_only: bool = False) List[float][source]#
Return numeric parameter values contained in this symbol.
This is a convenience wrapper over
get_numbers()that extracts the underlying scalar values fromNumbernodes.- Parameters:
fitable_only (bool, optional) – If True, return only parameters associated with fitable numbers. Defaults to False.
float_only (bool, optional) – If True, exclude integer-like parameters. Defaults to False.
- Returns:
Flat list of parameter values in traversal order.
- Return type:
List[float]
- set_parameters(params: List[float], fitable_only: bool = False, float_only: bool = False)[source]#
Assign new numeric parameter values to this symbol.
The values in
paramsare consumed in the same order as produced byget_parameters()with the same filter options.- Parameters:
params (List[float]) – New parameter values to assign.
fitable_only (bool, optional) – If True, only update fitable parameters and leave others unchanged. Defaults to False.
float_only (bool, optional) – If True, only update non-integer parameters. Defaults to False.
- Raises:
ValueError – If the length of
paramsdoes not match the number of parameters selected by the filters.
- classmethod map_nettype(*children_nettypes: Literal['node', 'edge', 'scalar']) Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
- eval(vars: dict = {}, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, use_eps: float = 0.0, return_exceptions: bool = False)#
Evaluate the expression numerically using NumPy.
- Parameters:
vars (dict, optional) – Mapping from variable names to their numerical values. Values can be scalars or
numpy.ndarrayobjects. Defaults to an empty dictionary.edge_list (Tuple[List[int], List[int]], optional) – Pair of integer lists
(sources, targets)describing directed edges in a graph. Node indices start from 0. If provided, this is used to parameterise graph-related symbols.num_nodes (int, optional) – Number of nodes in the underlying graph. If omitted, it may be inferred from
edge_listwhen possible.use_eps (float, optional) – Small positive value added in denominators or other potentially unstable operations to avoid division by zero and improve numerical stability. Defaults to 0.0.
return_exceptions (bool, optional) – If True, also return a list of diagnostics describing non-finite values produced by each subexpression. Defaults to False.
- Returns:
Numerical evaluation result of the expression, whose shape depends on the symbol and inputs. Or a
(result, exceptions)tuple whenreturn_exceptionsis True.- Return type:
numpy.ndarray | float | tuple
Examples
>>> import numpy as np >>> import nd2py as nd >>> x = nd.Variable("x") >>> (x ** 2 + 1).eval({"x": np.array([1.0, 2.0])}) array([2., 5.])
- eval_eic(vars: dict = {}, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, use_eps: float = 0.0, perturbation: float = 1e-06, return_exceptions: bool = False, exception_threshold: float = 1.0)#
Estimate the number of effective decimal digits lost during evaluation.
- Parameters:
vars – Mapping from variable names to sampled values.
edge_list – Optional graph edge sources and targets.
num_nodes – Optional number of graph nodes.
use_eps – Stabilising value used by protected operations.
perturbation – Relative central-difference step for operators whose derivatives are not implemented analytically.
return_exceptions – If True, return
(eic, exceptions).exception_threshold – Minimum estimated local digit loss reported as an anomalous structure.
- Returns:
Estimated decimal digits lost, optionally paired with diagnostics identifying anomalous subexpressions.
- Return type:
float | tuple
Examples
>>> import numpy as np >>> import nd2py as nd >>> x = nd.Variable("x") >>> eic, exceptions = (x - x).eval_eic( ... {"x": np.array([1.0, 2.0])}, ... return_exceptions=True, ... ) >>> bool(np.isinf(eic)) True >>> "x - x" in exceptions[0] True
- eval_torch(vars: dict = {}, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, use_eps: float = 0.0, device: str = 'cpu')#
Evaluate the expression numerically using PyTorch.
- Parameters:
vars (dict, optional) – Mapping from variable names to their numerical values. Values can be scalars or
torch.Tensorobjects. Defaults to an empty dictionary.edge_list (Tuple[List[int], List[int]], optional) – Pair of integer lists
(sources, targets)describing directed edges in a graph. Node indices start from 0. If provided, this is used to parameterise graph-related symbols.num_nodes (int, optional) – Number of nodes in the underlying graph. If omitted, it may be inferred from
edge_listwhen possible.use_eps (float, optional) – Small positive value added in denominators or other potentially unstable operations to avoid division by zero and improve numerical stability. Defaults to 0.0.
device (str, optional) – Target device on which tensors are allocated and computations are performed, such as
"cpu"or"cuda". Defaults to"cpu".
- Returns:
Numerical evaluation result of the expression.
- Return type:
torch.Tensor
Examples
>>> import torch >>> import nd2py as nd >>> x = nd.Variable("x") >>> (x + 1).eval_torch({"x": torch.tensor([1.0, 2.0])}) tensor([2., 3.])
- fix_nettype(nettype: NetType = 'node', direction: Literal['bottom-up', 'top-down'] = 'top-down', edge_to_node=['remove_targ', 'remove_sour', 'add_aggr', 'add_rgga'], node_to_edge=['remove_aggr', 'remove_rgga', 'add_targ', 'add_sour'], edge_to_scalar=['remove_sour', 'remove_targ', 'add_readout'], node_to_scalar=['remove_aggr', 'remove_rgga', 'add_readout'], scalar_to_node=['keep'], scalar_to_edge=['keep'])#
Normalize nettypes of all symbols in the expression.
This is useful in GP or LLM-based symbolic regression where equations are generated automatically and may contain inconsistent nettype annotations.
- Parameters:
nettype (NetType, optional) – Target nettype of the root symbol. Typical values include
"node","edge"and"scalar". Defaults to"node".direction (Literal["bottom-up", "top-down"], optional) – Direction in which the fix is propagated through the expression tree. Defaults to
"top-down".edge_to_node (List[str], optional) – Sequence of transformation rules applied when converting edge symbols to node symbols.
node_to_edge (List[str], optional) – Sequence of transformation rules applied when converting node symbols to edge symbols.
edge_to_scalar (List[str], optional) – Sequence of transformation rules applied when converting edge symbols to scalar symbols.
node_to_scalar (List[str], optional) – Sequence of transformation rules applied when converting node symbols to scalar symbols.
scalar_to_node (List[str], optional) – Sequence of transformation rules applied when converting scalar symbols to node symbols.
scalar_to_edge (List[str], optional) – Sequence of transformation rules applied when converting scalar symbols to edge symbols.
- Returns:
Root symbol of the expression with consistent nettypes.
- Return type:
Examples
>>> import nd2py as nd >>> x = nd.Variable("x", nettype="node") >>> fixed = x.fix_nettype("node") >>> fixed.nettype 'node'
- classmethod get_nettype_range() Set[Literal['node', 'edge', 'scalar']]#
Compute and cache the full nettype range for this operator class.
The nettype range is the set of all possible result nettypes that can be produced by this operator, over all combinations of valid child nettypes. The result is cached on the class to avoid recomputation.
- Returns:
Set of all nettypes that this operator can yield.
- Return type:
Set[NetType]
- infer_nettype()#
Infer possible nettypes for the entire expression tree.
This method uses the currently assigned nettype constraints as anchors and propagates them through the symbol tree to update
_possible_nettypesof all involved symbols.
- iter_postorder()#
Postorder traversal of the Symbol tree.
- iter_preorder()#
Non-recursive preorder traversal of the Symbol tree using an explicit stack.
- match(pattern: Symbol) Dict[str, Symbol] | None#
Match a pattern expression against self expression.
This function checks if the pattern can match the self expression by comparing their tree structures. Variables in the pattern can match any subexpression. The same variable name must match the same subexpression throughout the pattern.
- Parameters:
pattern – The pattern expression containing variables to be matched.
- Returns:
A dictionary mapping variable names from the pattern to their matched subexpressions, or None if the pattern does not match.
Examples
>>> from nd2py import Variable, sin, Add, Mul >>> from nd2py.core.tree import match >>> a = Variable('a') >>> x = Variable('x')
>>> # sin(a) matches sin(x*2+1) >>> f = sin(x*2+1) >>> f.match(sin(a)) {'a': x + 2*x}
>>> # a+a matches sin(x)+sin(x) (same variable must match same subexpression) >>> f = sin(x) + sin(x) >>> f.match(a+a) {'a': sin(x)}
>>> # a+a does NOT match sin(x)+cos(x) (different subexpressions) >>> f = sin(x) + cos(x) >>> f.match(a+a) None
>>> # a+b matches both sin(x)+sin(x) and sin(x)+cos(x) >>> f = sin(x) + sin(x) >>> f.match(a+b) {'a': sin(x), 'b': sin(x)}
- property nettype: Literal['node', 'edge', 'scalar'] | None#
Return the resolved nettype if unique.
When the candidate set contains exactly one element, this property returns that nettype. Otherwise it returns
Noneto indicate that the nettype is still ambiguous.- Returns:
Unique nettype if determined, otherwise
None.- Return type:
Optional[NetType]
- property possible_nettypes: Set[Literal['node', 'edge', 'scalar']]#
Return the set of possible nettypes for this object.
- Returns:
Current candidate nettypes that are consistent with all known constraints.
- Return type:
Set[NetType]
- replace(child: Symbol, other: Symbol, no_warn=False)#
Replace current expression (or subexpression denoted by child) with another expression.
- simplify(transform_constant_subtree: bool = True, remove_useless_readout: bool = True, remove_nested_sin: bool = False, remove_nested_cos: bool = False, remove_nested_tanh: bool = False, remove_nested_sigmoid: bool = False, remove_nested_sqrt: bool = False, remove_nested_sqrtabs: bool = False, remove_nested_exp: bool = False, remove_nested_log: bool = False, remove_nested_logabs: bool = False)#
Apply algebraic simplifications to the expression.
Each flag controls whether a specific family of simplification rules is enabled. By default constant subtrees are folded and useless readout nodes are removed.
- Parameters:
transform_constant_subtree (bool, optional) – If True, evaluate and replace constant-only subtrees with their numerical result. Defaults to True.
remove_useless_readout (bool, optional) – If True, eliminate redundant
Readoutnodes that do not affect the result. Defaults to True.remove_nested_sin (bool, optional) – If True, simplify expressions containing nested sine functions when possible. Defaults to False.
remove_nested_cos (bool, optional) – If True, simplify expressions containing nested cosine functions when possible. Defaults to False.
remove_nested_tanh (bool, optional) – If True, simplify expressions containing nested hyperbolic tangent functions when possible. Defaults to False.
remove_nested_sigmoid (bool, optional) – If True, simplify expressions containing nested sigmoid functions when possible. Defaults to False.
remove_nested_sqrt (bool, optional) – If True, simplify nested square root expressions when possible. Defaults to False.
remove_nested_sqrtabs (bool, optional) – If True, simplify nested
sqrtabs-like expressions when possible. Defaults to False.remove_nested_exp (bool, optional) – If True, simplify nested exponential expressions when possible. Defaults to False.
remove_nested_log (bool, optional) – If True, simplify nested logarithm expressions when possible. Defaults to False.
remove_nested_logabs (bool, optional) – If True, simplify nested
logabs-like expressions when possible. Defaults to False.
- Returns:
A simplified version of the original symbol expression.
- Return type:
Examples
>>> import nd2py as nd >>> x = nd.Variable("x") >>> (x + 0).simplify().to_str() 'x'
- split_by_add(split_by_sub: bool = False, expand_mul: bool = False, expand_div: bool = False, expand_aggr: bool = False, expand_rgga: bool = False, expand_sour: bool = False, expand_targ: bool = False, expand_readout: bool = False, remove_coefficients: bool = False, merge_bias: bool = False) List['Symbol']#
Split an additive expression into its additive terms.
The current symbol is treated as the root. Depending on the flags, this can also expand multiplication, division, aggregation and readout nodes before splitting.
- Parameters:
split_by_sub (bool, optional) – If True, treat subtraction nodes as additions when splitting, so that
a - bbecomes[a, -b]. Defaults to False.expand_mul (bool, optional) – If True, expand
Mulnodes before splitting. Defaults to False.expand_div (bool, optional) – If True, expand
Divnodes before splitting. Defaults to False.expand_aggr (bool, optional) – If True, expand aggregation nodes (for example graph aggregators) before splitting. Defaults to False.
expand_rgga (bool, optional) – If True, expand RGGA-related nodes before splitting. Defaults to False.
expand_sour (bool, optional) – If True, expand source-related transformations before splitting. Defaults to False.
expand_targ (bool, optional) – If True, expand target-related transformations before splitting. Defaults to False.
expand_readout (bool, optional) – If True, push
Readoutinside additions, so that for exampleReadout(a + b)becomes[Readout(a), Readout(b)]. Defaults to False.remove_coefficients (bool, optional) – If True, drop scalar coefficients from the resulting symbols. Defaults to False.
merge_bias (bool, optional) – If True, merge additive bias terms into neighbouring symbols when appropriate. Defaults to False.
- Returns:
List of symbols corresponding to each additive term.
- Return type:
List[Symbol]
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> [term.to_str() for term in (x + y + 1).split_by_add()] ['x', 'y', '1']
- split_by_mul(split_by_div: bool = False, merge_coefficients: bool = False) List['Symbol']#
Split a multiplicative expression into its multiplicative factors.
The current symbol is treated as the root. Depending on the flags, this can also split divisions and optionally merge coefficients.
- Parameters:
split_by_div (bool, optional) – If True, split divisions so that an expression like
a / bis treated as having factors[a, b]. Defaults to False.merge_coefficients (bool, optional) – If True, merge scalar coefficients into a single factor instead of returning them as separate symbols. Defaults to False.
- Returns:
List of symbols corresponding to each multiplicative factor.
- Return type:
List[Symbol]
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> [factor.to_str() for factor in (2 * x * y).split_by_mul()] ['2', 'x', 'y']
- to_str(raw=False, latex=False, number_format='', omit_mul_sign=False, skeleton=False, grouped_parameter_symbol='alpha') str#
Return a string representation of the symbol expression.
This is a thin wrapper around
StringPrinterand can produce raw, LaTeX, or skeleton forms of the expression.- Parameters:
raw (bool, optional) – If True, return the internal raw representation instead of a prettified one. Defaults to False.
latex (bool, optional) – If True, format the expression as LaTeX. Defaults to False.
number_format (str, optional) – Format specifier used to print numeric constants (for example
"0.2f"). Defaults to an empty string, which uses the default formatting.omit_mul_sign (bool, optional) – If True, omit explicit multiplication signs (for example render
abinstead ofa*b). Defaults to False.skeleton (bool, optional) – If True, ignore concrete numeric values and keep only the symbolic structure of the expression. Defaults to False.
- Returns:
String representation of the symbol expression.
- Return type:
str
Examples
>>> import nd2py as nd >>> x = nd.Variable("x") >>> (2 * x + 1).to_str() '2 * x + 1' >>> (2 * x + 1).to_str(latex=True) '2 \\times x + 1'
- to_tree(number_format='', flat=False, skeleton=False) str#
Return an ASCII tree representation of the expression.
- Parameters:
number_format (str, optional) – Format specifier used to print numeric constants (for example
"0.2f"). Defaults to an empty string, which uses the default formatting.flat (bool, optional) – If True, flatten nested
AddandMulnodes into a single level. Defaults to False.skeleton (bool, optional) – If True, ignore concrete numeric values and keep only the symbolic structure of the expression. Defaults to False.
- Returns:
Multi-line string visualising the expression tree.
- Return type:
str
Examples
>>> import nd2py as nd >>> x = nd.Variable("x") >>> print((nd.sin(x) + 1).to_tree()) Add (scalar) ├ Sin (scalar) ┆ └ x (scalar) └ 1 (scalar)
Submodules#
nd2py.core.symbols.empty module#
- class nd2py.core.symbols.empty.Empty(nettype: Literal['node', 'edge', 'scalar'] | None = None)[source]#
Bases:
Symbol- n_operands = 0#
- __init__(nettype: Literal['node', 'edge', 'scalar'] | None = None)[source]#
Initialize a Symbol node.
This constructor sets the nettype, sanitizes and attaches child operands, and then triggers a nettype inference pass on the whole expression tree.
- Parameters:
*operands – Child operands of this symbol. The number of operands must match
n_operandsof the concrete subclass. Non-symbol scalar values are automatically wrapped asNumbersymbols.nettype (Optional[NetType | Set[NetType]]) – Nettype constraint for this symbol, such as
"node","edge", or"scalar", or a set of allowed nettypes. If provided, it is propagated through the tree byinfer_nettype().
Examples
Concrete symbols are normally composed through the public operator classes and Python operators:
>>> import nd2py as nd >>> x = nd.Variable("x") >>> expression = nd.sin(x) + 1 >>> float(expression.eval({"x": 0.0})) 1.0
- map_nettype() Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
nd2py.core.symbols.functions module#
- nd2py.core.symbols.functions.sum(*operands)[source]#
Combine operands into an additive expression.
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> nd.sum(x, y, 1).to_str() 'x + y + 1'
- nd2py.core.symbols.functions.prod(*operands)[source]#
Combine operands into a multiplicative expression.
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> nd.prod(2, x, y).to_str() '2 * x * y'
- nd2py.core.symbols.functions.maximum(*operands)[source]#
Return the elementwise maximum of all operands.
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> float(nd.maximum(x, y).eval({"x": 1.0, "y": 2.0})) 2.0
- nd2py.core.symbols.functions.minimum(*operands)[source]#
Return the elementwise minimum of all operands.
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> float(nd.minimum(x, y).eval({"x": 1.0, "y": 2.0})) 1.0
- nd2py.core.symbols.functions.Constant(value, nettype: Literal['node', 'edge', 'scalar'] = 'scalar') Number[source]#
Create a fixed numerical constant.
- Parameters:
value – Numerical value of the constant.
nettype – Network type of the constant. Defaults to
"scalar".
Examples
>>> import nd2py as nd >>> constant = nd.Constant(2.0) >>> constant.fitable False
- nd2py.core.symbols.functions.variables(vars, *args, **kwargs)[source]#
Create one variable or a list of space-separated variables.
- Parameters:
vars – One variable name or several names separated by spaces.
*args – Additional positional arguments passed to
Variable.**kwargs – Additional keyword arguments passed to
Variable.
Examples
>>> import nd2py as nd >>> x, y = nd.variables("x y") >>> x.name, y.name ('x', 'y')
nd2py.core.symbols.number module#
- class nd2py.core.symbols.number.Number(value, nettype: Literal['node', 'edge', 'scalar'] = 'scalar', fitable=None)[source]#
Bases:
Symbol- n_operands = 0#
- __init__(value, nettype: Literal['node', 'edge', 'scalar'] = 'scalar', fitable=None)[source]#
Create a numerical parameter.
- Parameters:
value – Scalar or array-like numerical value.
nettype – Network type of the parameter. Defaults to
"scalar".fitable – Whether fitting algorithms may optimize the value. If omitted, the current fitable context is used.
Examples
>>> import nd2py as nd >>> coefficient = nd.Number(2.0) >>> x = nd.Variable("x") >>> float((coefficient * x).eval({"x": 3.0})) 6.0
- map_nettype() Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
- get_nettype_range() Set[Literal['node', 'edge', 'scalar']][source]#
获取此节点可能产生的所有 nettype 值域,并在首次调用时缓存到类属性中。
- property nettype_range: Set[Literal['node', 'edge', 'scalar']]#
获取此节点可能产生的所有 nettype 值域,并在首次调用时缓存到类属性中。
nd2py.core.symbols.grouped_parameter module#
- class nd2py.core.symbols.grouped_parameter.GroupedParameter(*operands, value: Dict[Any, float] | None = None, default: float | None = None, fitable: bool = True, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- __init__(*operands, value: Dict[Any, float] | None = None, default: float | None = None, fitable: bool = True, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Create a fitable parameter lookup indexed by a categorical variable.
Each distinct value of the Variable operand selects one scalar entry of
value. Labels not present invalueare added on first evaluation and initialized withdefault.- Parameters:
*operands – Exactly one categorical
Variableused to select parameter values.value – Optional initial mapping from category labels to numerical parameter values. Mapping order is preserved.
default – Value assigned to a previously unseen label.
Noneis interpreted as0.0.fitable – Whether
BFGSFitmay optimize the values.nettype – Optional network-type constraint. By default, the result follows the Variable operand.
Examples
>>> import numpy as np >>> import nd2py as nd >>> s = nd.Variable("s") >>> parameter = nd.GroupedParameter(s, default=1.0) >>> parameter.eval({"s": np.array(["a", "b", "a"])}) array([1., 1., 1.]) >>> parameter.value_dict {'a': 1.0, 'b': 1.0}
- bind(labels) None[source]#
Add previously unseen labels initialized with
default.Labels are appended in first-seen order. Existing labels and parameter values are left unchanged.
- Parameters:
labels – Scalar or array-like categorical labels.
- property value_dict#
Return the current label-to-parameter mapping.
nd2py.core.symbols.operands module#
- class nd2py.core.symbols.operands.Add(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Sub(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Mul(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Div(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Pow(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Max(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Min(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Identity(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Sin(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Cos(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Tan(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Sec(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Csc(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Cot(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Arcsin(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Arccos(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Arctan(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Log(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.LogAbs(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Exp(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Abs(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Neg(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Inv(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Sqrt(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.SqrtAbs(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Pow2(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Pow3(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Sinh(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Cosh(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Tanh(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Coth(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Sech(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Csch(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Sigmoid(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- class nd2py.core.symbols.operands.Regular(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 2#
- class nd2py.core.symbols.operands.Sour(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- classmethod map_nettype(*children_nettypes: Literal['node', 'edge', 'scalar']) Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
- class nd2py.core.symbols.operands.Targ(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Sour
- class nd2py.core.symbols.operands.Aggr(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- classmethod map_nettype(*children_nettypes: Literal['node', 'edge', 'scalar']) Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
- class nd2py.core.symbols.operands.Rgga(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Aggr
- class nd2py.core.symbols.operands.Readout(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]#
Bases:
Symbol- n_operands = 1#
- classmethod map_nettype(*children_nettypes: Literal['node', 'edge', 'scalar']) Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
nd2py.core.symbols.symbol module#
- class nd2py.core.symbols.symbol.Symbol(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]
Bases:
NetTypeMixin,TreeMixin,SymbolAPIMixin- __init__(*operands, nettype: Literal['node', 'edge', 'scalar'] | Set[Literal['node', 'edge', 'scalar']] | None = None)[source]
Initialize a Symbol node.
This constructor sets the nettype, sanitizes and attaches child operands, and then triggers a nettype inference pass on the whole expression tree.
- Parameters:
*operands – Child operands of this symbol. The number of operands must match
n_operandsof the concrete subclass. Non-symbol scalar values are automatically wrapped asNumbersymbols.nettype (Optional[NetType | Set[NetType]]) – Nettype constraint for this symbol, such as
"node","edge", or"scalar", or a set of allowed nettypes. If provided, it is propagated through the tree byinfer_nettype().
Examples
Concrete symbols are normally composed through the public operator classes and Python operators:
>>> import nd2py as nd >>> x = nd.Variable("x") >>> expression = nd.sin(x) + 1 >>> float(expression.eval({"x": 0.0})) 1.0
- copy()[source]
Return a deep copy of this symbol.
The copied symbol has the same tree structure and values as the original but does not share
parentlinks, so it can be safely inserted into a different expression tree.- Returns:
A deep copy of the current symbol.
- Return type:
- get_numbers(fitable_only: bool = False, float_only: bool = False, scalar_only: bool = False) List[Number][source]
Collect all
Numbernodes contained in this symbol.Traverses the expression tree in preorder and returns all numeric nodes that satisfy the given filters.
- Parameters:
fitable_only (bool, optional) – If True, return only numbers marked as fitable (trainable) parameters. Defaults to False.
float_only (bool, optional) – If True, exclude integer-like values (for example exponents that should remain fixed). Defaults to False.
scalar_only (bool, optional) – If True, only consider scalar numbers (nettype
"scalar"). Defaults to False.
- Returns:
List of numeric symbol nodes that match the filters.
- Return type:
List[Number]
- get_parameters(fitable_only: bool = False, float_only: bool = False) List[float][source]
Return numeric parameter values contained in this symbol.
This is a convenience wrapper over
get_numbers()that extracts the underlying scalar values fromNumbernodes.- Parameters:
fitable_only (bool, optional) – If True, return only parameters associated with fitable numbers. Defaults to False.
float_only (bool, optional) – If True, exclude integer-like parameters. Defaults to False.
- Returns:
Flat list of parameter values in traversal order.
- Return type:
List[float]
- set_parameters(params: List[float], fitable_only: bool = False, float_only: bool = False)[source]
Assign new numeric parameter values to this symbol.
The values in
paramsare consumed in the same order as produced byget_parameters()with the same filter options.- Parameters:
params (List[float]) – New parameter values to assign.
fitable_only (bool, optional) – If True, only update fitable parameters and leave others unchanged. Defaults to False.
float_only (bool, optional) – If True, only update non-integer parameters. Defaults to False.
- Raises:
ValueError – If the length of
paramsdoes not match the number of parameters selected by the filters.
- classmethod map_nettype(*children_nettypes: Literal['node', 'edge', 'scalar']) Literal['node', 'edge', 'scalar'] | None[source]
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
nd2py.core.symbols.variable module#
- class nd2py.core.symbols.variable.Variable(name, nettype: Literal['node', 'edge', 'scalar'] = 'scalar')[source]#
Bases:
Symbol- n_operands = 0#
- __init__(name, nettype: Literal['node', 'edge', 'scalar'] = 'scalar')[source]#
Create a named input variable.
- Parameters:
name – Key used to look up the variable in evaluation data.
nettype – Network type of the variable. Defaults to
"scalar".
Examples
>>> import nd2py as nd >>> x = nd.Variable("x") >>> float(x.eval({"x": 2.0})) 2.0
- map_nettype() Literal['node', 'edge', 'scalar'] | None[source]#
Default nettype mapping rule for symbol subclasses.
The default behavior enforces that
"node"and"edge"nettypes cannot be mixed. If only scalars are present, the result is"scalar"; otherwise it follows the presence of"node"or"edge".- Parameters:
*children_nettypes (NetType) – Nettypes of the child operands.
- Returns:
Inferred nettype for the parent symbol, or
Noneif the combination is invalid or cannot be determined.- Return type:
Optional[NetType]
- Raises:
ValueError – If the number of child nettypes does not match
cls.n_operands.
- get_nettype_range() Set[Literal['node', 'edge', 'scalar']][source]#
获取此节点可能产生的所有 nettype 值域,并在首次调用时缓存到类属性中。
- property nettype_range: Set[Literal['node', 'edge', 'scalar']]#
获取此节点可能产生的所有 nettype 值域,并在首次调用时缓存到类属性中。
The implementation of basic functionality of Symbol as an object, including: - GetCopy: Deep copy a Symbol tree. - GetLength: Count the number of nodes in a Symbol tree.
Submodules#
nd2py.core.basic.get_copy module#
nd2py.core.basic.get_length module#
Submodules#
nd2py.core.calc.eic_calc module#
- class nd2py.core.calc.eic_calc.EICCalc[source]#
Bases:
VisitorEstimate the number of effective decimal digits lost by a symbol tree.
This implements the diagnostic described in Beyond Accuracy and Complexity: The Effective Information Criterion for Structurally Stable Symbolic Regression.
The estimate recursively measures how much each subexpression amplifies relative input errors. Analytic derivatives are used for common element-wise operators. Other operators are evaluated by
NumpyCalcand differentiated with a central finite difference ingeneric_visit().
nd2py.core.calc.numpy_calc module#
- class nd2py.core.calc.numpy_calc.NumpyCalc[source]#
Bases:
Visitor- visit_GroupedParameter(node: GroupedParameter, *args, **kwargs)[source]#
nd2py.core.calc.torch_calc module#
- nd2py.core.calc.torch_calc.unpack_operands(mask_out_nan=False, double_check_nan=False, fill_nan_input=1.0, fill_nan_output=torch.nan)[source]#
Decorator to unpack operands of a node and apply a function to them. :param mask_out_nan: whether to replace NaN values in the input with fill_nan_input :param double_check_nan: whether to calculate the output for invalid inputs. Set to True can lead to performance degradation, but helps with operations like Div and Inv which map Non-nan to nan. :param fill_nan_input: value to replace NaN values in the input This can be any value as long as ‘func’ does not map it to nan. :param fill_nan_output: value to replace NaN values in the output
- class nd2py.core.calc.torch_calc.TorchCalc[source]#
Bases:
Visitor- visit_GroupedParameter(node: GroupedParameter, *args, **kwargs)[source]#
Submodules#
nd2py.core.transform.bfgs_fit module#
- class nd2py.core.transform.bfgs_fit.BFGSFit(*args: Any, **kwargs: Any)[source]#
Bases:
BaseEstimator,RegressorMixinFit numerical parameters in a symbolic expression with SciPy.
- Parameters:
expression – Expression containing fitable
NumberorGroupedParameternodes.edge_list – Optional graph edge list used during evaluation.
num_nodes – Optional number of graph nodes.
use_eps – Numerical-stability epsilon used during evaluation.
method – Optimization method passed to
scipy.optimize.minimize.tol – Termination tolerance passed to the optimizer.
options – Optional optimizer-specific settings.
fold_constant – Whether to fold constant subtrees before fitting.
Examples
>>> import numpy as np >>> import nd2py as nd >>> x = nd.Variable("x") >>> coefficient = nd.Number(1.0) >>> fit = nd.BFGSFit(coefficient * x).fit( ... {"x": np.array([1.0, 2.0, 3.0])}, ... np.array([2.0, 4.0, 6.0]), ... ) >>> np.allclose(fit.predict({"x": np.array([4.0])}), [8.0]) True
nd2py.core.transform.fix_nettype module#
- class nd2py.core.transform.fix_nettype.FixNetType[source]#
Bases:
Visitor- generic_visit(node, *args, **kwargs) _Type[source]#
direction = ‘top-down’: 每个 node 的 nettype 由 kwargs[‘nettype’] 决定。 direction = ‘bottom-up’: 每个 node 的 nettype 由其 operands 决定。只保证每个 node 运算不会出错即可,不需要对 kwargs[‘nettype’] 负责
- visit_Add(node, *args, **kwargs) _Type#
- visit_Sub(node, *args, **kwargs) _Type#
- visit_Mul(node, *args, **kwargs) _Type#
- visit_Div(node, *args, **kwargs) _Type#
- visit_Pow(node, *args, **kwargs) _Type#
- visit_Max(node, *args, **kwargs) _Type#
- visit_Min(node, *args, **kwargs) _Type#
- visit_Rgga(node, *args, **kwargs) _Type#
- visit_Targ(node, *args, **kwargs) _Type#
nd2py.core.transform.fold_constant module#
nd2py.core.transform.simplify module#
nd2py.core.transform.split_by_add module#
nd2py.core.transform.split_by_mul module#
Submodules#
nd2py.core.tree.iter_postorder module#
nd2py.core.tree.iter_preorder module#
nd2py.core.tree.tree_mixin module#
- class nd2py.core.tree.tree_mixin.TreeMixin[source]#
Bases:
objectProvide structural operations for a Symbol expression tree.
The host class supplies
n_operands,parent, andoperands. TreeMixin then provides root discovery, iterative preorder and postorder traversal, path lookup, replacement, and structural matching.Notes
nd2py expressions are trees with one parent per non-root Symbol. A child already owned by another parent is copied when inserted into a new expression.
- n_operands: int#
- parent: 'Symbol' | None#
- operands: List['Symbol']#
- property root#
- iter_preorder()[source]#
Non-recursive preorder traversal of the Symbol tree using an explicit stack.
- replace(child: Symbol, other: Symbol, no_warn=False)[source]#
Replace current expression (or subexpression denoted by child) with another expression.
- match(pattern: Symbol) Dict[str, Symbol] | None[source]#
Match a pattern expression against self expression.
This function checks if the pattern can match the self expression by comparing their tree structures. Variables in the pattern can match any subexpression. The same variable name must match the same subexpression throughout the pattern.
- Parameters:
pattern – The pattern expression containing variables to be matched.
- Returns:
A dictionary mapping variable names from the pattern to their matched subexpressions, or None if the pattern does not match.
Examples
>>> from nd2py import Variable, sin, Add, Mul >>> from nd2py.core.tree import match >>> a = Variable('a') >>> x = Variable('x')
>>> # sin(a) matches sin(x*2+1) >>> f = sin(x*2+1) >>> f.match(sin(a)) {'a': x + 2*x}
>>> # a+a matches sin(x)+sin(x) (same variable must match same subexpression) >>> f = sin(x) + sin(x) >>> f.match(a+a) {'a': sin(x)}
>>> # a+a does NOT match sin(x)+cos(x) (different subexpressions) >>> f = sin(x) + cos(x) >>> f.match(a+a) None
>>> # a+b matches both sin(x)+sin(x) and sin(x)+cos(x) >>> f = sin(x) + sin(x) >>> f.match(a+b) {'a': sin(x), 'b': sin(x)}
Submodules#
nd2py.core.nettype.inter_nettype module#
nd2py.core.nettype.nettype_mixin module#
- class nd2py.core.nettype.nettype_mixin.NetTypeMixin(nettype: Literal['node', 'edge', 'scalar'] | None = None)[source]#
Bases:
ABCMixin that manages nettype candidates and constraint propagation.
Symbols can carry a network type (nettype) describing their role in a computational graph, such as
"node","edge"or"scalar". This mixin tracks:User-assigned nettype anchors (hard constraints).
The set of possible nettypes each symbol can take.
Propagation of constraints across the expression tree.
The host class (typically
Symbol) is expected to provide:self.parent: Reference to the parent symbol in the tree.self.operands: List of child symbols.self.map_nettype(*children_nettypes: NetType) -> Optional[NetType]: Class method that maps child nettypes to a result nettype for the operator.
- abstractmethod classmethod map_nettype(*children_nettypes: Literal['node', 'edge', 'scalar']) Literal['node', 'edge', 'scalar'] | None[source]#
Map child nettypes to the operator’s resulting nettype.
This method defines the nettype semantics of a symbol class. Concrete subclasses must implement their own mapping logic.
- Parameters:
*children_nettypes (NetType) – Nettypes of each operand, in order.
- Returns:
Inferred nettype of the operator, or
Noneif the combination is invalid or cannot be resolved.- Return type:
Optional[NetType]
- __init__(nettype: Literal['node', 'edge', 'scalar'] | None = None)[source]#
Initialize nettype state for a symbol-like object.
The initial nettype can be provided as a single value or a set of allowed values. When specified, it acts as a hard constraint (anchor) that guides later nettype inference.
- Parameters:
nettype (Optional[NetType | Set[NetType]]) – Initial nettype constraint. If a string in
ALL_NETTYPES, it is converted to a singleton set; ifNone, all nettypes are initially allowed.
- property possible_nettypes: Set[Literal['node', 'edge', 'scalar']]#
Return the set of possible nettypes for this object.
- Returns:
Current candidate nettypes that are consistent with all known constraints.
- Return type:
Set[NetType]
- property nettype: Literal['node', 'edge', 'scalar'] | None#
Return the resolved nettype if unique.
When the candidate set contains exactly one element, this property returns that nettype. Otherwise it returns
Noneto indicate that the nettype is still ambiguous.- Returns:
Unique nettype if determined, otherwise
None.- Return type:
Optional[NetType]
- infer_nettype()[source]#
Infer possible nettypes for the entire expression tree.
This method uses the currently assigned nettype constraints as anchors and propagates them through the symbol tree to update
_possible_nettypesof all involved symbols.
- classmethod get_nettype_range() Set[Literal['node', 'edge', 'scalar']][source]#
Compute and cache the full nettype range for this operator class.
The nettype range is the set of all possible result nettypes that can be produced by this operator, over all combinations of valid child nettypes. The result is cached on the class to avoid recomputation.
- Returns:
Set of all nettypes that this operator can yield.
- Return type:
Set[NetType]
- nettype_range#
自定义的类属性装饰器。 允许通过 ClassName.property_name 直接获取动态计算的类属性, 同时也支持 instance.property_name。
Submodules#
nd2py.core.converter.from_postorder module#
nd2py.core.converter.from_preorder module#
nd2py.core.converter.parser module#
- nd2py.core.converter.parser.parse(expression: str, variables: Dict[str, Symbol] = None, callables: Dict[str, callable] = None) Symbol[source]#
Parse a textual expression into a symbol tree.
- Parameters:
expression – Python-like symbolic expression to parse.
variables – Optional mapping overriding inferred variables.
callables – Optional mapping adding or overriding callable symbols.
Examples
>>> import nd2py as nd >>> expression = nd.parse("sin(x) + 1") >>> float(expression.eval({"x": 0.0})) 1.0
nd2py.core.converter.string_printer module#
- class nd2py.core.converter.string_printer.StringPrinter[source]#
Bases:
Visitor- visit_GroupedParameter(node: GroupedParameter, *args, **kwargs) _Type[source]#
nd2py.core.converter.tree_printer module#
Submodules#
nd2py.core.context.copy_value module#
nd2py.core.context.nettype_inference module#
nd2py.core.context.set_fitable module#
nd2py.core.context.warn_once module#
Search algorithms#
- class nd2py.search.gp.GP(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, elitism_k: int = 10, population_size: int = 1000, tournament_size: int = 20, p_crossover: float = 0.9, p_subtree_mutation: float = 0.01, p_hoist_mutation: float = 0.01, p_point_mutation: float = 0.01, p_point_replace: float = 0.05, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), full_prob: float = 0.5, nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', n_jobs: int = None, log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, **kwargs)[source]#
Bases:
BaseEstimator,RegressorMixinGenetic Programming-based Symbolic Regression
- __init__(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, elitism_k: int = 10, population_size: int = 1000, tournament_size: int = 20, p_crossover: float = 0.9, p_subtree_mutation: float = 0.01, p_hoist_mutation: float = 0.01, p_point_mutation: float = 0.01, p_point_replace: float = 0.05, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), full_prob: float = 0.5, nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', n_jobs: int = None, log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, **kwargs)[source]#
Initialize a genetic-programming-based symbolic regression estimator.
This configures the function set, search hyperparameters, logging behavior, and optional graph structure used for nettype-aware expressions.
- Parameters:
variables (List[Variable]) – List of input variables that can be used in generated expressions.
binary (List[Symbol], optional) – Binary operator symbols available to the GP (for example
Add,Sub,Mul). Defaults to a standard arithmetic and min/max set.unary (List[Symbol], optional) – Unary operator symbols available to the GP (for example
Sqrt,Log,Sin). Defaults to a standard set of common functions.max_params (int, optional) – Maximum number of numeric parameters (
Numbernodes) allowed in an expression. Defaults to 2.elitism_k (int, optional) – Number of top individuals carried over unchanged between generations. Defaults to 10.
population_size (int, optional) – Number of individuals in each generation. Defaults to 1000.
tournament_size (int, optional) – Number of individuals competing in each tournament during parent selection. Defaults to 20.
p_crossover (float, optional) – Probability of applying subtree crossover. Defaults to 0.9.
p_subtree_mutation (float, optional) – Probability of applying subtree mutation. Defaults to 0.01.
p_hoist_mutation (float, optional) – Probability of applying hoist mutation. Defaults to 0.01.
p_point_mutation (float, optional) – Probability of applying point mutation. Defaults to 0.01.
p_point_replace (float, optional) – Probability of replacing a node during point mutation. Defaults to 0.05.
const_range (Tuple[float, float], optional) – Range from which random constants are sampled. Defaults to
(-1.0, 1.0).depth_range (Tuple[int, int], optional) – Minimum and maximum tree depth for randomly generated expressions. Defaults to
(2, 6).full_prob (float, optional) – Probability of using the “full” method rather than “grow” when generating random trees. Defaults to 0.5.
nettype (Optional[Literal["node", "edge", "scalar"]], optional) – Nettype of the target expression, used when working with graph data. Defaults to
"scalar".n_jobs (int, optional) – Number of parallel jobs used for evolving the population. If
None, evolution is run in a single process. Defaults toNone.log_per_iter (float, optional) – Log progress every
log_per_iteriterations; usefloat("inf")to disable iteration-based logging. Defaults tofloat("inf").log_per_sec (float, optional) – Log progress every
log_per_secseconds; usefloat("inf")to disable time-based logging. Defaults tofloat("inf").log_detailed_speed (bool, optional) – If True, include detailed timing information for individual steps in logs. Defaults to False.
save_path (str, optional) – File path to which JSON lines of per-iteration records are appended. If
None, records are not written to disk. Defaults toNone.random_state (Optional[int], optional) – Seed for the internal RNG to make runs reproducible. Defaults to
None.n_iter (int, optional) – Maximum number of evolution iterations. Defaults to 100.
use_tqdm (bool, optional) – If True, wrap the main evolution loop with a
tqdmprogress bar. Defaults to False.edge_list (Tuple[List[int], List[int]], optional) – Optional graph edge list
(sources, targets)used when evaluating graph operators. If provided andnum_nodesisNone, the number of nodes is inferred. Defaults toNone.num_nodes (int, optional) – Number of nodes in the underlying graph. If
Noneandedge_listis provided, it is inferred from the edges. Defaults toNone.**kwargs – Additional unused keyword arguments; a warning is logged if any are provided.
- Raises:
AssertionError – If the sum of mutation and crossover probabilities exceeds 1.0.
- fit(X: ndarray | DataFrame | Dict[str, ndarray], y: ndarray | Series)[source]#
Fit the GP model to training data by evolving expression trees.
The input features can be provided as a NumPy array, a pandas
DataFrame, or a dictionary mapping variable names to arrays. The method runs the evolutionary loop, tracks the best individual, and stores its expression tree inself.eqtree.- Parameters:
X (ndarray | DataFrame | Dict[str, ndarray]) – Input features with shape
(n_samples, n_dims)or an equivalent mapping from variable names to 1D arrays.y (ndarray | Series) – Target values with shape
(n_samples,).
- Returns:
The fitted estimator instance.
- Return type:
- Raises:
ValueError – If
Xis of an unsupported type.
- predict(X: ndarray | DataFrame | Dict[str, ndarray]) ndarray[source]#
Predict target values for
Xusing the best evolved expression tree.
- evolve(population: List[Individual], X: Dict[str, ndarray], y: ndarray, children_size=None, elitism_k=None) List[Individual][source]#
Evolve a population for one generation and return the offspring.
- init_population(X: Dict[str, ndarray], y: ndarray) List[Individual][source]#
Initialize the first population of individuals from the generator.
- tournament(population: List[Individual], num) List[Individual][source]#
Select individuals from the population via tournament selection.
- crossover(parent: Individual, donor: Individual) Individual[source]#
Create a child by replacing a subtree of
parentwith one fromdonor.
- subtree_mutation(parent: Individual) Individual[source]#
Create a child by replacing a random subtree with a newly generated random tree.
- hoist_mutation(parent: Individual) Individual[source]#
Create a child by hoisting a randomly chosen subtree to the root.
- point_mutation(parent: Individual) Individual[source]#
Create a child by performing point mutation with random symbol replacements or insertions.
- set_fitness(individual: Individual, X: Dict[str, ndarray], y: ndarray)[source]#
Compute and assign complexity, accuracy, and fitness for an individual.
- get_random_subtree(individual: Individual | Symbol, nettypes: Set[Literal['node', 'edge', 'scalar']] = None) Symbol[source]#
Sample a subtree from an individual following the GPlearn/Koza (1992) node-selection strategy.
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') GP#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
- class nd2py.search.gp.GPLearnGenerator(variables: List[Variable], binary: List[str | Symbol] = [Add, Sub, Mul, Div], unary: List[str | Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], full_prob: float = 0.5, depth_range: Tuple[int, int] = (2, 6), const_range: Tuple[float, float] = None, rng: RandomState = None, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, scalar_number_only=True)[source]#
Bases:
object- __init__(variables: List[Variable], binary: List[str | Symbol] = [Add, Sub, Mul, Div], unary: List[str | Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], full_prob: float = 0.5, depth_range: Tuple[int, int] = (2, 6), const_range: Tuple[float, float] = None, rng: RandomState = None, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, scalar_number_only=True)[source]#
Submodules#
nd2py.search.gp.gp module#
- class nd2py.search.gp.gp.Individual(eqtree: Symbol)[source]#
Bases:
object- copy() Individual[source]#
- class nd2py.search.gp.gp.GP(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, elitism_k: int = 10, population_size: int = 1000, tournament_size: int = 20, p_crossover: float = 0.9, p_subtree_mutation: float = 0.01, p_hoist_mutation: float = 0.01, p_point_mutation: float = 0.01, p_point_replace: float = 0.05, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), full_prob: float = 0.5, nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', n_jobs: int = None, log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, **kwargs)[source]#
Bases:
BaseEstimator,RegressorMixinGenetic Programming-based Symbolic Regression
- __init__(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, elitism_k: int = 10, population_size: int = 1000, tournament_size: int = 20, p_crossover: float = 0.9, p_subtree_mutation: float = 0.01, p_hoist_mutation: float = 0.01, p_point_mutation: float = 0.01, p_point_replace: float = 0.05, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), full_prob: float = 0.5, nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', n_jobs: int = None, log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, **kwargs)[source]#
Initialize a genetic-programming-based symbolic regression estimator.
This configures the function set, search hyperparameters, logging behavior, and optional graph structure used for nettype-aware expressions.
- Parameters:
variables (List[Variable]) – List of input variables that can be used in generated expressions.
binary (List[Symbol], optional) – Binary operator symbols available to the GP (for example
Add,Sub,Mul). Defaults to a standard arithmetic and min/max set.unary (List[Symbol], optional) – Unary operator symbols available to the GP (for example
Sqrt,Log,Sin). Defaults to a standard set of common functions.max_params (int, optional) – Maximum number of numeric parameters (
Numbernodes) allowed in an expression. Defaults to 2.elitism_k (int, optional) – Number of top individuals carried over unchanged between generations. Defaults to 10.
population_size (int, optional) – Number of individuals in each generation. Defaults to 1000.
tournament_size (int, optional) – Number of individuals competing in each tournament during parent selection. Defaults to 20.
p_crossover (float, optional) – Probability of applying subtree crossover. Defaults to 0.9.
p_subtree_mutation (float, optional) – Probability of applying subtree mutation. Defaults to 0.01.
p_hoist_mutation (float, optional) – Probability of applying hoist mutation. Defaults to 0.01.
p_point_mutation (float, optional) – Probability of applying point mutation. Defaults to 0.01.
p_point_replace (float, optional) – Probability of replacing a node during point mutation. Defaults to 0.05.
const_range (Tuple[float, float], optional) – Range from which random constants are sampled. Defaults to
(-1.0, 1.0).depth_range (Tuple[int, int], optional) – Minimum and maximum tree depth for randomly generated expressions. Defaults to
(2, 6).full_prob (float, optional) – Probability of using the “full” method rather than “grow” when generating random trees. Defaults to 0.5.
nettype (Optional[Literal["node", "edge", "scalar"]], optional) – Nettype of the target expression, used when working with graph data. Defaults to
"scalar".n_jobs (int, optional) – Number of parallel jobs used for evolving the population. If
None, evolution is run in a single process. Defaults toNone.log_per_iter (float, optional) – Log progress every
log_per_iteriterations; usefloat("inf")to disable iteration-based logging. Defaults tofloat("inf").log_per_sec (float, optional) – Log progress every
log_per_secseconds; usefloat("inf")to disable time-based logging. Defaults tofloat("inf").log_detailed_speed (bool, optional) – If True, include detailed timing information for individual steps in logs. Defaults to False.
save_path (str, optional) – File path to which JSON lines of per-iteration records are appended. If
None, records are not written to disk. Defaults toNone.random_state (Optional[int], optional) – Seed for the internal RNG to make runs reproducible. Defaults to
None.n_iter (int, optional) – Maximum number of evolution iterations. Defaults to 100.
use_tqdm (bool, optional) – If True, wrap the main evolution loop with a
tqdmprogress bar. Defaults to False.edge_list (Tuple[List[int], List[int]], optional) – Optional graph edge list
(sources, targets)used when evaluating graph operators. If provided andnum_nodesisNone, the number of nodes is inferred. Defaults toNone.num_nodes (int, optional) – Number of nodes in the underlying graph. If
Noneandedge_listis provided, it is inferred from the edges. Defaults toNone.**kwargs – Additional unused keyword arguments; a warning is logged if any are provided.
- Raises:
AssertionError – If the sum of mutation and crossover probabilities exceeds 1.0.
- fit(X: ndarray | DataFrame | Dict[str, ndarray], y: ndarray | Series)[source]#
Fit the GP model to training data by evolving expression trees.
The input features can be provided as a NumPy array, a pandas
DataFrame, or a dictionary mapping variable names to arrays. The method runs the evolutionary loop, tracks the best individual, and stores its expression tree inself.eqtree.- Parameters:
X (ndarray | DataFrame | Dict[str, ndarray]) – Input features with shape
(n_samples, n_dims)or an equivalent mapping from variable names to 1D arrays.y (ndarray | Series) – Target values with shape
(n_samples,).
- Returns:
The fitted estimator instance.
- Return type:
- Raises:
ValueError – If
Xis of an unsupported type.
- predict(X: ndarray | DataFrame | Dict[str, ndarray]) ndarray[source]#
Predict target values for
Xusing the best evolved expression tree.
- evolve(population: List[Individual], X: Dict[str, ndarray], y: ndarray, children_size=None, elitism_k=None) List[Individual][source]#
Evolve a population for one generation and return the offspring.
- init_population(X: Dict[str, ndarray], y: ndarray) List[Individual][source]#
Initialize the first population of individuals from the generator.
- tournament(population: List[Individual], num) List[Individual][source]#
Select individuals from the population via tournament selection.
- crossover(parent: Individual, donor: Individual) Individual[source]#
Create a child by replacing a subtree of
parentwith one fromdonor.
- subtree_mutation(parent: Individual) Individual[source]#
Create a child by replacing a random subtree with a newly generated random tree.
- hoist_mutation(parent: Individual) Individual[source]#
Create a child by hoisting a randomly chosen subtree to the root.
- point_mutation(parent: Individual) Individual[source]#
Create a child by performing point mutation with random symbol replacements or insertions.
- set_fitness(individual: Individual, X: Dict[str, ndarray], y: ndarray)[source]#
Compute and assign complexity, accuracy, and fitness for an individual.
- get_random_subtree(individual: Individual | Symbol, nettypes: Set[Literal['node', 'edge', 'scalar']] = None) Symbol[source]#
Sample a subtree from an individual following the GPlearn/Koza (1992) node-selection strategy.
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') GP#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
- class nd2py.search.llmsr.LLMResult(gen: Iterator)[source]#
Bases:
objectWrapper for LLM generator that captures the return value.
This class wraps a generator and provides convenient property access to the result dictionary after the generator is exhausted.
The key is using yield from to delegate to the inner generator, which automatically captures the return value via StopIteration.value.
Example
>>> api = OpenAIAPI(model='gpt-4o-mini') >>> result = api("Hello") # Returns LLMResult >>> for content in result: ... print(content) >>> print(result.usage) # Access via property >>> print(result.contents) # List of generated contents
- property usage: dict#
Token usage statistics.
- property messages: list#
Input messages.
- property response: dict#
Raw API response.
- property responses: list#
Raw API responses (for n>1 generations).
- property contents: list#
List of generated content strings.
- class nd2py.search.llmsr.LLMSR(prompt: str, eval_program: callable, seed_program: callable, template: str = '{prompt}\n\n{eval_program}\n\n{seed_programs}', namespace: Dict[str, object] = {}, n_islands: int = 10, n_iter: int = 1000, programs_per_prompt: int = 2, temperature_init: float = 0.1, temperature_period: int = 30000, random_state: int | None = None, log_per_iter: int = 1, log_per_sec: float = None, save_path: str = None, llm_provider: str = 'SiliconFlow', llm_model: str = 'Qwen3-8B')[source]#
Bases:
BaseEstimator,RegressorMixin- __init__(prompt: str, eval_program: callable, seed_program: callable, template: str = '{prompt}\n\n{eval_program}\n\n{seed_programs}', namespace: Dict[str, object] = {}, n_islands: int = 10, n_iter: int = 1000, programs_per_prompt: int = 2, temperature_init: float = 0.1, temperature_period: int = 30000, random_state: int | None = None, log_per_iter: int = 1, log_per_sec: float = None, save_path: str = None, llm_provider: str = 'SiliconFlow', llm_model: str = 'Qwen3-8B')[source]#
- tournament(islands: List[List[Individual]], data, n_iter=None) Tuple[int, List[Individual]][source]#
- set_fit_request(*, data: bool | None | str = '$UNCHANGED$') LLMSR#
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
data (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
dataparameter infit.- Returns:
self – The updated object.
- Return type:
object
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') LLMSR#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
Submodules#
nd2py.search.llmsr.llmsr module#
- class nd2py.search.llmsr.llmsr.LLMSR(prompt: str, eval_program: callable, seed_program: callable, template: str = '{prompt}\n\n{eval_program}\n\n{seed_programs}', namespace: Dict[str, object] = {}, n_islands: int = 10, n_iter: int = 1000, programs_per_prompt: int = 2, temperature_init: float = 0.1, temperature_period: int = 30000, random_state: int | None = None, log_per_iter: int = 1, log_per_sec: float = None, save_path: str = None, llm_provider: str = 'SiliconFlow', llm_model: str = 'Qwen3-8B')[source]#
Bases:
BaseEstimator,RegressorMixin- __init__(prompt: str, eval_program: callable, seed_program: callable, template: str = '{prompt}\n\n{eval_program}\n\n{seed_programs}', namespace: Dict[str, object] = {}, n_islands: int = 10, n_iter: int = 1000, programs_per_prompt: int = 2, temperature_init: float = 0.1, temperature_period: int = 30000, random_state: int | None = None, log_per_iter: int = 1, log_per_sec: float = None, save_path: str = None, llm_provider: str = 'SiliconFlow', llm_model: str = 'Qwen3-8B')[source]#
- tournament(islands: List[List[Individual]], data, n_iter=None) Tuple[int, List[Individual]][source]#
- set_fit_request(*, data: bool | None | str = '$UNCHANGED$') LLMSR#
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
data (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
dataparameter infit.- Returns:
self – The updated object.
- Return type:
object
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') LLMSR#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
- nd2py.search.llmsr.llmsr.render_python(text: str, width=120, highlight_lines=[], theme='staroffice') str[source]#
- class nd2py.search.mcts.MCTS(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, time_limit=None, sample_num=300, keep_vars=False, normalize_y=False, normalize_X=False, remove_abnormal=False, train_eval_split=1.0, child_num=50, n_playout=100, d_playout=10, max_len=30, c=1.41, eta=0.999, **kwargs)[source]#
Bases:
BaseEstimator,RegressorMixinMonte Carlo Tree Search-based Symbolic Regression
- __init__(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, time_limit=None, sample_num=300, keep_vars=False, normalize_y=False, normalize_X=False, remove_abnormal=False, train_eval_split=1.0, child_num=50, n_playout=100, d_playout=10, max_len=30, c=1.41, eta=0.999, **kwargs)[source]#
Initialize a Monte Carlo Tree Search symbolic regression estimator.
This configures the function set, search hyperparameters, logging behavior, optional graph structure, and various data preprocessing options used during MCTS-based exploration of expression trees.
- Parameters:
variables (List[Variable]) – List of input variables that can be used in generated expressions.
binary (List[Symbol], optional) – Binary operator symbols available to the search (for example
Add,Sub,Mul). Defaults to a standard arithmetic and min/max set.unary (List[Symbol], optional) – Unary operator symbols available to the search (for example
Sqrt,Log,Sin). Defaults to a standard set of common functions.max_params (int, optional) – Maximum number of numeric parameters (
Numbernodes) allowed in an expression. Defaults to 2.const_range (Tuple[float, float], optional) – Range from which random constants are sampled. Defaults to
(-1.0, 1.0).depth_range (Tuple[int, int], optional) – Minimum and maximum tree depth for randomly generated expressions. Defaults to
(2, 6).nettype (Optional[Literal["node", "edge", "scalar"]], optional) – Nettype of the target expression when working with graph data. Defaults to
"scalar".log_per_iter (float, optional) – Log progress every
log_per_iteriterations; usefloat("inf")to disable iteration-based logging. Defaults tofloat("inf").log_per_sec (float, optional) – Log progress every
log_per_secseconds; usefloat("inf")to disable time-based logging. Defaults tofloat("inf").log_detailed_speed (bool, optional) – If True, include detailed timing information for individual steps in logs. Defaults to False.
save_path (str, optional) – Directory in which JSON lines of per-iteration records are stored as
records.jsonl. IfNone, records are not written to disk. Defaults toNone.random_state (Optional[int], optional) – Seed used to control randomness for reproducible runs. Defaults to
None.n_iter (int, optional) – Maximum number of MCTS iterations. Defaults to 100.
use_tqdm (bool, optional) – If True, wrap the main search loop with a
tqdmprogress bar. Defaults to False.edge_list (Tuple[List[int], List[int]], optional) – Optional graph edge list
(sources, targets)used when evaluating graph operators. Defaults toNone.num_nodes (int, optional) – Number of nodes in the underlying graph; if
None, it may be inferred elsewhere. Defaults toNone.time_limit (float, optional) – Maximum wall-clock time (in seconds) for the search; if exceeded, the search terminates early. Defaults to
None.sample_num (int, optional) – Number of samples drawn when evaluating or sampling candidate expressions. Defaults to 300.
keep_vars (bool, optional) – If True, keep variable names instead of renaming them during preprocessing. Defaults to False.
normalize_y (bool, optional) – If True, normalize target values before fitting. Defaults to False.
normalize_X (bool, optional) – If True, normalize input features before fitting. Defaults to False.
remove_abnormal (bool, optional) – If True, attempt to remove abnormal samples before training. Defaults to False.
train_eval_split (float, optional) – Fraction of data used for training; the remainder may be used for evaluation. Defaults to 1.0.
child_num (int, optional) – Maximum number of child nodes expanded from a node during expansion. Defaults to 50.
n_playout (int, optional) – Number of rollouts performed from a node during simulation. Defaults to 100.
d_playout (int, optional) – Maximum depth of each simulation rollout. Defaults to 10.
max_len (int, optional) – Maximum allowed expression length; used to constrain actions. Defaults to 30.
c (float, optional) – Exploration constant used in the UCT formula during selection. Defaults to 1.41.
eta (float, optional) – Complexity penalty factor used in the reward function, where larger
etadiscounts complex expressions less. Defaults to 0.999.**kwargs – Additional unused keyword arguments; a warning is logged if any are provided.
- fit(X: ndarray | DataFrame | Dict[str, ndarray], y: ndarray | Series)[source]#
Fit the MCTS model to training data by exploring expression trees.
The input features can be provided as a NumPy array, a pandas
DataFrame, or a dictionary mapping variable names to arrays. The method builds a Monte Carlo search tree, repeatedly performs selection–expansion–simulation–backpropagation steps, and tracks the best discovered symbolic expression inself.eqtree.- Parameters:
X (ndarray | DataFrame | Dict[str, ndarray]) – Input features with shape
(n_samples, n_dims)or an equivalent mapping from variable names to 1D arrays.y (ndarray | Series) – Target values with shape
(n_samples,).
- Returns:
The fitted estimator instance.
- Return type:
- Raises:
ValueError – If
Xis of an unsupported type.
- predict(X: ndarray | DataFrame | Dict[str, ndarray]) ndarray[source]#
Predict target values for
Xusing the best expression found by MCTS.
- action(state: Node, action: Tuple[Symbol, Symbol]) Node[source]#
Apply an action to a state by replacing an empty placeholder with a symbol.
- check_valid_action(state: Node, action: Tuple[Symbol, Symbol]) bool[source]#
Return whether a proposed action is valid under length and nettype constraints.
- iter_valid_action(state: Node, shuffle=False) Generator[Tuple[Symbol, Symbol], None, None][source]#
Iterate over all valid actions from a given state, optionally in random order.
- pick_valid_action(state: Node) Tuple[Symbol, Symbol][source]#
Randomly sample a single valid action from the current state.
- fill_to_complete(state: Node) Node[source]#
Fill all remaining empty leaves in a state with compatible variables.
- expand(node: Node, X: Dict[str, ndarray], y: ndarray) Node[source]#
Expand a node by generating child states and return one child for simulation.
- simulate(node: Node, X: Dict[str, ndarray], y: ndarray) Tuple[Node, float][source]#
Run playout simulations from a node and return the best simulated state and reward.
- backpropagate(node: Node, reward: float)[source]#
Backpropagate a reward up the tree, updating visit counts and value estimates.
- set_reward(node: Node, X: Dict[str, ndarray], y: ndarray)[source]#
Fit parameters, evaluate an expression, and assign reward and diagnostics to a node.
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') MCTS#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
Submodules#
nd2py.search.mcts.mcts module#
- class nd2py.search.mcts.mcts.MCTS(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, time_limit=None, sample_num=300, keep_vars=False, normalize_y=False, normalize_X=False, remove_abnormal=False, train_eval_split=1.0, child_num=50, n_playout=100, d_playout=10, max_len=30, c=1.41, eta=0.999, **kwargs)[source]#
Bases:
BaseEstimator,RegressorMixinMonte Carlo Tree Search-based Symbolic Regression
- __init__(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, time_limit=None, sample_num=300, keep_vars=False, normalize_y=False, normalize_X=False, remove_abnormal=False, train_eval_split=1.0, child_num=50, n_playout=100, d_playout=10, max_len=30, c=1.41, eta=0.999, **kwargs)[source]#
Initialize a Monte Carlo Tree Search symbolic regression estimator.
This configures the function set, search hyperparameters, logging behavior, optional graph structure, and various data preprocessing options used during MCTS-based exploration of expression trees.
- Parameters:
variables (List[Variable]) – List of input variables that can be used in generated expressions.
binary (List[Symbol], optional) – Binary operator symbols available to the search (for example
Add,Sub,Mul). Defaults to a standard arithmetic and min/max set.unary (List[Symbol], optional) – Unary operator symbols available to the search (for example
Sqrt,Log,Sin). Defaults to a standard set of common functions.max_params (int, optional) – Maximum number of numeric parameters (
Numbernodes) allowed in an expression. Defaults to 2.const_range (Tuple[float, float], optional) – Range from which random constants are sampled. Defaults to
(-1.0, 1.0).depth_range (Tuple[int, int], optional) – Minimum and maximum tree depth for randomly generated expressions. Defaults to
(2, 6).nettype (Optional[Literal["node", "edge", "scalar"]], optional) – Nettype of the target expression when working with graph data. Defaults to
"scalar".log_per_iter (float, optional) – Log progress every
log_per_iteriterations; usefloat("inf")to disable iteration-based logging. Defaults tofloat("inf").log_per_sec (float, optional) – Log progress every
log_per_secseconds; usefloat("inf")to disable time-based logging. Defaults tofloat("inf").log_detailed_speed (bool, optional) – If True, include detailed timing information for individual steps in logs. Defaults to False.
save_path (str, optional) – Directory in which JSON lines of per-iteration records are stored as
records.jsonl. IfNone, records are not written to disk. Defaults toNone.random_state (Optional[int], optional) – Seed used to control randomness for reproducible runs. Defaults to
None.n_iter (int, optional) – Maximum number of MCTS iterations. Defaults to 100.
use_tqdm (bool, optional) – If True, wrap the main search loop with a
tqdmprogress bar. Defaults to False.edge_list (Tuple[List[int], List[int]], optional) – Optional graph edge list
(sources, targets)used when evaluating graph operators. Defaults toNone.num_nodes (int, optional) – Number of nodes in the underlying graph; if
None, it may be inferred elsewhere. Defaults toNone.time_limit (float, optional) – Maximum wall-clock time (in seconds) for the search; if exceeded, the search terminates early. Defaults to
None.sample_num (int, optional) – Number of samples drawn when evaluating or sampling candidate expressions. Defaults to 300.
keep_vars (bool, optional) – If True, keep variable names instead of renaming them during preprocessing. Defaults to False.
normalize_y (bool, optional) – If True, normalize target values before fitting. Defaults to False.
normalize_X (bool, optional) – If True, normalize input features before fitting. Defaults to False.
remove_abnormal (bool, optional) – If True, attempt to remove abnormal samples before training. Defaults to False.
train_eval_split (float, optional) – Fraction of data used for training; the remainder may be used for evaluation. Defaults to 1.0.
child_num (int, optional) – Maximum number of child nodes expanded from a node during expansion. Defaults to 50.
n_playout (int, optional) – Number of rollouts performed from a node during simulation. Defaults to 100.
d_playout (int, optional) – Maximum depth of each simulation rollout. Defaults to 10.
max_len (int, optional) – Maximum allowed expression length; used to constrain actions. Defaults to 30.
c (float, optional) – Exploration constant used in the UCT formula during selection. Defaults to 1.41.
eta (float, optional) – Complexity penalty factor used in the reward function, where larger
etadiscounts complex expressions less. Defaults to 0.999.**kwargs – Additional unused keyword arguments; a warning is logged if any are provided.
- fit(X: ndarray | DataFrame | Dict[str, ndarray], y: ndarray | Series)[source]#
Fit the MCTS model to training data by exploring expression trees.
The input features can be provided as a NumPy array, a pandas
DataFrame, or a dictionary mapping variable names to arrays. The method builds a Monte Carlo search tree, repeatedly performs selection–expansion–simulation–backpropagation steps, and tracks the best discovered symbolic expression inself.eqtree.- Parameters:
X (ndarray | DataFrame | Dict[str, ndarray]) – Input features with shape
(n_samples, n_dims)or an equivalent mapping from variable names to 1D arrays.y (ndarray | Series) – Target values with shape
(n_samples,).
- Returns:
The fitted estimator instance.
- Return type:
- Raises:
ValueError – If
Xis of an unsupported type.
- predict(X: ndarray | DataFrame | Dict[str, ndarray]) ndarray[source]#
Predict target values for
Xusing the best expression found by MCTS.
- action(state: Node, action: Tuple[Symbol, Symbol]) Node[source]#
Apply an action to a state by replacing an empty placeholder with a symbol.
- check_valid_action(state: Node, action: Tuple[Symbol, Symbol]) bool[source]#
Return whether a proposed action is valid under length and nettype constraints.
- iter_valid_action(state: Node, shuffle=False) Generator[Tuple[Symbol, Symbol], None, None][source]#
Iterate over all valid actions from a given state, optionally in random order.
- pick_valid_action(state: Node) Tuple[Symbol, Symbol][source]#
Randomly sample a single valid action from the current state.
- fill_to_complete(state: Node) Node[source]#
Fill all remaining empty leaves in a state with compatible variables.
- expand(node: Node, X: Dict[str, ndarray], y: ndarray) Node[source]#
Expand a node by generating child states and return one child for simulation.
- simulate(node: Node, X: Dict[str, ndarray], y: ndarray) Tuple[Node, float][source]#
Run playout simulations from a node and return the best simulated state and reward.
- backpropagate(node: Node, reward: float)[source]#
Backpropagate a reward up the tree, updating visit counts and value estimates.
- set_reward(node: Node, X: Dict[str, ndarray], y: ndarray)[source]#
Fit parameters, evaluate an expression, and assign reward and diagnostics to a node.
- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') MCTS#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
nd2py.search.mcts.mcts_forest module#
- class nd2py.search.mcts.mcts_forest.MCTSForest(variables: List[Variable], binary: List[Symbol] = [Add, Sub, Mul, Div, Max, Min], unary: List[Symbol] = [Sqrt, Log, Abs, Neg, Inv, Sin, Cos, Tan], max_params: int = 2, const_range: Tuple[float, float] = (-1.0, 1.0), depth_range: Tuple[int, int] = (2, 6), nettype: Literal['node', 'edge', 'scalar'] | None = 'scalar', log_per_iter: int = inf, log_per_sec: float = inf, log_detailed_speed: bool = False, save_path: str = None, random_state: int | None = None, n_iter=100, use_tqdm=False, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, time_limit=None, sample_num=300, keep_vars=False, normalize_y=False, normalize_X=False, remove_abnormal=False, train_eval_split=1.0, child_num=50, n_playout=100, d_playout=10, max_len=30, c=1.41, eta=0.999, **kwargs)[source]#
Bases:
MCTS- set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') MCTSForest#
Configure whether metadata should be requested to be passed to the
scoremethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed toscoreif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it toscore.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter inscore.- Returns:
self – The updated object.
- Return type:
object
- class nd2py.search.ndformer.NDFormerModelConfig(n_mantissa: int = 4, min_exponent: int = -100, max_exponent: int = 100, max_var_num: int = 10, model: str = 'default', n_head: int = 8, d_emb: int = 128, d_ff: int = 512, dropout: float = 0.2, n_GNN_layers: int = 2, n_transformer_encoder_layers: int = 2, n_transformer_decoder_layers: int = 2, use_aux_input: bool = True, n_induction_points: int = 128, max_seq_len: int = 100, operands: Tuple[str] = <factory>, min_data_num: int = 100, max_data_num: int = 200, min_node_num: int = 10, max_node_num: int = 100, min_edge_num: int = 20, max_edge_num: int = 600, min_var_val: int = -10, max_var_val: int = 10, min_coeff_val: int = -20, max_coeff_val: int = 20)[source]#
Bases:
objectConfiguration for NDFormer model architecture and capabilities.
═══════════════════════════════════════════════════════════════════════════ PURPOSE ═══════════════════════════════════════════════════════════════════════════
This class defines the model’s structure and capabilities:
Model architecture (transformer layers, GNN layers, embedding dimensions)
Tokenization scheme (number encoding, vocabulary)
Supported operators and sequence length limits
═══════════════════════════════════════════════════════════════════════════ RELATIONSHIP WITH NDFormerMCTS (INFERENCE-TIME SEARCH) ═══════════════════════════════════════════════════════════════════════════
TL;DR: Users of NDFormerMCTS do not need to interact with this class directly.
When using a pre-trained model with NDFormerMCTS:
The trained model + config is a black box: The model and its associated config are loaded together from a checkpoint. The config is used internally to reconstruct the tokenizer and model architecture.
No control over search behavior: NDFormerMCTS does NOT use this config to control how search proceeds. Search parameters (beam_width, temperature, c, etc.) are configured directly in NDFormerMCTS.__init__().
Capability validation only: NDFormerMCTS may use the config to verify that search settings are within the model’s capabilities: - max_len (search) should not exceed max_seq_len (model capability) - Operator set should be compatible with trained vocabulary - Variable count should not exceed max_var_num
This design follows standard ML practice where model architecture config is separate from inference/search hyperparameters.
═══════════════════════════════════════════════════════════════════════════ USAGE ═══════════════════════════════════════════════════════════════════════════
Training a new model:
`python config = NDFormerModelConfig(model='default', n_head=16, d_emb=256) tokenizer = NDFormerTokenizer(config, variables) model = NDFormerModel.create(config, tokenizer) # ... train on dataset ... torch.save({'model': model.state_dict(), 'config': config}, 'checkpoint.pth') `Using a pre-trained model (automatic, users don’t handle config directly):
`python search = NDFormerMCTS(variables=[x, y]) search.load_ndformer('hf://YuMeow/ndformer:best.pth') # Config is automatically loaded and used for capability validation search.fit(X, y) `Creating alternative model architectures: ```python @NDFormerModel.register_model(‘gcn’) class GCNNDFormer(NDFormerModel):
- def __init__(self, config, tokenizer):
super().__init__(config, tokenizer) # … custom architecture …
config = NDFormerModelConfig(model=’gcn’) model = NDFormerModel.create(config, tokenizer) ```
═══════════════════════════════════════════════════════════════════════════ ATTRIBUTES ═══════════════════════════════════════════════════════════════════════════
- n_mantissa: int = 4#
Number of digits in mantissa for number tokenization.
- min_exponent: int = -100#
Minimum exponent value for number tokenization.
- max_exponent: int = 100#
Maximum exponent value for number tokenization.
- max_var_num: int = 10#
Maximum number of variables per nettype (node/edge/scalar).
- model: str = 'default'#
Model architecture type. Used by NDFormerModel.create() to select subclass.
Available models are registered via @NDFormerModel.register_model(‘name’). Default is ‘default’ (the base NDFormerModel architecture).
- n_head: int = 8#
Number of attention heads in multi-head self-attention.
- d_emb: int = 128#
Dimension of token embeddings and hidden states.
- d_ff: int = 512#
Dimension of feed-forward network intermediate layer.
- dropout: float = 0.2#
Dropout probability applied to embeddings and attention.
- n_GNN_layers: int = 2#
Number of graph neural network layers for encoding graph topology.
- n_transformer_encoder_layers: int = 2#
Number of transformer encoder layers.
- n_transformer_decoder_layers: int = 2#
Number of transformer decoder layers for autoregressive generation.
- use_aux_input: bool = True#
Whether to use auxiliary inputs (parent/nettype information).
- __init__(n_mantissa: int = 4, min_exponent: int = -100, max_exponent: int = 100, max_var_num: int = 10, model: str = 'default', n_head: int = 8, d_emb: int = 128, d_ff: int = 512, dropout: float = 0.2, n_GNN_layers: int = 2, n_transformer_encoder_layers: int = 2, n_transformer_decoder_layers: int = 2, use_aux_input: bool = True, n_induction_points: int = 128, max_seq_len: int = 100, operands: Tuple[str] = <factory>, min_data_num: int = 100, max_data_num: int = 200, min_node_num: int = 10, max_node_num: int = 100, min_edge_num: int = 20, max_edge_num: int = 600, min_var_val: int = -10, max_var_val: int = 10, min_coeff_val: int = -20, max_coeff_val: int = 20) None#
- n_induction_points: int = 128#
Number of induction points for Set Transformer encoder (FLASH-ANSR). Only used when model=’flash_ansr’.
- max_seq_len: int = 100#
Maximum sequence length the model can handle.
Note: NDFormerMCTS uses this for capability validation - search with max_len > max_seq_len may produce unreliable results.
- operands: Tuple[str]#
Tuple of operator class names in the model vocabulary.
Note: NDFormerMCTS may check if its operator set is compatible with the trained model’s vocabulary.
- min_data_num: int = 100#
Minimum number of samples per training equation.
- max_data_num: int = 200#
Maximum number of samples per training equation.
- min_node_num: int = 10#
Minimum number of nodes in generated graphs.
- max_node_num: int = 100#
Maximum number of nodes in generated graphs.
- min_edge_num: int = 20#
Minimum number of edges in generated graphs.
- max_edge_num: int = 600#
Maximum number of edges in generated graphs.
- min_var_val: int = -10#
Minimum absolute value for variable sampling.
- max_var_val: int = 10#
Maximum absolute value for variable sampling.
- min_coeff_val: int = -20#
Minimum value for equation coefficients.
- max_coeff_val: int = 20#
Maximum value for equation coefficients.
- class nd2py.search.ndformer.NDFormerTokenizer(config: NDFormerModelConfig, variables: List[Symbol] | None = None)[source]#
Bases:
object- __init__(config: NDFormerModelConfig, variables: List[Symbol] | None = None)[source]#
- property vocab_size#
- property pad_token_id#
- property sos_token_id#
- property eos_token_id#
- property unk_token_id#
- encode(eqtree: Symbol, mode: Literal['token', 'token_id'] = 'token') Tuple[List[int], List[int], List[int]][source]#
- decode(tokens: List[str], parents: List[str], nettypes: List[str], mode: Literal['token', 'token_id'] = 'token') Symbol[source]#
- encode_array(data: ndarray, mode: Literal['token', 'token_id'] = 'token_id')[source]#
专门用于将纯浮点数组转换为 token 或 token_id
- decode_array(tokens: ndarray, mode: Literal['token', 'token_id'] = 'token_id')[source]#
专门用于将 token 或 token_id 数组转换回纯浮点数组
- classmethod from_dict(config: dict) NDFormerTokenizer[source]#
- classmethod load(filepath: str) NDFormerTokenizer[source]#
从本地 JSON 文件加载
Submodules#
nd2py.search.ndformer.ndformer_config module#
- class nd2py.search.ndformer.ndformer_config.NDFormerModelConfig(n_mantissa: int = 4, min_exponent: int = -100, max_exponent: int = 100, max_var_num: int = 10, model: str = 'default', n_head: int = 8, d_emb: int = 128, d_ff: int = 512, dropout: float = 0.2, n_GNN_layers: int = 2, n_transformer_encoder_layers: int = 2, n_transformer_decoder_layers: int = 2, use_aux_input: bool = True, n_induction_points: int = 128, max_seq_len: int = 100, operands: Tuple[str] = <factory>, min_data_num: int = 100, max_data_num: int = 200, min_node_num: int = 10, max_node_num: int = 100, min_edge_num: int = 20, max_edge_num: int = 600, min_var_val: int = -10, max_var_val: int = 10, min_coeff_val: int = -20, max_coeff_val: int = 20)[source]#
Bases:
objectConfiguration for NDFormer model architecture and capabilities.
═══════════════════════════════════════════════════════════════════════════ PURPOSE ═══════════════════════════════════════════════════════════════════════════
This class defines the model’s structure and capabilities:
Model architecture (transformer layers, GNN layers, embedding dimensions)
Tokenization scheme (number encoding, vocabulary)
Supported operators and sequence length limits
═══════════════════════════════════════════════════════════════════════════ RELATIONSHIP WITH NDFormerMCTS (INFERENCE-TIME SEARCH) ═══════════════════════════════════════════════════════════════════════════
TL;DR: Users of NDFormerMCTS do not need to interact with this class directly.
When using a pre-trained model with NDFormerMCTS:
The trained model + config is a black box: The model and its associated config are loaded together from a checkpoint. The config is used internally to reconstruct the tokenizer and model architecture.
No control over search behavior: NDFormerMCTS does NOT use this config to control how search proceeds. Search parameters (beam_width, temperature, c, etc.) are configured directly in NDFormerMCTS.__init__().
Capability validation only: NDFormerMCTS may use the config to verify that search settings are within the model’s capabilities: - max_len (search) should not exceed max_seq_len (model capability) - Operator set should be compatible with trained vocabulary - Variable count should not exceed max_var_num
This design follows standard ML practice where model architecture config is separate from inference/search hyperparameters.
═══════════════════════════════════════════════════════════════════════════ USAGE ═══════════════════════════════════════════════════════════════════════════
Training a new model:
`python config = NDFormerModelConfig(model='default', n_head=16, d_emb=256) tokenizer = NDFormerTokenizer(config, variables) model = NDFormerModel.create(config, tokenizer) # ... train on dataset ... torch.save({'model': model.state_dict(), 'config': config}, 'checkpoint.pth') `Using a pre-trained model (automatic, users don’t handle config directly):
`python search = NDFormerMCTS(variables=[x, y]) search.load_ndformer('hf://YuMeow/ndformer:best.pth') # Config is automatically loaded and used for capability validation search.fit(X, y) `Creating alternative model architectures: ```python @NDFormerModel.register_model(‘gcn’) class GCNNDFormer(NDFormerModel):
- def __init__(self, config, tokenizer):
super().__init__(config, tokenizer) # … custom architecture …
config = NDFormerModelConfig(model=’gcn’) model = NDFormerModel.create(config, tokenizer) ```
═══════════════════════════════════════════════════════════════════════════ ATTRIBUTES ═══════════════════════════════════════════════════════════════════════════
- n_mantissa: int = 4#
Number of digits in mantissa for number tokenization.
- min_exponent: int = -100#
Minimum exponent value for number tokenization.
- max_exponent: int = 100#
Maximum exponent value for number tokenization.
- max_var_num: int = 10#
Maximum number of variables per nettype (node/edge/scalar).
- model: str = 'default'#
Model architecture type. Used by NDFormerModel.create() to select subclass.
Available models are registered via @NDFormerModel.register_model(‘name’). Default is ‘default’ (the base NDFormerModel architecture).
- n_head: int = 8#
Number of attention heads in multi-head self-attention.
- d_emb: int = 128#
Dimension of token embeddings and hidden states.
- d_ff: int = 512#
Dimension of feed-forward network intermediate layer.
- dropout: float = 0.2#
Dropout probability applied to embeddings and attention.
- n_GNN_layers: int = 2#
Number of graph neural network layers for encoding graph topology.
- n_transformer_encoder_layers: int = 2#
Number of transformer encoder layers.
- n_transformer_decoder_layers: int = 2#
Number of transformer decoder layers for autoregressive generation.
- use_aux_input: bool = True#
Whether to use auxiliary inputs (parent/nettype information).
- __init__(n_mantissa: int = 4, min_exponent: int = -100, max_exponent: int = 100, max_var_num: int = 10, model: str = 'default', n_head: int = 8, d_emb: int = 128, d_ff: int = 512, dropout: float = 0.2, n_GNN_layers: int = 2, n_transformer_encoder_layers: int = 2, n_transformer_decoder_layers: int = 2, use_aux_input: bool = True, n_induction_points: int = 128, max_seq_len: int = 100, operands: Tuple[str] = <factory>, min_data_num: int = 100, max_data_num: int = 200, min_node_num: int = 10, max_node_num: int = 100, min_edge_num: int = 20, max_edge_num: int = 600, min_var_val: int = -10, max_var_val: int = 10, min_coeff_val: int = -20, max_coeff_val: int = 20) None#
- n_induction_points: int = 128#
Number of induction points for Set Transformer encoder (FLASH-ANSR). Only used when model=’flash_ansr’.
- max_seq_len: int = 100#
Maximum sequence length the model can handle.
Note: NDFormerMCTS uses this for capability validation - search with max_len > max_seq_len may produce unreliable results.
- operands: Tuple[str]#
Tuple of operator class names in the model vocabulary.
Note: NDFormerMCTS may check if its operator set is compatible with the trained model’s vocabulary.
- min_data_num: int = 100#
Minimum number of samples per training equation.
- max_data_num: int = 200#
Maximum number of samples per training equation.
- min_node_num: int = 10#
Minimum number of nodes in generated graphs.
- max_node_num: int = 100#
Maximum number of nodes in generated graphs.
- min_edge_num: int = 20#
Minimum number of edges in generated graphs.
- max_edge_num: int = 600#
Maximum number of edges in generated graphs.
- min_var_val: int = -10#
Minimum absolute value for variable sampling.
- max_var_val: int = 10#
Maximum absolute value for variable sampling.
- min_coeff_val: int = -20#
Minimum value for equation coefficients.
- max_coeff_val: int = 20#
Maximum value for equation coefficients.
nd2py.search.ndformer.ndformer_dataset module#
- class nd2py.search.ndformer.ndformer_dataset.InfiniteSampler(*args: Any, **kwargs: Any)[source]#
Bases:
Sampler
- class nd2py.search.ndformer.ndformer_dataset.NDFormerDataset(*args: Any, **kwargs: Any)[source]#
Bases:
Dataset- __init__(config: NDFormerModelConfig, eqtree_generator: NDFormerEqtreeGenerator, topo_generator: NDFormerGraphGenerator, data_generator: NDFormerDataGenerator, tokenizer: NDFormerTokenizer, n_samples: int | None = None, random_state: int | None = None)[source]#
nd2py.search.ndformer.ndformer_generator module#
- class nd2py.search.ndformer.ndformer_generator.NDFormerEqtreeGenerator(variables: List[Variable], binary: List[str | Symbol] = [Add, Sub, Mul, Div], unary: List[str | Symbol] = [Sqrt, SqrtAbs, Pow2, Pow3, Log, LogAbs, Exp, Abs, Neg, Inv, Sin, Cos, Tan, Tanh, Sigmoid, Aggr, Sour, Targ, Readout], full_prob: float = 0.5, depth_range: Tuple[int, int] = (2, 6), const_range: Tuple[float, float] = None, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, scalar_number_only=True)[source]#
Bases:
object- __init__(variables: List[Variable], binary: List[str | Symbol] = [Add, Sub, Mul, Div], unary: List[str | Symbol] = [Sqrt, SqrtAbs, Pow2, Pow3, Log, LogAbs, Exp, Abs, Neg, Inv, Sin, Cos, Tan, Tanh, Sigmoid, Aggr, Sour, Targ, Readout], full_prob: float = 0.5, depth_range: Tuple[int, int] = (2, 6), const_range: Tuple[float, float] = None, edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, scalar_number_only=True)[source]#
- class nd2py.search.ndformer.ndformer_generator.NDFormerGraphGenerator(config: NDFormerModelConfig)[source]#
Bases:
object- __init__(config: NDFormerModelConfig)[source]#
- sample(topology: Literal['ER', 'BA', 'WS', 'Complete'] = None, _rng: Generator = None, **kwargs)[source]#
Arguments: - V: node num - topology: ‘ER’, ‘BA’, ‘WS’, ‘Complete’ - kwargs:
(When topology is ‘ER’) - p: edge probability - directed: directed or not (When topology is ‘BA’) - m: number of edges to attach from a new node to existing nodes (When topology is ‘WS’) - k: each node is connected to k nearest neighbors in ring topology - p: probability of rewiring each edge (When topology is ‘Complete’) - None
Return: - edge_list: (2, E), edge list - num_nodes: int, node num
- class nd2py.search.ndformer.ndformer_generator.NDFormerDataGenerator(config: NDFormerModelConfig)[source]#
Bases:
object- __init__(config: NDFormerModelConfig)[source]#
- sample(eqtree: Symbol, dist_type: Literal['GMM', 'Uniform', 'Gaussian'] = 'GMM', edge_list: Tuple[List[int], List[int]] = None, num_nodes: int = None, sample_num: int = None, _rng: Generator = None, **kwargs)[source]#
Arguments: - eqtree: a symbolic expression tree
- Returns:
- var_dict = dict(
A: np.ndarray, (V, V) G: np.ndarray, (E, 2) out: np.ndarray, (N, V) or (N, E) v1/v2/v3/v4/v5: np.ndarray, (N, V) e1/e2/e3/e4/e5: np.ndarray, (N, E)
)
nd2py.search.ndformer.ndformer_model module#
- class nd2py.search.ndformer.ndformer_model.NDFormerModel(*args: Any, **kwargs: Any)[source]#
Bases:
FactoryMixin,ModuleBase class for NDFormer models.
Inherits from FactoryMixin which provides: - NDFormerModel.register_model(‘name’): Decorator to register subclasses - NDFormerModel.create(config, tokenizer): Factory method to create instances
The base class is automatically registered as ‘default’ model.
Example
@NDFormerModel.register_model(‘gcn’) class GCNNDFormer(NDFormerModel):
- def __init__(self, config, tokenizer):
super().__init__(config, tokenizer) # … custom architecture …
# Usage config = NDFormerModelConfig(model=’gcn’) model = NDFormerModel.create(config, tokenizer)
- __init__(config: NDFormerModelConfig, tokenizer: NDFormerTokenizer)[source]#
- encode_graph(data_node, data_edge, data_scalar, edge_list, num_nodes, node_batch_idx=None, timer=None)[source]#
图编码阶段:仅在图拓扑变更或初始化时调用一次。
Args: - data_node: (SampleNum, NodeNum, max_var_num+1, 3) - data_edge: (SampleNum, EdgeNum, max_var_num+1, 3) - data_scalar: (SampleNum, BatchNum, max_var_num+1, 3) - edge_list: (2, EdgeNum) - num_nodes: int - node_batch_idx: (TotalNodeNum,) 每个节点所属图的索引
Returns: - memory: (BatchNum, MaxNodeNum, d_emb) - memory_key_padding_mask: (BatchNum, MaxNodeNum) 或 None (如果 node_batch_idx is None), 其中 True 代表需要被忽略的 Pad
- decode_sequence(memory, partial_eq, memory_key_padding_mask=None, seq_batch_idx=None, timer=None)[source]#
序列解码阶段:支持 1-to-N 广播,可高频调用。
Args: - memory: (BatchNum, NodeNum*SampleNum, d_emb), 来自 encode_graph 的输出 - partial_eq: (SeqNum, MaxSeqLen) - memory_key_padding_mask: (BatchNum, NodeNum*SampleNum) 或 None, 其中 True 代表需要被忽略的 Pad - seq_batch_idx: (SeqNum,) 每个序列所属图的索引, 用于将 memory 中的节点特征正确广播到每个序列
Returns: - logits: (SeqNum, vocab_size)
nd2py.search.ndformer.ndformer_tokenizer module#
- class nd2py.search.ndformer.ndformer_tokenizer.NumberTokenizer(n_mantissa=4, min_exponent=-100, max_exponent=100)[source]#
Bases:
object
- class nd2py.search.ndformer.ndformer_tokenizer.NDFormerTokenizer(config: NDFormerModelConfig, variables: List[Symbol] | None = None)[source]#
Bases:
object- __init__(config: NDFormerModelConfig, variables: List[Symbol] | None = None)[source]#
- property vocab_size#
- property pad_token_id#
- property sos_token_id#
- property eos_token_id#
- property unk_token_id#
- encode(eqtree: Symbol, mode: Literal['token', 'token_id'] = 'token') Tuple[List[int], List[int], List[int]][source]#
- decode(tokens: List[str], parents: List[str], nettypes: List[str], mode: Literal['token', 'token_id'] = 'token') Symbol[source]#
- encode_array(data: ndarray, mode: Literal['token', 'token_id'] = 'token_id')[source]#
专门用于将纯浮点数组转换为 token 或 token_id
- decode_array(tokens: ndarray, mode: Literal['token', 'token_id'] = 'token_id')[source]#
专门用于将 token 或 token_id 数组转换回纯浮点数组
- classmethod from_dict(config: dict) NDFormerTokenizer[source]#
- classmethod load(filepath: str) NDFormerTokenizer[source]#
从本地 JSON 文件加载
Data generation and utilities#
Submodules#
nd2py.dataset.tokenizer module#
Subpackages#
- class nd2py.utils.NamedTimer(unit='iter')[source]#
Bases:
Timer- to_str(mode: Literal['time', 'count', 'pace', 'speed'] = 'pace', mode_of_detail: Literal['time', 'count', 'pace', 'speed'] | None = 'pace', mode_of_percent: Literal['by_time', 'by_count'] | None = 'by_time')[source]#
- property names#
- property time#
- property count#
- property named_time#
- property named_count#
- property named_pace#
- property named_speed#
- class nd2py.utils.ParallelTimer(unit='iter')[source]#
Bases:
Timer- to_str(mode: Literal['time', 'count', 'pace', 'speed'] = 'pace', mode_of_detail: Literal['time', 'count', 'pace', 'speed'] | None = 'pace', mode_of_percent: Literal['by_time', 'by_count'] | None = 'by_time')[source]#
- property names#
- property count#
- property named_time#
- property named_count#
- property named_pace#
- property named_speed#
- class nd2py.utils.Timer(unit='iter')[source]#
Bases:
object- property time#
- property count#
- property pace#
- property speed#
- nd2py.utils.add_minus_flags(parser: ArgumentParser)[source]#
自动为 argparse.ArgumentParser 中含有下划线的参数添加别名。例如: –fix_existing -> 添加别名 –fix-existing –augment_OD_num -> 添加别名 –augment-OD-num
- nd2py.utils.add_negation_flags(parser: ArgumentParser)[source]#
自动为 parser 中的 store_true 参数添加对应的 –no-xxx 选项。
- class nd2py.utils.classproperty(fget)[source]#
Bases:
object自定义的类属性装饰器。 允许通过 ClassName.property_name 直接获取动态计算的类属性, 同时也支持 instance.property_name。
- nd2py.utils.download_model(name: str, checkpoint: str, repo: str = None, release_tag: str = None, token: str = None) Path[source]#
从 Github 的 {repo} 仓库的 {release_tag} 版本中下载名为 {name} 的模型文件,并保存到本地路径 {checkpoint}。
- nd2py.utils.init_logger(package_name: str, exp_name: str = None, log_file: str = None, info_level: Literal['debug', 'trace', 'info', 'note', 'warning', 'error', 'critical'] = 'info', file_max_size_MB: float = 50.0, file_backup_count: int = 100, show_lineno_for_all_levels: bool = False)[source]#
Initialize the logger for the package. Args: - package_name: The name of the package / project, used in loggin.getLogger({package_name}.{path}.{to}.{file}). - exp_name: The name of the experiment, used in log prefix. - log_file: The path to the log file. If None, no file logging is performed. - info_level: The level of info logging. Can be one of ‘debug’, ‘info’, ‘note’, ‘warning’, ‘error’, ‘critical’. - file_max_size_MB: The maximum size of the log file in MB. Default is 50MB. - file_backup_count: The number of backup files to keep. Default is 100.
- nd2py.utils.render_python(text: str, width=120, highlight_lines=[], theme='staroffice') str[source]#
Subpackages#
Submodules#
nd2py.utils.attr_dict module#
nd2py.utils.auto_gpu module#
- class nd2py.utils.auto_gpu.AutoGPU[source]#
Bases:
objectAutomatically choose a GPU with enough free memory
nd2py.utils.classproperty module#
nd2py.utils.fix_parser module#
nd2py.utils.logger module#
- nd2py.utils.logger.init_logger(package_name: str, exp_name: str = None, log_file: str = None, info_level: Literal['debug', 'trace', 'info', 'note', 'warning', 'error', 'critical'] = 'info', file_max_size_MB: float = 50.0, file_backup_count: int = 100, show_lineno_for_all_levels: bool = False)[source]#
Initialize the logger for the package. Args: - package_name: The name of the package / project, used in loggin.getLogger({package_name}.{path}.{to}.{file}). - exp_name: The name of the experiment, used in log prefix. - log_file: The path to the log file. If None, no file logging is performed. - info_level: The level of info logging. Can be one of ‘debug’, ‘info’, ‘note’, ‘warning’, ‘error’, ‘critical’. - file_max_size_MB: The maximum size of the log file in MB. Default is 50MB. - file_backup_count: The number of backup files to keep. Default is 100.
nd2py.utils.metrics module#
nd2py.utils.plot module#
- nd2py.utils.plot.get_fig(RN, CN, FW=None, FH=None, AW=None, AH=None, A_ratio=1.0, LM=3, RM=3, TM=3, BM=3, HS=None, VS=None, dpi=300, fontsize=7, lw=0.5, gridspec=False, **kwargs)[source]#
- nd2py.utils.plot.plot_resilience(f: callable, extent=(0, 1, 0, 1), gridnum=(1000, 1000), cmap=None, norm=None, ax=None, reset_xylim=True, lw=1)[source]#
绘制二维函数的韧性 - f: 二维函数,如 lambda x, y: y - 3*y**2 - y**3 + x*y**3 - extent: 函数定义域 (xmin, xmax, ymin, ymax) - gridnum: 网格数量 (xnum, ynum) — Example: >>> f = lambda x, y: y - 3*y**2 - y**3 + x*y**3 >>> plot_resilience(f, ax=axes[0], extent=(0, 5, 0, 5)) >>> f = lambda x, y: np.sin(np.sqrt(x**2 + y ** 2)) >>> plot_resilience(f, ax=axes[1], extent=(-4*np.pi, 4*np.pi, -4*np.pi, 4*np.pi)) >>> f = lambda x, y: np.sin(np.sqrt(x ** 2 + y ** 2)) * x - y * np.cos(np.sqrt(x ** 2 + y ** 2)) >>> plot_resilience(f, ax=axes[2], extent=(-4*np.pi, 4*np.pi, -4*np.pi, 4*np.pi))
- class nd2py.utils.plot.EqualizeNormalize(samples, clip=False)[source]#
Bases:
Normalize按分布而非值进行归一化
- __init__(samples, clip=False)[source]#
- Parameters:
vmin (float or None) – Values within the range
[vmin, vmax]from the input data will be linearly mapped to[0, 1]. If either vmin or vmax is not provided, they default to the minimum and maximum values of the input, respectively.vmax (float or None) – Values within the range
[vmin, vmax]from the input data will be linearly mapped to[0, 1]. If either vmin or vmax is not provided, they default to the minimum and maximum values of the input, respectively.clip (bool, default: False) –
Determines the behavior for mapping values outside the range
[vmin, vmax].If clipping is off, values outside the range
[vmin, vmax]are also transformed, resulting in values outside[0, 1]. This behavior is usually desirable, as colormaps can mark these under and over values with specific colors.If clipping is on, values below vmin are mapped to 0 and values above vmax are mapped to 1. Such values become indistinguishable from regular boundary values, which may cause misinterpretation of the data.
Notes
If
vmin == vmax, input data will be mapped to 0.
- nd2py.utils.plot.plotOD(ax, source: List[str], destination: List[str], flow: List[float], location: Dict[str, Tuple[float, float]], linetype: Literal['straight', 'parabola', 'rotated_parabola', 'projected_parabola'] = 'straight', N=100, zorder=10, **kwargs)[source]#
绘制OD流量
- nd2py.utils.plot.clear_svg(path, debug=False)[source]#
matplotlib 生成的 svg 中会使用 <text style=”font: 9.8px ‘Arial’; text-anchor: middle” x=”80.307802” y=”193.900483”>2020-02-02</text> 的语法,而 Powerpoint 无法识别 font: 9.8px ‘Arial’; 的简写记法,只能识别 font-family: ‘Arial’; font-size: 9.8px; 的记法。因此需要进行转换。考虑的属性包括: - font-size - font-family - font-weight - font-style
- nd2py.utils.plot.load_font()[source]#
plt.title(“示例图表:数字平方”, fontproperties=font, size=15)
plt.xlabel(“数字”, fontproperties=font, size=12)
plt.ylabel(“平方”, fontproperties=font, size=12)
nd2py.utils.render_markdown module#
nd2py.utils.render_python module#
nd2py.utils.softmax module#
- nd2py.utils.softmax.__init__(*args, **kwargs)#
Initialize self. See help(type(self)) for accurate signature.
nd2py.utils.tag2ansi module#
nd2py.utils.timing module#
Lightweight timing utilities for optional performance diagnostics.
- class nd2py.utils.timing.Timer(unit='iter')[source]#
Bases:
object- property time#
- property count#
- property pace#
- property speed#
- class nd2py.utils.timing.NamedTimer(unit='iter')[source]#
Bases:
Timer- to_str(mode: Literal['time', 'count', 'pace', 'speed'] = 'pace', mode_of_detail: Literal['time', 'count', 'pace', 'speed'] | None = 'pace', mode_of_percent: Literal['by_time', 'by_count'] | None = 'by_time')[source]#
- property names#
- property time#
- property count#
- property named_time#
- property named_count#
- property named_pace#
- property named_speed#
- class nd2py.utils.timing.ParallelTimer(unit='iter')[source]#
Bases:
Timer- to_str(mode: Literal['time', 'count', 'pace', 'speed'] = 'pace', mode_of_detail: Literal['time', 'count', 'pace', 'speed'] | None = 'pace', mode_of_percent: Literal['by_time', 'by_count'] | None = 'by_time')[source]#
- property names#
- property count#
- property named_time#
- property named_count#
- property named_pace#
- property named_speed#