Types
Equations
Equations are specified as binary trees with the Node type, defined as follows.
DynamicExpressions.NodeModule.Node Type
Node{T,D} <: AbstractExpressionNode{T,D}Node defines a symbolic expression stored in a binary tree. A single Node instance is one "node" of this tree, and has references to its children. By tracing through the children nodes, you can evaluate or print a given expression.
Fields
degree::UInt8: Degree of the node. 0 for constants, 1 for unary operators, 2 for binary operators, etc. Maximum ofD.constant::Bool: Whether the node is a constant.val::T: Value of the node. Ifdegree==0, andconstant==true, this is the value of the constant. It has a type specified by the overall type of theNode(e.g.,Float64).feature::UInt16: Index of the feature to use in the case of a feature node. Only defined ifdegree == 0 && constant == false.op::UInt8: Ifdegree==1, this is the index of the operator inoperators.unaops. Ifdegree==2, this is the index of the operator inoperators.binops. In other words, this is an enum of the operators, and is dependent on the specificOperatorEnumobject. Only defined ifdegree >= 1children::NTuple{D,Node{T,D}}: Children of the node. Only defined up todegree
For accessing and modifying children, use get_child, set_child!, get_children, and set_children!.
Constructors
Node([T]; val=nothing, feature=nothing, op=nothing, children=nothing, allocator=default_allocator)
Node{T}(; val=nothing, feature=nothing, op=nothing, children=nothing, allocator=default_allocator)Create a new node in an expression tree. If T is not specified in either the type or the first argument, it will be inferred from the value of val passed or the children. The children keyword is used to pass in a collection of children nodes.
You may also construct nodes via the convenience operators generated by creating an OperatorEnum.
You may also choose to specify a default memory allocator for the node other than simply Node{T}() in the allocator keyword argument.
When you create an Options object, the operators passed are also re-defined for Node types. This allows you use, e.g., t=Node(; feature=1) * 3f0 to create a tree, so long as * was specified as a binary operator. This works automatically for operators defined in Base, although you can also get this to work for user-defined operators by using @extend_operators:
SymbolicRegression.InterfaceDynamicExpressionsModule.@extend_operators Macro
@extend_operators optionsExtends all operators defined in this options object to work on the AbstractExpressionNode type. While by default this is already done for operators defined in Base when you create an options and pass define_helper_functions=true, this does not apply to the user-defined operators. Thus, to do so, you must apply this macro to the operator enum in the same module you have the operators defined.
When using these node constructors, types will automatically be promoted. You can convert the type of a node using convert:
Missing docstring.
Missing docstring for convert(::Type{Node{T1}}, tree::Node{T2}) where {T1, T2}. Check Documenter's build log for details.
You can set a tree (in-place) with set_node!:
DynamicExpressions.NodeModule.set_node! Function
set_node!(tree::AbstractExpressionNode{T}, new_tree::AbstractExpressionNode{T}) where {T}Set every field of tree equal to the corresponding field of new_tree.
You can create a copy of a node with copy_node:
DynamicExpressions.NodeModule.copy_node Method
copy_node(tree::AbstractExpressionNode; break_sharing::Val{BS}=Val(false)) where {BS}Copy a node, recursively copying all children nodes. This is more efficient than the built-in copy.
If break_sharing is set to Val(true), sharing in a tree will be ignored.
Expressions
Expressions are represented using the Expression type, which combines the raw Node type with an OperatorEnum.
DynamicExpressions.ExpressionModule.Expression Type
Expression{T, N, D} <: AbstractExpression{T, N}(Experimental) Defines a high-level, user-facing, expression type that encapsulates an expression tree (like Node) along with associated metadata for evaluation and rendering.
Fields
tree::N: The root node of the raw expression tree.metadata::Metadata{D}: A named tuple of settings for the expression, such as the operators and variable names.
Constructors
Expression(tree::AbstractExpressionNode, metadata::NamedTuple): Construct from the fields@parse_expression(expr, operators=operators, variable_names=variable_names, node_type=Node): Parse a Julia expression with a given context and create an Expression object.
Usage
This type is intended for end-users to interact with and manipulate expressions at a high level, abstracting away the complexities of the underlying expression tree operations.
sourceSymbolicRegression.CoreModule.ExpressionSpecModule.ExpressionSpec Type
ExpressionSpec <: AbstractExpressionSpec(Experimental) Default specification for basic expressions without special options.
sourceThese types allow you to define and manipulate expressions with a clear separation between the structure and the operators used.
Template Expressions
Template expressions allow you to specify predefined structures and constraints for your expressions. These use ComposableExpressions as their internal expression type, which makes them flexible for creating a structure out of a single function.
These use the TemplateStructure type to define how expressions should be combined and evaluated.
SymbolicRegression.TemplateExpressionModule.TemplateExpression Type
TemplateExpression{T,F,N,E,TS,D} <: AbstractExpression{T,N}A symbolic expression that allows the combination of multiple sub-expressions in a structured way, with constraints on variable usage.
TemplateExpression is designed for symbolic regression tasks where domain-specific knowledge or constraints must be imposed on the model's structure.
Constructor
TemplateExpression(trees; structure, operators, variable_names)trees: ANamedTupleholding the sub-expressions (e.g.,f = Expression(...),g = Expression(...)).structure: ATemplateStructurewhich holds functions that define how the sub-expressions are combined in different contexts.operators: AnOperatorEnumthat defines the allowed operators for the sub-expressions.variable_names: An optionalVectorofStringthat defines the names of the variables in the dataset.
Example
Let's create an example TemplateExpression that combines two sub-expressions f(x1, x2) and g(x3):
# Define operators and variable names
options = Options(; binary_operators=(+, *, /, -), unary_operators=(sin, cos))
operators = options.operators
variable_names = ["x1", "x2", "x3"]
# Create sub-expressions
x1 = Expression(Node{Float64}(; feature=1); operators, variable_names)
x2 = Expression(Node{Float64}(; feature=2); operators, variable_names)
x3 = Expression(Node{Float64}(; feature=3); operators, variable_names)
# Create TemplateExpression
example_expr = (; f=x1, g=x3)
st_expr = TemplateExpression(
example_expr;
structure=TemplateStructure{(:f, :g)}(
((; f, g), (x1, x2, x3)) -> sin(f(x1, x2)) + g(x3)^2
),
operators,
variable_names,
)When fitting a model in SymbolicRegression.jl, you can provide expression_spec=TemplateExpressionSpec(; structure=TemplateStructure(...)) as an option. The variable_constraints will constraint f to only have access to x1 and x2, and g to only have access to x3.
SymbolicRegression.TemplateExpressionModule.TemplateStructure Type
TemplateStructure{K,E,NF} <: FunctionA struct that defines a prescribed structure for a TemplateExpression, including functions that define the result in different contexts.
The K parameter is used to specify the symbols representing the inner expressions. If not declared using the constructor TemplateStructure{K}(...), the keys of the variable_constraints NamedTuple will be used to infer this.
The Kp parameter is used to specify the symbols representing the parameters, if any.
Fields
combine: Required function taking aNamedTupleofComposableExpressions (sharing the keysK), and then tuple representing the data ofValidVectors. For example,((; f, g), (x1, x2, x3)) -> f(x1, x2) + g(x3)would be a validcombinefunction. You may also re-use the callable expressions and use different inputs, such as((; f, g), (x1, x2)) -> f(x1 + g(x2)) - g(x1)is another valid choice.num_features: OptionalNamedTupleof function keys => integers representing the number of features used by each expression. If not provided, it will be inferred using thecombinefunction. For example, ifftakes two arguments, andgtakes one, thennum_features = (; f=2, g=1).num_parameters: OptionalNamedTupleof parameter keys => integers representing the number of parameters required for each parameter vector.
SymbolicRegression.TemplateExpressionModule.TemplateExpressionSpec Type
TemplateExpressionSpec <: AbstractExpressionSpec(Experimental) Specification for template expressions with pre-defined structure.
sourceYou can use the @template_spec macro as an easy way to create a TemplateExpressionSpec:
Missing docstring.
Missing docstring for @template_spec. Check Documenter's build log for details.
Composable expressions are used internally by TemplateExpression and allow you to combine multiple expressions together.
SymbolicRegression.ComposableExpressionModule.ComposableExpression Type
ComposableExpression{T,N,D} <: AbstractComposableExpression{T,N} <: AbstractExpression{T,N}A symbolic expression representing a mathematical formula as an expression tree (tree::N) with associated metadata (metadata::Metadata{D}). Used to construct and manipulate expressions in symbolic regression tasks.
Example:
Create variables x1 and x2, and build an expression f = x1 * sin(x2):
operators = OperatorEnum(; binary_operators=(+, *, /, -), unary_operators=(sin, cos))
variable_names = ["x1", "x2"]
x1 = ComposableExpression(Node(Float64; feature=1); operators, variable_names)
x2 = ComposableExpression(Node(Float64; feature=2); operators, variable_names)
f = x1 * sin(x2)
# ^This now references the first and second arguments of things passed to it:
f(x1, x1) # == x1 * sin(x1)
f(randn(5), randn(5)) # == randn(5) .* sin.(randn(5))
# You can even pass it to itself:
f(f, f) # == (x1 * sin(x2)) * sin((x1 * sin(x2)))Parametric Expressions
Parametric expressions are a type of expression that includes parameters which can be optimized during the search.
DynamicExpressions.ParametricExpressionModule.ParametricExpression Type
ParametricExpression{T,N<:ParametricNode{T},D<:NamedTuple} <: AbstractExpression{T,N}(Experimental) An expression to store parameters for a tree
sourceDynamicExpressions.ParametricExpressionModule.ParametricNode Type
A type of expression node that also stores a parameter index
sourceSymbolicRegression.ParametricExpressionModule.ParametricExpressionSpec Type
ParametricExpressionSpec <: AbstractExpressionSpecWarning
ParametricExpressionSpec is no longer recommended. Please use @template_spec (creating a TemplateExpressionSpec) instead.
(Experimental) Specification for parametric expressions with configurable maximum parameters.
sourceThese types allow you to define expressions with parameters that can be tuned to fit the data better. You can specify the maximum number of parameters using the expression_options argument in SRRegressor.
Population
Groups of equations are given as a population, which is an array of trees tagged with cost, loss, and birthdate–-these values are given in the PopMember.
SymbolicRegression.PopulationModule.Population Type
Population(pop::Array{PopMember{T,L}, 1})Create population from list of PopMembers.
sourcePopulation(dataset::Dataset{T,L};
population_size, nlength::Int=3, options::AbstractOptions,
nfeatures::Int)Create random population and evaluate them on the dataset.
sourcePopulation(X::AbstractMatrix{T}, y::AbstractVector{T};
population_size, nlength::Int=3,
options::AbstractOptions, nfeatures::Int,
loss_type::Type=Nothing)Create random population and score them on the dataset.
sourcePopulation members
SymbolicRegression.PopMemberModule.PopMember Type
PopMember(t::AbstractExpression{T}, cost::L, loss::L)Create a population member with a birth date at the current time. The type of the Node may be different from the type of the cost and loss.
Arguments
t::AbstractExpression{T}: The tree for the population member.cost::L: The cost (normalized to a baseline, and offset by a complexity penalty)loss::L: The raw loss to assign.
PopMember(
dataset::Dataset{T,L},
t::AbstractExpression{T},
options::AbstractOptions
)Create a population member with a birth date at the current time. Automatically compute the cost for this tree.
Arguments
dataset::Dataset{T,L}: The dataset to evaluate the tree on.t::AbstractExpression{T}: The tree for the population member.options::AbstractOptions: What options to use.
Hall of Fame
SymbolicRegression.HallOfFameModule.HallOfFame Type
HallOfFame{T<:DATA_TYPE,L<:LOSS_TYPE,N<:AbstractExpression{T}}List of the best members seen all time in .members, with .members[c] being the best member seen at complexity c. Including only the members which actually have been set, you can run .members[exists].
Fields
members::Array{PopMember{T,L,N},1}: List of the best members seen all time. These are ordered by complexity, with.members[1]the member with complexity 1.exists::Array{Bool,1}: Whether the member at the given complexity has been set.
Dataset
SymbolicRegression.CoreModule.DatasetModule.Dataset Type
Dataset{T<:DATA_TYPE,L<:LOSS_TYPE}Abstract type for all dataset types in SymbolicRegression.jl.
sourceSymbolicRegression.LossFunctionsModule.update_baseline_loss! Function
update_baseline_loss!(dataset::Dataset{T,L}, options::AbstractOptions) where {T<:DATA_TYPE,L<:LOSS_TYPE}Update the baseline loss of the dataset using the loss function specified in options.