<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://symreg.at/feed.xml" rel="self" type="application/atom+xml" /><link href="https://symreg.at/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-07-02T13:32:22+00:00</updated><id>https://symreg.at/feed.xml</id><title type="html">SymReg</title><subtitle>Website about Symbolic Regression (SymReg).</subtitle><author><name>Gabriel Kronberger</name></author><entry><title type="html">Review of the WCCI/CEC 2026 Symbolic Regression Workshop</title><link href="https://symreg.at/blog/2026/wcci-cec-symbolic-regression-workshop/" rel="alternate" type="text/html" title="Review of the WCCI/CEC 2026 Symbolic Regression Workshop" /><published>2026-06-23T13:00:00+00:00</published><updated>2026-06-23T13:00:00+00:00</updated><id>https://symreg.at/blog/2026/wcci-cec-symbolic-regression-workshop</id><content type="html" xml:base="https://symreg.at/blog/2026/wcci-cec-symbolic-regression-workshop/"><![CDATA[<p>Post by Gabriel Kronberger <a href="https://www.linkedin.com/in/gabriel-kronberger-89a09450/">LinkedIn</a></p>
<p>We organized the <a href="https://heal.heuristiclab.com/research/symbolic-regression-workshop">Workshop on Symbolic Regression and Equation Discovery</a> as a subevent within WCCI/CEC 2026 in Maastricht, Netherlands this year. After several years of hosting it at GECCO, it was a great opportunity for meeting new people, discussing SR developments, and sharing ideas.</p>
<p>For the first time, we used OpenReview as a platform to organize paper submissions and reviews. We received 8 submissions and accepted 5 papers, which were presented during the workshop. The accepted papers and review discussions are <a href="https://openreview.net/group?id=IEEE.org/WCCI/2026/Workshop/SymReg&amp;referrer=%5BHomepage%5D(%2F)#tab-accept-oral">archived on OpenReview</a>.</p>
<!--more-->
<h2 id="workshop-overview">Workshop Overview</h2>
<div class="row">
    <div class="col-lg-7 col-md-12 text-center">
        <figure class="image-box">
            <img src="/blog/resources/2026-06-23-wcci-cec-symbolic-regression-workshop/wcci.jpg" id="wcci-logo">
        </figure>
    </div>
    <div class="col-lg-7 col-md-12 text-center">
        <figure class="image-box">
            <img src="/blog/resources/2026-06-23-wcci-cec-symbolic-regression-workshop/symreg-banner.png" id="symreg-banner">
        </figure>
    </div>
</div>
<h3 id="program">Program</h3>
<p>Two invited talks and four contributed talks were presented during the workshop.</p>
<ul>
<li><strong>Invited Talk:</strong> <em>&quot;Exhaustive Symbolic Regression: Learning Physics directly from Data&quot;</em>, Harry Desmond</li>
<li><em>&quot;Learning Parametric Nitrogen Fertilizer Response Curves Using Neuro Symbolic Regression&quot;</em>, Giorgio Morales, John Sheppard</li>
<li><em>&quot;SRToolkit: Shared Infrastructure for Symbolic Regression Research&quot;</em>, Sebastian Mežnar, Ljupco Todorovski, Sašo Džeroski</li>
<li><strong>Invited Talk:</strong> <em>&quot;Evolution of mutation + Genetic and agentic symbolic regression of distributed rate-and-state friction models&quot;</em>, Marco Virgolin</li>
<li><em>&quot;Prediction Intervals and Confidence Regions for Symbolic Regression Models based on Likelihood Profiles&quot;</em>, Fabricio Olivetti de Franca, Gabriel Kronberger</li>
<li><em>&quot;Generalized Residuals Symbolic Regression&quot;</em>, Rory Sweeney, Takfarinas Saber, James McDermott</li>
</ul>
<p><a href="https://www.port.ac.uk/about-us/structure-and-governance/our-people/our-staff/harry-desmond">Harry Desmond</a> presented  exhaustive symbolic regression and in particular their formulation for the calculation of total description length of symbolic regression models, combining model accuracy and complexity for ranking expressions. He then presented several applications and their results in astrophysics including modeling of universe expansion and the radial acceleration relation of galaxies.</p>
<p><a href="https://marcovirgolin.github.io/">Marco Virgolin</a> gave a nice overview of different approaches to mutation in the history of symbolic regression, from initial &quot;tree twiddling&quot; operators to agentic LLM-based approaches. He discussed them within a unified framework of expression variation operators in different algorithms. A short demo in the end showed how agentic-AI based on LLMs can be useful for finding equations in settings where a single evaluation is expensive, such as in physics simulations.</p>
<p>The main takeaway from Marco's talk is that if fitness evaluation is costly, it is worth to use more informed mutation operators to guide the search, while for cheap fitness evaluation, simple mutation operators are sufficient.
Make sure to check out his <a href="https://github.com/Unlayer-AI/automodel">automodel skill</a>.
Application to tyre friction modelling: <a href="https://github.com/Unlayer-AI/friction-modeling-symreg2026">https://github.com/Unlayer-AI/friction-modeling-symreg2026</a></p>
<h3 id="discussion">Discussion</h3>
<p>The workshop concluded with a discussion session on relevant future research directions for symbolic regression.</p>
<p>The discussion revolved around <strong>integration of prior knowledge</strong> into symbolic regression. Some partial solutions which are often application-specific have been proposed e.g. for limit behavior, symmetries, structural preferences [<a href="http://doi.org/10.1145/3377930.3390152">1</a>, <a href="https://doi.org/10.1162/evco_a_00294">2</a>, <a href="https://doi.org/10.1155/2016/1021378">3</a>]. However, it is unclear how those can be expressed, generally to allow SR search processes to consider diverse background knowledge.
In a Bayesian formulation we could potentially express this using priors. There are also other possibilities, such as integrated directly into ML loss functions or as secondary objectives.
A study was mentioned where neural networks were used in an interactive learning scenario to learn human preferences using interactive feedback from pairwise comparisons.
LLMs may provide another avenue for understanding and reacting to background knowledge in written form. The potential of using fuzzy computing ideas for handling human preferences was also mentioned.</p>
<p>Another topic that was raised is that SR community could benefit from research directed into <strong>describing SR algorithm behavior</strong>. A lot of comparison of methods is based on the results only, i.e. whether method A beats method B in performance. Currently, there is a lot of momentum in the development of different SR methods also in related AI-focussed domains, but there is no clear understanding of the (dis)similarities of methods. How can all of this busyness be directed to develop something substantially new, to prevent that we are re-inventing / discussing the same things over and over again? Visualizations of algorithm internals, such as inheritance patterns, diversity, or inheritability of solution properties could be especially insightful to get a better understanding of algorithm behavior.</p>
<p><strong>Handling uncertainty in SR</strong> was a topic in multiple presentations: in the form of uncertainty-aware model selection (based on DL, or Bayesian information criterion) which automatically prefers less complex models when data is scarce or noisy, and for calculating parameter confidence intervals and prediction intervals for symbolic regression models.</p>
<p>Prior work looking into using symbolic regression with <strong>vectorial input values</strong> was briefly discussed as well [<a href="https://link.springer.com/chapter/10.1007/978-3-030-16670-0_14">4</a>, <a href="https://dl.acm.org/doi/abs/10.1145/3583133.3590695">5</a>, <a href="https://link.springer.com/chapter/10.1007/978-981-16-8113-4_2">6</a>, <a href="https://arxiv.org/abs/2303.03200">7</a>].</p>
<h3 id="plans-for-2027">Plans for 2027</h3>
<p>We are still undecided where to host the next workshop in 2027. We are <strong>considering both GECCO and CEC</strong>, and we will announce the location and dates on the workshop website once decided.</p>
<p>We are also interested in <strong>hosting a symbolic regression / equation discovery workshop at one of the large AI conferences</strong> (NeurIPS, ICML, ICLR, AAAI, IJCAI) in 2027. If you are interested in co-organizing such a workshop, please <a href="mailto:gabriel.kronberger@fh-hagenberg.at">contact us</a>.</p>
<p>Additionally, we try to host <strong>a small, in-depth, invitation-only multi-day SymReg event</strong> most likely in the EU in 2027. Let us know if you are interested in participating in such an event.</p>
<p>Finally, I want to thank my co-organizers: Fabricio Olivetti, William LaCava and Steven Gustafson as well as the members of the Programme Committee (Deaglan J. Bartlett, Geoffrey F. Bomarito, Harry Desmond, Alcides Fonseca, Johannes Koch, Alessandro Lucantonio, James McDermott, Julia Reuter, Colm O'Riordan, Giovanni Squillero, Alberto Tonda, Leonardo Trujillo, Bernhard Werth, Stephan Winkler, Aisha Yousuf) for their help in reviewing the submitted papers.</p>]]></content><author><name>Gabriel Kronberger</name></author><category term="science" /><summary type="html"><![CDATA[Post by Gabriel Kronberger LinkedIn We organized the Workshop on Symbolic Regression and Equation Discovery as a subevent within WCCI/CEC 2026 in Maastricht, Netherlands this year. After several years of hosting it at GECCO, it was a great opportunity for meeting new people, discussing SR developments, and sharing ideas. For the first time, we used OpenReview as a platform to organize paper submissions and reviews. We received 8 submissions and accepted 5 papers, which were presented during the workshop. The accepted papers and review discussions are archived on OpenReview.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://symreg.at/blog/resources/2026-06-23-wcci-cec-symbolic-regression-workshop/wcci.jpg" /><media:content medium="image" url="https://symreg.at/blog/resources/2026-06-23-wcci-cec-symbolic-regression-workshop/wcci.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">A Powerful Database for Equations: Using e-graphs and Equality Saturation for Interactive Equation Discovery</title><link href="https://symreg.at/blog/2025/a-powerful-database-for-expressions/" rel="alternate" type="text/html" title="A Powerful Database for Equations: Using e-graphs and Equality Saturation for Interactive Equation Discovery" /><published>2025-11-30T10:00:00+00:00</published><updated>2025-11-30T10:00:00+00:00</updated><id>https://symreg.at/blog/2025/a-powerful-database-for-expressions</id><content type="html" xml:base="https://symreg.at/blog/2025/a-powerful-database-for-expressions/"><![CDATA[<p>Post by Fabricio Olivetti de França (<a href="https://scholar.google.com/citations?user=1FgxaZ0AAAAJ">Scholar</a>, <a href="https://www.linkedin.com/in/olivetti/">Linkedin</a>)</p>
<p>In the last post we introduced the idea of e-graphs and how it can play an important role with <strong>equation discovery</strong> (aka <strong>symbolic regression</strong>). We also introduced <strong><a href="https://github.com/folivetti/eggp">eggp</a></strong> <a href="#1">[1]</a>, the first equation discovery algorithm that takes advantage of e-graphs by using it as a powerful database system and enforce novelty.</p>
<p>We also briefly introduced <strong><a href="https://github.com/folivetti/reggression">r🥚ression</a></strong> <a href="#2">[2]</a>, a Python tool that allows us to explore the power of e-graphs in different scenario. In this post, we will play a bit more with this tool to show how powerful e-graphs can be as a go to tool for equation discovery.</p>
<p>For a gentle introduction to e-graphs and equality saturation, see the <a href="/blog/2025/equality-saturation-and-symbolic-regression/">previous part of this blog post</a>.</p>
<!--more-->
<h2 id="first-things-first">First things first</h2>
<p>For this experiment, we will use a dataset generated from the function below (inspired by the Salustowicz function <a href="#3">[3]</a> <a href="#10">[10]</a>):</p>
<p>$$
e^{-x/1.2}, x^3  \left(\cos(x), \sin(x)^2 - 3.1415\right)
$$</p>
<p>Let's generate data points in the range $[0, 10]$ while adding a bit of Gaussian noise:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">)</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">x</span><span class="o">/</span><span class="mf">1.2</span><span class="p">)</span><span class="o">*</span><span class="n">x</span><span class="o">**</span><span class="mi">3</span><span class="o">*</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="n">cos</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> \
    <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="mf">3.1415</span><span class="p">)</span> \
    <span class="o">+</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="n">normal</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mf">0.05</span><span class="p">,</span> <span class="n">x</span><span class="p">.</span><span class="n">shape</span><span class="p">)</span>
</code></pre></div></div>
<p>To make things a bit more interesting for this post, we will use just the middle part for training and the rest as a test set:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">lb</span><span class="p">,</span> <span class="n">ub</span> <span class="o">=</span> <span class="mf">2.1</span><span class="p">,</span> <span class="mi">5</span>
<span class="n">x_sel</span> <span class="o">=</span> <span class="n">x</span><span class="p">[(</span><span class="n">x</span><span class="o">&gt;</span><span class="n">lb</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">x</span><span class="o">&lt;</span><span class="n">ub</span><span class="p">)].</span><span class="n">reshape</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
<span class="n">y_sel</span> <span class="o">=</span> <span class="n">y</span><span class="p">[(</span><span class="n">x</span><span class="o">&gt;</span><span class="n">lb</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">x</span><span class="o">&lt;</span><span class="n">ub</span><span class="p">)]</span>
<span class="n">x_ood</span> <span class="o">=</span> <span class="n">x</span><span class="p">[(</span><span class="n">x</span><span class="o">&lt;=</span><span class="n">lb</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">x</span><span class="o">&gt;=</span><span class="n">ub</span><span class="p">)].</span><span class="n">reshape</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">y_ood</span> <span class="o">=</span> <span class="n">y</span><span class="p">[(</span><span class="n">x</span><span class="o">&lt;=</span><span class="n">lb</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">x</span><span class="o">&gt;=</span><span class="n">ub</span><span class="p">)]</span>
</code></pre></div></div>
<p>Plotting the training set as red dots and the test set as green dots, we have:</p>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto;" src="/blog/resources/2025-12-01-a-powerful-database-for-expressions/data.svg" id="benchmark dataset" alt="Training and test data used in the e-graph symbolic regression example" loading="lazy">
    </figure>
</div>
<p>We are, of course, making things harder for symbolic regression:</p>
<ol>
<li>The relationship is nonlinear.</li>
<li>The training set is insufficient to guarantee an unique global optima.</li>
</ol>
<p>In any case, the purpose here is to show how we can use r🥚ression to explore alternative models.</p>
<h2 id="laying-the-egg-">Laying the egg 🥚</h2>
<p>We can create an initial e-graph for this dataset using <code>eggp</code>. As mentioned <a href="/blog/2025/equality-saturation-and-symbolic-regression/">in the previous post</a>, this algorithm uses e-graphs to enforce the generation of new expressions, avoiding redundancy in the search.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">eggp</span> <span class="kn">import</span> <span class="n">EGGP</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="n">reg</span> <span class="o">=</span> <span class="n">EGGP</span><span class="p">(</span><span class="n">gen</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">nPop</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">maxSize</span><span class="o">=</span><span class="mi">25</span><span class="p">,</span> \
      <span class="n">nonterminals</span><span class="o">=</span><span class="s">"add,sub,mul,div,log,power,sin,cos,abs,sqrt"</span><span class="p">,</span> \
      <span class="n">simplify</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">optRepeat</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">optIter</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">folds</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span>  \
      <span class="n">dumpTo</span><span class="o">=</span><span class="s">"vlad.egg"</span><span class="p">)</span>
<span class="n">reg</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">x_sel</span><span class="p">,</span> <span class="n">y_sel</span><span class="p">)</span>
</code></pre></div></div>
<p>Some observations:</p>
<ul>
<li>The non-terminal set is large in order to generate many different alternative models.</li>
<li>We are not running for a large number of iterations, so we could possibly find better models with proper settings.</li>
<li>The maximum size is larger than the true equation.</li>
</ul>
<p>We are saving the final e-graph into the file named <code>vlad.egg</code> so we can explore it after the search.
Looking at the results we can see the Pareto front with different trade-offs of accuracy and size.</p>
<table>
<thead>
<tr>
<th align="left">Math</th>
<th align="right">size</th>
<th align="right">loss_train</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">$$\theta_{0}$$</td>
<td align="right">1</td>
<td align="right">0.360495</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \operatorname{cos}(x_{0})\right)$$</td>
<td align="right">4</td>
<td align="right">0.319114</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \frac{\theta_{1}}{x_{0}}\right)$$</td>
<td align="right">5</td>
<td align="right">0.318433</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + (\left(\theta_{1} - x_{0}\right))^2\right)$$</td>
<td align="right">6</td>
<td align="right">0.0641624</td>
</tr>
<tr>
<td align="left">$$\left(\left(\operatorname{cos}(x_{0}) \cdot \left(x_{0} + \theta_{0}\right)\right) + \theta_{1}\right)$$</td>
<td align="right">8</td>
<td align="right">0.0421559</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\operatorname{cos}(\left(\theta_{1} + \operatorname{cos}(x_{0})\right)) \cdot x_{0}\right)\right)$$</td>
<td align="right">9</td>
<td align="right">0.012507</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\operatorname{cos}(\left(\theta_{1} + \operatorname{cos}(x_{0})\right)) \cdot \left(\theta_{2} \cdot x_{0}\right)\right)\right)$$</td>
<td align="right">11</td>
<td align="right">0.00899634</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\operatorname{cos}(\operatorname{cos}(x_{0})) \cdot \left(\theta_{1} \cdot \operatorname{cos}(\left(x_{0} + \theta_{2}\right))\right)\right)\right)$$</td>
<td align="right">12</td>
<td align="right">0.0046806</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} - \left(\operatorname{cos}(\operatorname{cos}(x_{0})) \cdot \left(\theta_{1} \cdot \operatorname{cos}(\left (\left(x_{0} + \theta_{2}\right)\right ))\right)\right)\right)$$</td>
<td align="right">13</td>
<td align="right">0.00481255</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\operatorname{cos}(\operatorname{cos}(x_{0})) \cdot \left(\theta_{1} \cdot \operatorname{cos}(\left(\left(\theta_{2} - x_{0}\right) + \theta_{3}\right))\right)\right)\right)$$</td>
<td align="right">14</td>
<td align="right">0.00586963</td>
</tr>
<tr>
<td align="left">$$\left(\left(\operatorname{cos}(\operatorname{cos}(x_{0})) \cdot \left(\theta_{0} \cdot \operatorname{cos}(\left(\left(\theta_{1} - \left(x_{0} + \theta_{2}\right)\right) + \theta_{3}\right))\right)\right) + \theta_{4}\right)$$</td>
<td align="right">16</td>
<td align="right">0.00547237</td>
</tr>
</tbody>
</table>
<h2 id="hatching-the-egg-">Hatching the egg 🐣</h2>
<p>Now, let's load the e-graph into <code>r🥚ression</code>:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">reggression</span> <span class="kn">import</span> <span class="n">Reggression</span>
<span class="n">egg</span> <span class="o">=</span> <span class="n">Reggression</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s">"vlad.csv"</span><span class="p">,</span> <span class="n">loadFrom</span><span class="o">=</span><span class="s">"vlad.egg"</span><span class="p">)</span>
</code></pre></div></div>
<p>If we look at the top-5 models, we can see small variations of the top performing with similar fitness (negative MSE) values.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">egg</span><span class="p">.</span><span class="n">top</span><span class="p">(</span><span class="mi">5</span><span class="p">)[[</span><span class="s">"Latex"</span><span class="p">,</span> <span class="s">"Fitness"</span><span class="p">,</span> <span class="s">"Size"</span><span class="p">]]</span>
</code></pre></div></div>
<table>
<thead>
<tr>
<th align="left">Latex</th>
<th align="right">Fitness</th>
<th align="right">Size</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">$$\left(\left(\operatorname{cos}(\operatorname{cos}(x)) \cdot \left(\theta_{0} \cdot \operatorname{cos}(\left(\left(\theta_{1} - \left(x + \theta_{2}\right)\right) + \theta_{3}\right))\right)\right) + \theta_{4}\right)$$</td>
<td align="right">-0.00415306</td>
<td align="right">16</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\operatorname{cos}(\operatorname{cos}(x)) \cdot \left(\operatorname{cos}(\left(\mid\mid\left(\left(x + \theta_{1}\right) + \theta_{2}\right)\mid\mid + \theta_{3}\right)) \cdot \theta_{4}\right)\right)\right)$$</td>
<td align="right">-0.00425244</td>
<td align="right">18</td>
</tr>
<tr>
<td align="left">$$\left(\left(\left(\operatorname{cos}(\operatorname{cos}(x)) \cdot \left(\operatorname{cos}(\left(\left(\theta_{0} - \left(x + \theta_{1}\right)\right) + \theta_{2}\right)) \cdot \theta_{3}\right)\right) + \theta_{4}\right) + \theta_{5}\right)$$</td>
<td align="right">-0.00430326</td>
<td align="right">18</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\left(\operatorname{cos}(\operatorname{cos}(x)) \cdot \left(\operatorname{cos}(\left(\mid\left(\sqrt{x}^2 + \theta_{1}\right)\mid + \theta_{2}\right)) \cdot \theta_{3}\right)\right) + \theta_{4}\right)\right)$$</td>
<td align="right">-0.00430774</td>
<td align="right">19</td>
</tr>
<tr>
<td align="left">$$\left(\theta_{0} + \left(\operatorname{cos}(\operatorname{cos}(x)) \cdot \left(\theta_{1} \cdot \operatorname{cos}(\left(\left(\theta_{2} - x\right) + \theta_{3}\right))\right)\right)\right)$$</td>
<td align="right">-0.0043503</td>
<td align="right">14</td>
</tr>
</tbody>
</table>
<p>Some of these functions behave similarly while others display a different behavior when looking outside of the training region:</p>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto;" src="/blog/resources/2025-12-01-a-powerful-database-for-expressions/top5.svg" id="top five expressions" alt="Plot comparing the top five symbolic regression expressions" loading="lazy">
    </figure>
</div>
<!-- ![](figs/top5.svg) -->
<p>We can also plot the best models while limiting the maximum size:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model_top</span><span class="p">(</span><span class="n">egg</span><span class="p">.</span><span class="n">top</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="s">"size &lt;= 10"</span><span class="p">]),</span> <span class="n">n</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
</code></pre></div></div>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto;" src="/blog/resources/2025-12-01-a-powerful-database-for-expressions/top10.svg" id="top ten expressions" alt="Plot comparing top symbolic regression expressions with maximum size ten" loading="lazy">
    </figure>
</div>
<p>We can see even more different behaviors compared to the previous plot but, sill, none of them are even close to the correct one  :-(</p>
<p>Since we are still far from the true expression, let us investigate the distribution of the tokens of the top 1000 generated expressions.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">egg</span><span class="p">.</span><span class="n">distributionOfTokens</span><span class="p">(</span><span class="n">top</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span>
</code></pre></div></div>
<p>This command returns a table with the number of times each token was used in the top expressions and the average fitness of the expressions that contains such token.  The table is ordered by average fitness (negative MSE).</p>
<table>
<thead>
<tr>
<th align="left">Pattern</th>
<th align="right">Count</th>
<th align="right">AvgFit</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">x0</td>
<td align="right">2604</td>
<td align="right">-0.00359749</td>
</tr>
<tr>
<td align="left">t0</td>
<td align="right">1006</td>
<td align="right">-0.009312</td>
</tr>
<tr>
<td align="left">t1</td>
<td align="right">981</td>
<td align="right">-0.00941213</td>
</tr>
<tr>
<td align="left">t2</td>
<td align="right">955</td>
<td align="right">-0.00937039</td>
</tr>
<tr>
<td align="left">t3</td>
<td align="right">806</td>
<td align="right">-0.00893546</td>
</tr>
<tr>
<td align="left">t4</td>
<td align="right">466</td>
<td align="right">-0.00910986</td>
</tr>
<tr>
<td align="left">t5</td>
<td align="right">144</td>
<td align="right">-0.00786632</td>
</tr>
<tr>
<td align="left">t6</td>
<td align="right">1</td>
<td align="right">-0.013187</td>
</tr>
<tr>
<td align="left">Abs(v0)</td>
<td align="right">465</td>
<td align="right">-0.00810496</td>
</tr>
<tr>
<td align="left">Sin(v0)</td>
<td align="right">74</td>
<td align="right">-0.0115615</td>
</tr>
<tr>
<td align="left">Cos(v0)</td>
<td align="right">3029</td>
<td align="right">-0.00309273</td>
</tr>
<tr>
<td align="left">Sqrt(v0)</td>
<td align="right">32</td>
<td align="right">-0.00845579</td>
</tr>
<tr>
<td align="left">Square(v0)</td>
<td align="right">27</td>
<td align="right">-0.00967352</td>
</tr>
<tr>
<td align="left">Log(v0)</td>
<td align="right">10</td>
<td align="right">-0.00972384</td>
</tr>
<tr>
<td align="left">Exp(v0)</td>
<td align="right">45</td>
<td align="right">-0.0118458</td>
</tr>
<tr>
<td align="left">Cube(v0)</td>
<td align="right">38</td>
<td align="right">-0.00867039</td>
</tr>
<tr>
<td align="left">(v0 + v1)</td>
<td align="right">3405</td>
<td align="right">-0.00275121</td>
</tr>
<tr>
<td align="left">(v0 - v1)</td>
<td align="right">351</td>
<td align="right">-0.00848634</td>
</tr>
<tr>
<td align="left">(v0 * v1)</td>
<td align="right">2139</td>
<td align="right">-0.0042415</td>
</tr>
<tr>
<td align="left">(v0 / v1)</td>
<td align="right">68</td>
<td align="right">-0.00815694</td>
</tr>
</tbody>
</table>
<p>Apart from the first rows that displays the terminals, we can see that the absolute value function is frequently used and often contributes to a lower fitness, even though it is not present in the ground-truth expression.</p>
<blockquote>
<p>When we have partial functions such as <code>log</code> and <code>sqrt</code>, the absolute value can help &quot;fixing&quot; invalid inputs.</p>
</blockquote>
<p>Sine and cosine are ranked next, but with cosine being more often used. The exponential is rarely used and particularly with a worse average fitness than the other tokens. The reason for this could be that fitting parameters inside an exponential function can be tricky depending on the initial values.</p>
<p>We can verify that by plotting the top 5 expressions with the pattern $e^{\square_0}\square_1$ with the command:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">egg</span><span class="p">.</span><span class="n">top</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="s">"exp(v0)*v1"</span><span class="p">)</span>
</code></pre></div></div>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto;" src="/blog/resources/2025-12-01-a-powerful-database-for-expressions/top5pat.svg" id="top five patterns" alt="Top five expressions matching the selected exponential pattern" loading="lazy">
    </figure>
</div>
<p>as we can see, still not a very good fit, as expected.</p>
<h2 id="with-a-little-help-from-my-friends-">With a little help from my friends 🐣🐤</h2>
<p>We can try our luck with another SR method, such as Operon <a href="#4">[4]</a>, and insert the obtained expressions into the e-graph:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pyoperon.sklearn</span> <span class="kn">import</span> <span class="n">SymbolicRegressor</span>
<span class="n">regOp</span> <span class="o">=</span> <span class="n">SymbolicRegressor</span><span class="p">(</span><span class="n">objectives</span><span class="o">=</span><span class="p">[</span><span class="s">'mse'</span><span class="p">,</span><span class="s">'length'</span><span class="p">],</span> <span class="n">max_length</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">allowed_symbols</span><span class="o">=</span><span class="s">'add,sub,mul,div,square,sin,cos,exp,log,sqrt,abs,constant,variable'</span><span class="p">)</span>
<span class="n">regOp</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">x_sel</span><span class="p">,</span> <span class="n">y_sel</span><span class="p">)</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">"equations.operon"</span><span class="p">,</span> <span class="s">"w"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">eq</span> <span class="ow">in</span> <span class="n">regOp</span><span class="p">.</span><span class="n">pareto_front_</span><span class="p">:</span>
  <span class="n">eqstr</span> <span class="o">=</span> <span class="n">regOp</span><span class="p">.</span><span class="n">get_model_string</span><span class="p">(</span><span class="n">eq</span><span class="p">[</span><span class="s">'tree'</span><span class="p">])</span>
  <span class="n">fitness</span> <span class="o">=</span> <span class="o">-</span><span class="n">eq</span><span class="p">[</span><span class="s">'mean_squared_error'</span><span class="p">]</span>
  <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">eqstr</span><span class="si">}</span><span class="s">,</span><span class="si">{</span><span class="n">fitness</span><span class="si">}</span><span class="s">,</span><span class="si">{</span><span class="n">fitness</span><span class="si">}</span><span class="s">"</span><span class="p">,</span> <span class="nb">file</span><span class="o">=</span><span class="n">f</span><span class="p">)</span>
<span class="n">f</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">egg</span><span class="p">.</span><span class="n">importFromCSV</span><span class="p">(</span><span class="s">"equations.operon"</span><span class="p">)</span>
</code></pre></div></div>
<p>Plotting the top-5 expressions we get:</p>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto;" src="/blog/resources/2025-12-01-a-powerful-database-for-expressions/top5operon.svg" id="top five expressions from operon" alt="Top five expressions after importing Operon results into the e-graph" loading="lazy">
    </figure>
</div>
<p>Still no luck! But we didn't make things easy for SR anyway!</p>
<p>We can insert the ground-truth expression to see whether the parameter optimization is capable of converging to the true parameters and if the fitness is better than what we have.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">egg</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"exp(x0/t0)*(x0^3)*(cos(x0)*(sin(x0)^2)-t1)"</span><span class="p">)</span>
</code></pre></div></div>
<table>
<thead>
<tr>
<th align="left">Latex</th>
<th align="right">Fitness</th>
<th align="left">Parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">$$\left(\left({x^{3.0}} \cdot \left(\left(\operatorname{cos}(x) \cdot {\operatorname{sin}(x)^{2.0}}\right) + \theta_{0}\right)\right) \cdot e^{\left(x \cdot \theta_{1}\right)}\right)$$</td>
<td align="right">-0.00256414</td>
<td align="left">[-3.15, -0.83]</td>
</tr>
</tbody>
</table>
<p>The answer is YES! We can get the ground-truth expression with enough iterations and a larger amount of luck :-)
Or, we can even resort to adding some constraints <a href="#5">[5]</a>...</p>
<h3 id="its-all-the-same-no-matter-where-you-are-">It's all the same, no matter where you are 🐥🐥🐥</h3>
<p>We can also use r🥚ression to check whether two or more expressions are equivalent. Let's say we want to see whether $(x+3)^2 - 9$ and $x(x + 6)$ are the same.</p>
<p>First, we create an empty e-graph:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">newegg</span> <span class="o">=</span> <span class="n">Reggression</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s">"vlad.csv"</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s">"MSE"</span><span class="p">)</span>
</code></pre></div></div>
<p>Next, we add both expressions while storing their e-class ids:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">eid1</span> <span class="o">=</span> <span class="n">egg</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"(x0 + 3)**2 - 9"</span><span class="p">).</span><span class="n">Id</span><span class="p">.</span><span class="n">values</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">eid2</span> <span class="o">=</span> <span class="n">egg</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"x0*(x0 + 6)"</span><span class="p">).</span><span class="n">Id</span><span class="p">.</span><span class="n">values</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">print</span><span class="p">(</span><span class="n">eid1</span><span class="p">,</span> <span class="n">eid2</span><span class="p">)</span>
<span class="o">&gt;</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">9</span>
</code></pre></div></div>
<p>Initially, their ids are going to be different, since until now they are distinct to each other as far as the e-graph is concerned.</p>
<p>Now, the main idea is that we run equality saturation to produce all the equivalent forms of each one of these expressions following a set of rules, such as:</p>
<p>$$
(x + y)^2 \rightarrow x^2 + y^2 + 2xy
$$</p>
<blockquote>
<p>If the set of rules are sufficient to produce at least one common expression departing from the first and from the second expressions, they will eventually be merged, and their e-class id will become the same.</p>
</blockquote>
<p>We can run some iterations of equality saturation using the command:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">egg</span><span class="p">.</span><span class="n">eqsat</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
</code></pre></div></div>
<p>And, now, their ids should be the same!</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="s">"Id of the first equation: </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">egg</span><span class="p">.</span><span class="n">report</span><span class="p">(</span><span class="n">eid1</span><span class="p">).</span><span class="n">loc</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> <span class="p">[</span><span class="s">"Info"</span><span class="p">,</span> <span class="s">"Training"</span><span class="p">]])</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Id of the second equation: </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">egg</span><span class="p">.</span><span class="n">report</span><span class="p">(</span><span class="n">eid2</span><span class="p">).</span><span class="n">loc</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> <span class="p">[</span><span class="s">"Info"</span><span class="p">,</span> <span class="s">"Training"</span><span class="p">]])</span>
<span class="o">&gt;</span> <span class="n">Id</span> <span class="n">of</span> <span class="n">the</span> <span class="n">first</span> <span class="n">equation</span><span class="p">:</span> <span class="mi">16</span>
<span class="o">&gt;</span> <span class="n">Id</span> <span class="n">of</span> <span class="n">the</span> <span class="n">second</span> <span class="n">equation</span><span class="p">:</span> <span class="mi">16</span>
</code></pre></div></div>
<p>After running equality saturation, we can also retrieve a sample of the equivalent expressions for that e-class id:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">egg</span><span class="p">.</span><span class="n">getNExpressions</span><span class="p">(</span><span class="n">eid1</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
</code></pre></div></div>
<p>Leading to:</p>
<p>$$
((6.0 + x) * x)   \\
((x + 6.0) * x)  \\
((x * 6.0) + (x ^ 2))  \\
((x * 6.0) + (x ^ 2))  \\
(0.0 + ((6.0 + x) * x))  \\
(0.0 + ((x + 6.0) * x))  \\
((2.0 * (x * 3.0)) + (x ^ 2))  \\
((2.0 * (3.0 * x)) + (x ^ 2))  \\
(((x * 3.0) * 2.0) + (x ^ 2))  \\
(((3.0 * x) * 2.0) + (x ^ 2)) \\
$$</p>
<p>This can potentially be used to integrate e-graphs with other genetic programming algorithms or even reward based algorithms such as Monte Carlo Tree Search <a href="#6">[6]</a> <a href="#7">[7]</a> and Deep Reinforcement Learning <a href="#8">[8]</a>, and LLMs <a href="#9">[9]</a>.</p>
<h2 id="stay-tuned">Stay tuned!</h2>
<p>As we can see, there is still a vast ground to be explored with the combination of e-graphs and symbolic regression! Stay tuned for our next exciting work on this topic.</p>
<h2 id="try-it-yourself">Try it yourself</h2>
<p>The full Jupyter Notebook is available <a href="https://github.com/folivetti/reggression/tree/main/tutorials/blog">here</a> and the rEGGression repository also host some <a href="https://github.com/folivetti/reggression/tree/main/tutorials">tutorials</a></p>
<h2 id="references">References</h2>
<p><a id="1">[1]</a> de França, Fabrício Olivetti, and Gabriel Kronberger. &quot;Improving Genetic Programming for Symbolic Regression with Equality Graphs.&quot; <em>Proceedings of the Genetic and Evolutionary Computation Conference</em>. 2025.</p>
<p><a id="2">[2]</a> de França, Fabrício Olivetti, and Gabriel Kronberger. &quot;rEGGression: an Interactive and Agnostic Tool for the Exploration of Symbolic Regression Models.&quot; <em>Proceedings of the Genetic and Evolutionary Computation Conference</em>. 2025.</p>
<p><a id="3">[3]</a> Vladislavleva, Ekaterina J., Guido F. Smits, and Dick Den Hertog. &quot;Order of nonlinearity as a complexity measure for models generated by symbolic regression via pareto genetic programming.&quot; <em>IEEE Transactions on Evolutionary Computation</em> 13.2 (2008): 333-349.</p>
<p><a id="4">[4]</a> Burlacu, Bogdan, Gabriel Kronberger, and Michael Kommenda. &quot;Operon C++ an efficient genetic programming framework for symbolic regression.&quot; <em>Proceedings of the 2020 genetic and evolutionary computation conference companion</em>. 2020.</p>
<p><a id="5">[5]</a> Kronberger, Gabriel, et al. &quot;Shape-constrained symbolic regression—improving extrapolation with prior knowledge.&quot; <em>Evolutionary computation</em> 30.1 (2022): 75-98.</p>
<p><a id="6">[6]</a> Kamienny, Pierre-Alexandre, et al. &quot;Deep generative symbolic regression with monte-carlo-tree-search.&quot; <em>International Conference on Machine Learning</em>. PMLR, 2023.</p>
<p><a id="7">[7]</a> Sun, Fangzheng, et al. &quot;Symbolic Physics Learner: Discovering governing equations via Monte Carlo tree search.&quot; <em>The Eleventh International Conference on Learning Representations</em>.</p>
<p><a id="8">[8]</a> Mundhenk, Terrell, et al. &quot;Symbolic regression via deep reinforcement learning enhanced genetic programming seeding.&quot; <em>Advances in Neural Information Processing Systems</em> 34 (2021): 24912-24923.</p>
<p><a id="9">[9]</a> Shojaee, Parshin, et al. &quot;LLM-SR: Scientific Equation Discovery via Programming with Large Language Models.&quot; <em>The Thirteenth International Conference on Learning Representations</em>.</p>
<p><a id="10">[10]</a> R. Salustowicz and J. Schmidhuber, &quot;Probabilistic incremental program evolution&quot;, Evolutionary Computation, vol. 5, no. 2, pp. 123–141, 1997.</p>]]></content><author><name>Fabrício Olivetti de França</name></author><category term="science" /><summary type="html"><![CDATA[Post by Fabricio Olivetti de França (Scholar, Linkedin) In the last post we introduced the idea of e-graphs and how it can play an important role with equation discovery (aka symbolic regression). We also introduced eggp [1], the first equation discovery algorithm that takes advantage of e-graphs by using it as a powerful database system and enforce novelty. We also briefly introduced r🥚ression [2], a Python tool that allows us to explore the power of e-graphs in different scenario. In this post, we will play a bit more with this tool to show how powerful e-graphs can be as a go to tool for equation discovery. For a gentle introduction to e-graphs and equality saturation, see the previous part of this blog post.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://symreg.at/blog/resources/2025-12-01-a-powerful-database-for-expressions/top5operon.svg" /><media:content medium="image" url="https://symreg.at/blog/resources/2025-12-01-a-powerful-database-for-expressions/top5operon.svg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Secret Weapon for Better Equation Discovery: E-graphs and Equality Saturation</title><link href="https://symreg.at/blog/2025/equality-saturation-and-symbolic-regression/" rel="alternate" type="text/html" title="The Secret Weapon for Better Equation Discovery: E-graphs and Equality Saturation" /><published>2025-10-26T11:00:00+00:00</published><updated>2025-10-26T11:00:00+00:00</updated><id>https://symreg.at/blog/2025/equality-saturation-and-symbolic-regression</id><content type="html" xml:base="https://symreg.at/blog/2025/equality-saturation-and-symbolic-regression/"><![CDATA[<blockquote>
<p>This guest post <em>by Fabrício Olivetti de França</em> describes the concepts of Equality Graphs and Equality Saturation and the benefits of using E-Graphs in Symbolic Regression.</p>
</blockquote>
<!--more-->
<p>In data science, physics, and engineering, the ultimate goal isn't just prediction, it's <strong>understanding</strong>. Finding a single, elegant mathematical formula that perfectly describes a set of data points is the holy grail. This is called <strong>Equation Discovery</strong> or <strong>Symbolic Regression (SR)</strong>.</p>
<p>Traditional AI models such as Artificial Neural Networks give us complex, black-box equations. SR aims for human-readable formulas (like $f(x) = \log(x) + c$).</p>
<p>To find this perfect formula, all search algorithms, whether they use Genetic Programming (GP), Monte Carlo Tree Search (MCTS), or Deep Learning (DL), follow a cycle of: proposing a candidate equation, learning from its performance, and repeating.</p>
<p>How the proposal and learning steps work depends on the algorithm:</p>
<ul>
<li><strong>Genetic Programming</strong> proposes new equations by modifying existing equations or combining them. It learns by favoring the selection of the best equations found so far.</li>
<li><strong>Monte Carlo Tree Search</strong> proposal step generates a new equation by traversing a tree of possible grammar derivations that are more probable to fit the data taking a confidence interval into consideration. It learns by updating the probabilities of each derivation.</li>
<li><strong>Deep Learning</strong> and <strong>Reinforcement Learning</strong> propose new equations by choosing the next symbol that maximizes the expected reward given the last choice. It learns by reinforcing the quality of the generated expression through the sequence of steps.</li>
</ul>
<p>The problem? The search space is unbelievably vast and filled with redundancy.</p>
<h2 id="its-all-the-same-no-matter-where-you-are">It's all the same, no matter where you are</h2>
<p>Imagine trying to navigate a forest with many paths leading to the same (wrong) destination, and you have to try them all until you follow one that leads you to your goal. That's the reality of Symbolic Regression.
Consider the simple expression $2x$. How many different ways can you write that same value?</p>
<p>$$
x+x \\
\frac{4x}{2} \\
3x-x \\
\dots \text{and many more!}
$$</p>
<p>All these expressions are mathematically identical; they will all yield the exact same result for the same dataset.</p>
<p>This redundancy creates two issues for our search algorithms:</p>
<ol>
<li>
<p><strong>Wasted Time:</strong> The algorithm might revisit $x+x$ after having already explored $2x$, wasting valuable computational budget.</p>
</li>
<li>
<p><strong>Complexity:</strong> If $x+x$ is the correct solution, we want its simplest, and most interpretable form ($2x$), not one of the infinitely complex equivalent forms. Using post-processing simplification tools often fails or introduces new problems, as we've shown in our research <a href="#1">[1]</a>.</p>
</li>
</ol>
<p>On the other hand, redundancy can be helpful. Sometimes, navigating from $x+x$ to $3x-x$ can be a &quot;stepping stone&quot; to reach a new, better area of the search space. This is known as the <strong>neutral space theory</strong> <a href="#2">[2]</a>.</p>
<p>But what if we could detect <em>all</em> equivalent expressions in real-time and use that knowledge to make the search efficient?</p>
<h2 id="a-database-for-math-expressions-the-e-graph">A database for math expressions: the E-graph</h2>
<p>The solution lies in <strong>E-graphs</strong> and <strong>Equality Saturation</strong> <a href="#3">[3]</a>.</p>
<p>Think of an e-graph as a <strong>database</strong> for mathematical expressions. It’s designed to store many different, but equivalent, expressions with a minimum amount of space. It also makes it easier to query for expressions with certain patterns.</p>
<p>In an e-graph, symbols (such as $+, -, x, \log$) are called <strong>e-nodes</strong>. The core concept is the <strong>e-class</strong>, which acts as an <strong>equivalence group</strong>. Any e-node belonging to the same e-class represents a mathematically identical value.</p>
<p>For example, in the figure below, the dashed box in the middle is an e-class. It contains two e-nodes: one for multiplication (<code>2x</code>) and one for addition (<code>x+x</code>). Because they are in the same e-class, the graph automatically knows that $2x = x+x$.</p>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto; max-width:190px" src="/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/eqexample.png" id="equality-saturation-example" alt="E-graph example showing equivalent expressions 2x and x plus x" loading="lazy">
    </figure>
</div>
<p>This structure is immensely powerful. Now, when the graph builds a larger expression, such as a term squared (the very top multiplication operator in this e-graph), it knows it can be represented in four different ways instantly:</p>
<p>$$
(2x) (2x) \\
(2x) (x+x) \\
(x+x) (2x) \\
(x+x)(x+x)
$$</p>
<p>The E-graph stores all four, but only pays the storage cost for one!</p>
<h2 id="equality-saturation-automatically-generating-equivalence">Equality saturation: automatically generating equivalence</h2>
<p>How does the E-graph learn what's equivalent? It uses an algorithm called <strong>Equality Saturation</strong>. This process takes a simple set of mathematical rules (such as the distributive property or $a+a=2a$) and applies them repeatedly until no new equivalences can be found (or until a time limit is reached).</p>
<p>Let’s watch it work on the expression $(x+x)^2$ using three simple rules:</p>
<p>$$
\alpha + \alpha \rightarrow 2\alpha \\
\alpha \times \alpha \rightarrow \alpha^2 \\
\alpha \times (\beta + \gamma) \rightarrow (\alpha \times \beta + \alpha \times \gamma)
$$</p>
<ol>
<li><strong>Start:</strong> Insert $(x+x)^2$ into the graph.</li>
</ol>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto; max-width:190px" src="/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/pat1.png" id="equality-saturation-pattern-1" alt="Initial e-graph state for the expression x plus x squared" loading="lazy">
    </figure>
</div>
<ol start="2">
<li><strong>Apply Rules:</strong> The rule $\alpha + \alpha \rightarrow 2\alpha$ applies to the inner expression $x+x$:</li>
</ol>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto; max-width:190px" src="/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/pat3.png" id="equality-saturation-pattern-3" alt="Equality saturation applying a rewrite rule to the inner x plus x expression" loading="lazy">
    </figure>
</div>
<ol start="3">
<li>We <strong>insert</strong> the right-hand side, $2x$, and <strong>merge</strong> it with the e-class for $x+x$, as the graph knows they are identical:</li>
</ol>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto; max-width:190px" src="/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/pat5.png" id="equality-saturation-pattern-5" alt="E-graph after merging the equivalent expressions 2x and x plus x" loading="lazy">
    </figure>
</div>
<ol start="4">
<li><strong>Repeat until Saturation:</strong> The process continues, applying other rules until the E-graph contains every possible equivalent expression derived from these rules:</li>
</ol>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto; max-width:190px" src="/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/grow.png" id="equality-saturation-grow" alt="Expanded e-graph after repeated equality saturation rewrites" loading="lazy">
    </figure>
</div>
<p>The most popular implementation of equality saturation is Egg <a href="#4">[4]</a>, a library written in Rust.
But, how can e-graphs and equality saturation help with symbolic regression search?</p>
<h2 id="symbolic-regression-and-e-graphs-its-a-match-">Symbolic Regression and E-graphs, its a match 💖!</h2>
<p>A few years ago, we realized this powerful mechanism could be the missing piece in Symbolic Regression and we <strong>pioneered</strong> their integration in different applications.</p>
<p>First, we demonstrated that e-graphs are a superior <strong>simplification tool</strong> compared to standard methods like <code>sympy</code> <a href="#1">[1]</a>. By simplifying equations with equality saturation, we not only reduced model complexity but also increased the probability of finding the best-fitting local optima <a href="#6">[6]</a>.</p>
<p>Second, we found the E-graph structure could be used to analyze how inefficient standard search algorithms like Genetic Programming were under a limited budget, showing how often they revisited the same expressions <a href="#5">[5]</a> in severely length-limited and therefore constrained search spaces.</p>
<p>At this point, we felt there was much more we could do with e-graphs in SR.</p>
<h2 id="generating-uniqueness">Generating uniqueness</h2>
<p>In our most recent work on <strong>e-graph genetic programming</strong> (<a href="https://github.com/folivetti/eggp"><strong>eggp</strong></a>) <a href="#7">[7]</a>, we turned the e-graph into a <strong>database and guidance system</strong> for equation discovery.</p>
<p>Remember how genetic programming works:</p>
<ul>
<li>Create initial random expressions</li>
<li>Repeat:
<ul>
<li>Select two expressions proportional to their performance</li>
<li>Combine parts of these expressions generating a new expression</li>
<li>Replace a part of this expression with a random variation</li>
</ul>
</li>
</ul>
<p>As stated before, this can be inefficient since we can generate many equivalent expressions during the process <a href="#5">[5]</a>. But, what if we store every generated expression into a single e-graph and run the equality saturation algorithm?</p>
<p>For once, we would have a database system allowing us to query whether a given expression was already visited, even in an equivalent form. But also, we can use this information to enforce the generation of new expressions!</p>
<div class="col-md-6 text-center">
    <figure class="image-box">
        <img style="max-height:auto; max-width:800px" src="/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/cxegg.png" id="equality-saturation-crossover" alt="E-graph-guided crossover example for symbolic regression search" loading="lazy">
    </figure>
</div>
<p>It works like this, imagine that the current state of the search is the e-graph above! The green e-classes are the root of the already evaluated expressions.
Let's say that GP decides to recombine the expressions $x + \sqrt{x}$ and $x + 2x$, choosing to replace $\sqrt{x}$ of the first expression with something else from the second.
The choices of recombination are ${x+x, x+2, x+2x, x+x+2x}$. We can query each one of these choices to verify whether they already exist in the e-graph. If they do and were already evaluated, we discard them!</p>
<p>Similarly, we can do the same for the mutation. let's suppose we will mutate the expression $x + \sqrt{x}$ by replacing $\sqrt{x}$ with a random expression. If we are unlucky, we may generate the expression $2x$, thus forming $x+2x$, which was already evaluated. After detecting the duplicate, we can change the multiplication in $2x$ with any binary operator that would generate a new expression!</p>
<h2 id="explore-the-search-space-with-codeeggpcode-and-codereggressioncode">Explore the Search Space with <code>eggp</code> and <code>rEGGression</code></h2>
<p>You can start using this algorithm right now! Here is how you can install our library and use it to find an equation for a real-world fluid dynamics dataset.
You can install eggp with <code>pip</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip <span class="nb">install </span>eggp

</code></pre></div></div>
<h3 id="finding-a-formula">Finding a Formula</h3>
<p>This example uses <code>eggp</code> to find a relationship for one of the 'Nikuradse problems' <a href="#9">[9]</a> (see the tutorials at this <a href="https://github.com/folivetti/eggp/tree/main/tutorials">link</a>).</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">eggp</span> <span class="kn">import</span> <span class="n">EGGP</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="n">pd</span><span class="p">.</span><span class="n">set_option</span><span class="p">(</span><span class="s">'display.max_colwidth'</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="p">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s">"datasets/nikuradse_1.csv"</span><span class="p">)</span>

<span class="n">model</span> <span class="o">=</span> <span class="n">EGGP</span><span class="p">(</span><span class="n">gen</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">nPop</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">maxSize</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span> <span class="n">nTournament</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">pc</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">pm</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">nonterminals</span><span class="o">=</span><span class="s">'add,sub,mul,div,power,exp,log'</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s">'MSE'</span><span class="p">,</span> <span class="n">simplify</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">dumpTo</span><span class="o">=</span><span class="s">'regression_example.egg'</span><span class="p">)</span>

<span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">df</span><span class="p">[[</span><span class="s">'r_k'</span><span class="p">,</span> <span class="s">'log_Re'</span><span class="p">]],</span> <span class="n">df</span><span class="p">[</span><span class="s">'target'</span><span class="p">])</span>
<span class="k">print</span><span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">results</span><span class="p">[[</span><span class="s">'Expression'</span><span class="p">,</span> <span class="s">'loss_train'</span><span class="p">,</span> <span class="s">'loss_val'</span><span class="p">,</span> <span class="s">'size'</span><span class="p">]])</span>
</code></pre></div></div>
<p>After running the search, the final e-graph (stored in <code>regression_example.egg</code>) contains the entire history of visited, unique solutions.  This can be used to resume the search with  different settings, such as a different nonterminal set:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">model</span> <span class="o">=</span> <span class="n">EGGP</span><span class="p">(</span><span class="n">gen</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">nPop</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">maxSize</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span> <span class="n">nTournament</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">pc</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">pm</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">nonterminals</span><span class="o">=</span><span class="s">'add,sub,mul,div,power,exp,log,sin,tanh'</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s">'MSE'</span><span class="p">,</span> <span class="n">loadFrom</span><span class="o">=</span><span class="s">'regression_example.egg'</span><span class="p">)</span>

<span class="n">model</span><span class="p">.</span><span class="n">fit</span><span class="p">(</span><span class="n">df</span><span class="p">[[</span><span class="s">'r_k'</span><span class="p">,</span> <span class="s">'log_Re'</span><span class="p">]],</span> <span class="n">df</span><span class="p">[</span><span class="s">'target'</span><span class="p">])</span>

<span class="k">print</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Last population resumed from the first Pareto front: "</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">model</span><span class="p">.</span><span class="n">results</span><span class="p">[[</span><span class="s">'Expression'</span><span class="p">,</span> <span class="s">'loss_train'</span><span class="p">,</span> <span class="s">'loss_val'</span><span class="p">,</span> <span class="s">'size'</span><span class="p">]])</span>

</code></pre></div></div>
<h3 id="interactive-model-selection-with-codereggressioncode">Interactive Model Selection with <code>rEGGression</code></h3>
<p>This e-graph can be further explored with the <a href="https://github.com/folivetti/reggression">rEGGression</a> tool <a href="#8">[8]</a>. An e-graph explorer for Symbolic Regression.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">reggression</span> <span class="kn">import</span> <span class="n">Reggression</span>

<span class="n">egg</span> <span class="o">=</span> <span class="n">Reggression</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s">"datasets/nikuradse_1.csv"</span><span class="p">,</span> <span class="n">loadFrom</span><span class="o">=</span><span class="s">"regression_example.egg"</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s">"MSE"</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">egg</span><span class="p">.</span><span class="n">top</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="s">"v0 ^ v0"</span><span class="p">)</span>

</code></pre></div></div>
<p>This will retrieve the top 5 expressions that follow the pattern $\alpha^\alpha$, such as $x^x$ or $\log((x+5)^{x+5}) + 3$. The result is a list of the best-performing models matching your structural criteria:</p>
<table>
<thead>
<tr>
<th>Expression</th>
<th>Fitness</th>
<th>Size</th>
</tr>
</thead>
<tbody>
<tr>
<td>$\left({\operatorname{log}({\log_{Re}^{\log_{Re}}})^{\theta_{0}}} \cdot r_{k}\right)^{\theta_{1}}$</td>
<td>-0.001514</td>
<td>10</td>
</tr>
<tr>
<td>$\left(\left({\log_{Re}^{\log_{Re}}} \cdot \theta_{0}\right) + \frac{\theta_{1}}{\operatorname{log}(r_{k})}\right)$</td>
<td>-0.001567</td>
<td>10</td>
</tr>
<tr>
<td>$\left(\frac{\operatorname{log}({\log_{Re}^{\log_{Re}}})}{\left(\theta_{0} \cdot r_{k}\right)} + \theta_{1}\right)$</td>
<td>-0.004623</td>
<td>10</td>
</tr>
<tr>
<td>$\left(\frac{\left(r_{k} + \theta_{0}\right)^{\theta_{1}}}{\operatorname{log}(r_{k})^{\operatorname{log}(r_{k})}} + \theta_{2}\right)$</td>
<td>-0.005701</td>
<td>13</td>
</tr>
<tr>
<td>$\left(\operatorname{log}({\log_{Re}^{\log_{Re}}}) \cdot r_{k}\right)^{\theta_{0}}$</td>
<td>-0.010011</td>
<td>8</td>
</tr>
</tbody>
</table>
<p>Or retrieving the top-5 expressions <strong>not</strong> having the pattern $\log(v)$:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="n">egg</span><span class="p">.</span><span class="n">top</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="s">"log(v0)"</span><span class="p">,</span> <span class="n">negate</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</code></pre></div></div>
<table>
<thead>
<tr>
<th>Expression</th>
<th>Fitness</th>
<th>Size</th>
</tr>
</thead>
<tbody>
<tr>
<td>$\left(\left( \left(\theta_{0} \cdot r_{k}\right)^{\theta_1 ^ {\log_{Re}}} \cdot \theta_{2}\right) + \theta_{3} \right)$</td>
<td>-0.001131</td>
<td>11</td>
</tr>
<tr>
<td>$\left({\left(\log_{Re} \cdot \theta_{0}\right)^{\theta_{1}}} \cdot \left(r_{k} + \theta_{2}\right)\right)^{\theta_{3}}$</td>
<td>-0.001187</td>
<td>11</td>
</tr>
<tr>
<td>$\left(\frac{\left(r_{k} + \theta_{0}\right)^{\theta_{1}}}{\left(\frac{\theta_{2}}{log_{Re}} + \theta_{3}\right)} + \theta_{4}\right)$</td>
<td>-0.001190</td>
<td>13</td>
</tr>
<tr>
<td>$\left({\left(e^{\left(\log_{Re} + \theta_{0}\right)} \cdot \theta_{1}\right)^{\theta_{2}}} \cdot r_{k}\right)^{\theta_{3}}$</td>
<td>-0.001191</td>
<td>12</td>
</tr>
<tr>
<td>$\left(\theta_0 \cdot \left(\left(\left(\log_{Re} \cdot \log_{Re}\right) \cdot \theta_{1}\right) + r_{k}\right)\right)^{\theta_{2}}$</td>
<td>-0.001192</td>
<td>11</td>
</tr>
</tbody>
</table>
<h2 id="conclusion">Conclusion</h2>
<p>The integration of e-graphs and equality saturation is not just an academic exercise; it's a fundamental change in how we approach Symbolic Regression. By treating equivalent expressions as one, we eliminate computational waste and focus the search entirely on finding novel and better solutions.</p>
<p>Our <code>eggp</code> algorithm shows the potential of this integration, achieving state-of-the-art results with a streamlined genetic programming framework. Furthermore, <code>rEGGression</code> gives the human expert unparalleled power to explore the results, acting as an interactive tool for guided model selection that is agnostic to the original SR method.</p>
<p>The days of algorithms driving in circles are over. E-graphs have provided the GPS.</p>
<h3 id="coming-up-next">Coming up Next!</h3>
<p>This library is not limited to just that! In the next blog post we will show how to use rEGGression to integrate and improve other algorithms!</p>
<h3 id="technical-details">Technical Details</h3>
<p>Our e-graph implementation is available at the <a href="https://github.com/folivetti/srtree">Haskell Symbolic Regression</a> library with some differences from <a href="https://docs.rs/egg/latest/egg/">egg</a> to make it more convenient for symbolic regression and memory efficient.</p>
<p>Our SR algorithm <a href="https://github.com/folivetti/eggp">eggp</a> already shows the potential of this integration, being capable of beating the state-of-the-art with a simple genetic programming framework.</p>
<p>The  <a href="https://github.com/folivetti/reggression">rEGGression</a> Python library make it easy to explore the explored solutions and can be used as an interactive tool for a guided model selection.</p>
<h2 id="references">References</h2>
<p><a id="1">[1]</a> de Franca, Fabricio Olivetti, and Gabriel Kronberger. &quot;Reducing overparameterization of symbolic regression models with equality saturation.&quot; <em>Proceedings of the Genetic and Evolutionary Computation Conference</em>. 2023.</p>
<p><a id="2">[2]</a> Banzhaf, Wolfgang, Ting Hu, and Gabriela Ochoa. &quot;How the combinatorics of neutral spaces leads genetic programming to discover simple solutions.&quot; <em>Genetic Programming Theory and Practice XX</em>. Singapore: Springer Nature Singapore, 2024. 65-86.</p>
<p><a id="3">[3]</a> Tate, Ross, et al. &quot;Equality saturation: a new approach to optimization.&quot; <em>Proceedings of the 36th annual ACM SIGPLAN-SIGACT symposium on Principles of programming languages</em>. 2009.</p>
<p><a id="4">[4]</a> Willsey, Max, et al. &quot;Egg: Fast and extensible equality saturation.&quot; <em>Proceedings of the ACM on Programming Languages</em> 5.POPL (2021): 1-29.</p>
<p><a id="5">[5]</a> Kronberger, Gabriel, et al. &quot;The inefficiency of genetic programming for symbolic regression.&quot; <em>International Conference on Parallel Problem Solving from Nature</em>. Cham: Springer Nature Switzerland, 2024.</p>
<p><a id="6">[6]</a> Kronberger, Gabriel, and Fabricio Olivetti de Franca. &quot;Effects of reducing redundant parameters in parameter optimization for symbolic regression using genetic programming.&quot; <em>Journal of Symbolic Computation</em> 129 (2025): 102413.</p>
<p><a id="7">[7]</a> de França, Fabrício Olivetti, and Gabriel Kronberger. &quot;Improving Genetic Programming for Symbolic Regression with Equality Graphs.&quot; <em>Proceedings of the Genetic and Evolutionary Computation Conference</em>. 2025.</p>
<p><a id="8">[8]</a> de França, Fabrício Olivetti, and Gabriel Kronberger. &quot;rEGGression: an Interactive and Agnostic Tool for the Exploration of Symbolic Regression Models.&quot; <em>Proceedings of the Genetic and Evolutionary Computation Conference</em>. 2025.</p>
<p><a id="9">[9]</a> Guimerà, Roger, et al. &quot;A Bayesian machine scientist to aid in the solution of challenging scientific problems.&quot; Science Advances Vol. 6, No. 5, eaav6971, <a href="https://doi.org/10.1126/sciadv.aav6971">doi: 10.1126/sciadv.aav69</a> 2020.</p>]]></content><author><name>Fabrício Olivetti de França</name></author><category term="science" /><summary type="html"><![CDATA[This guest post by Fabrício Olivetti de França describes the concepts of Equality Graphs and Equality Saturation and the benefits of using E-Graphs in Symbolic Regression.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://symreg.at/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/cxegg.png" /><media:content medium="image" url="https://symreg.at/blog/resources/2025-10-26-equality-saturation-and-symbolic-regression/cxegg.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Report on the Symbolic Regression at GECCO 2025, Malaga</title><link href="https://symreg.at/blog/2025/symbolic-regression-workshop-gecco/" rel="alternate" type="text/html" title="Report on the Symbolic Regression at GECCO 2025, Malaga" /><published>2025-07-18T11:00:00+00:00</published><updated>2025-07-18T11:00:00+00:00</updated><id>https://symreg.at/blog/2025/symbolic-regression-workshop-gecco</id><content type="html" xml:base="https://symreg.at/blog/2025/symbolic-regression-workshop-gecco/"><![CDATA[<p>This year's workshop on Symbolic Regression at GECCO (Genetic and Evolutionary Computation Conference) saw a record number of submissions and was very well received. We had two marvelous sessions with nine contributed talks and a 30-minute long lively discussion round. The overall quality of talks was high, spanning a good mix of topics including benchmarking, efficiency improvements, theoretical considerations, and applications. Thanks to all the speakers and participants for their contributions.</p>
<!--more-->
<p>The sessions for the GP track and the poster sessions had several additional contributions on SR.</p>
<p>It has been a while since my (Gabriel's) previous in-person visit to GECCO in 2018. For me, it was an outstanding intellectually satisfying event in Malaga, thanks to the many friends and new like-minded colleagues that I met after a long time. The many interesting and friendly chats I had in the breaks between sessions and at dinner were the best part of the conference.</p>
<h2 id="talks">Talks</h2>
<p>Florian Bachinger presented his proposal of benchmarks for shape constrained regression which should be helpful for the development of SR algorithms that allow to incorporate knowledge on the shape of the regression function (range, monotonicity, curvature). Regression with shape constraints could for instance be helpful to restrict function behaviour outside the range of training data to improve extrapolation.
The benchmark is based on an adapted version of the AI Feynman SR benchmark functions which uses physically appropriate ranges for the input variables.
They derive target constraints for each benchmark instance automatically by analysing data from the known target function and its derivatives. <a href="https://github.com/prescriptiveanalytics/SCR-Benchmarks" target="_blank">SCR-Benchmarks</a></p>
<p>Hernan Lira presented an application of SR for identifying pathways of oceanic metabolism in the OceanIA project <a href="https://oceania.inria.cl" target="_blank"><a href="https://oceania.inria.cl">https://oceania.inria.cl</a></a>. They use SR to describe the relationships between environmental conditions in the ocean, gene abundances and metabolism pathways in oceanic life and a large set of relevant descriptors (KO). They use several specific adaptations, such as a hierarchical (2-level) model and a multi-view approach, to find a common model structure but allow different fitting parameters for metabolism at different ocean depths. The fitness function includes several penalty terms to nudge GP to identify biologically plausible and consistent multi-view SR models. Several questions were discussed which mainly revolved around the constraints that were used to improve biological plausibility.</p>
<p>Fitria Wulandari presented a data augmentation idea to improve the extrapolation behavior of SR models. The approach is based on generating synthetic data outside of the region of training data (extrapolation range) from a teacher model. The teacher model is trained only on the available data but allows to freely generate  additional training data for SR. The hypothesis is that the bias of the teacher model can lead to useful synthetic data (probably: lower noise, smooth) for SR. Different algorithms were tried for the teacher model (NN, RF, GBT, SR) and the performance of SR with and without teacher model was compared. Results seem to be mixed / inconclusive.</p>
<p>Alberto Tonda showed an example where data transformation can mislead search. This problem appears for example in symbolic system identification, that is finding ordinary differential equations that predict the dynamics of systems based solely on samples of observed states from the system. Alberto showed that two options for solving this problem both involve data transformation. Here this refers to adding calculated columns for the approximated derivatives of trajectories to the dataset that are used as the target for symbolic regression. By this the symbolic identification problem is converted to a symbolic regression problem which is beneficial as it is easier to evaluate a loss function (no numeric integration) but on the other hand requires smoothing of the approximate derivatives. They used Savitzky-Golay smoothing and tuned hyperparameters for the smoother. The result was tested on ODEBench whereby for some instances the data transformation led to a misleading fitness function (the loss of the true data generating function was higher than the loss of the identified function). Discussion revolved around the characteristics around the problematic instances (more wiggly or more chaotic?).</p>
<p>Jiajun Duan presented results using a well-known benchmark dataset from the medical domain (Parkinson’s) to argue that using a hinge-loss function for the classification problem instead of accuracy is beneficial but admits that the hinge loss does not match typical likelihood functions for classification problems.</p>
<p>Bernhard Werth revisited pruning in tree-based GP for SR. Pruning is the removal of ineffective subexpressions with the motivation to make space for beneficial growth of expressions, ideally reducing size and/or improving prediction error. The looked at continuous pruning which means pruning a part or all of the trees in each generation, not just at the end.
The empirical results on a large set of datasets did show an improvement in training and test quality but did not show a clear difference in model length between GP with and without pruning. One explanation given by the speaker was that strict offspring selection (a specific variant of GP developed in the group) immediately fills up the pruned subexpressions with other expressions of similar size.</p>
<p>Erik-Jan Senn presented his preliminary work on establishing theoretical statements about the limit-behaviour model selection consistency and efficiency of symbolic regression algorithms. The main motivation being to see whether SR algorithms can identify the “true model” or the best approximation in the limit of infinite number of observations. He introduced an abstract formulation of all SR algorithms as two-phase model selection approaches and conjectures that exhaustive symbolic regression (Bartlett et al.) selects the correct functional form in large samples (with the assumption that the parameter fitting problem is solved by an oracle). He did not make a similar statement about GP yet but argues that the PAC framework should be revisited to get a better understanding about the theoretical guarantees of SR. How this affects practical applications was not covered.</p>
<p>Guilherme Imai Almeida presented the recent modifications of SRBench and new results. To reduce runtime for running all the experiments the number of datasets was reduced by selecting the datasets that were most discriminative among the different algorithms via a dimensionality reduction and agglomerative clustering. The dataset features for this clustering were descriptive features such as the size (number of observations and variables), best R², as well as performance results of algorithms. A focus of recent SRBench work was to allow more detailed comparisons between algorithms on individual datasets instead of aggregating all results into a single rank for comparison (benchmarking is not about finding a winner but instead should give us insights in the relative weaknesses and open issues of existing implementations). In the discussion the point was raised that it is still useful to have the simple ranking of algorithms because outsiders are mainly interested in finding out what is the “best” method on average that can be used.</p>
<p>Nathan Haut presented result of using alternating tournaments in GP with three objectives, prediction error, expression complexity (visitation length), and smoothness of the regression function. They used alternating Pareto tournaments in two objectives, that is, if in one generation they select the Pareto optimal individuals regarding prediction error and complexity they would switch this to prediction error and smoothness in the next generation. Many different variations for alternating Pareto tournaments were evaluated on the Kotanchek test function and several other benchmark datasets and positive results were observed: prediction errors, complexity and smoothness could be improved on average. As a remark about the motivation for using Pareto tournaments instead of doing multi.-objective NSGA-II directly, Nathan mentioned that Pareto tournaments in his experience focus more on the most important region/knee of the Pareto front instead of keeping the whole Pareto front in the population.</p>
<h2 id="discussion">Discussion</h2>
<p>After the talks we have a lively 30-minute long discussion round allowing all participants to express their thoughts about the most pressing topics in SR research.</p>
<h3 id="stability">Stability</h3>
<p>An issue raised was stability of GP for SR. While there is some degree of semantic stability which leads to comparable prediction errors of the produced models from multiple GP runs, the expressions can be completely different each time. This is problematic in scientific and engineering applications because it reduces trust in in the results and requires more effort in the validation or interpretation of the expressions to gain knowledge about the studied systems.
Stability is a beneficial property for SR algorithms and it is worthwhile to improve current systems in this direction. Recent work on using equality saturation and egraphs, also presented in other tracks at GECCO could help here.</p>
<h3 id="uncertainty">Uncertainty</h3>
<p>The next topic was handling uncertainty of SR models. We are frequently just assuming exact data points (discarding data / measurement uncertainty) and often use a loss function such as negative R² or sum of squared errors to assess model fit. First, we should start including an error model for the data; uncertainty of data propagates into uncertainty of parameters, and further into uncertainty of predictions giving e.g. confidence intervals for parameters or prediction intervals. Including this uncertainty has other benefits in model selection, overfitting reduction, and preventing unnecessarily complexity models. Beyond that the model selection uncertainty through GP search is another factor.
On the other hand, there can be difficulties expression confidence regions or prediction intervals when combining multiple models into an ensemble or with multi-modal likelihood functions (not sure if I understood the online comment correctly).
In any case, recent work in Bayesian symbolic regression and sequential Monte Carlo sampling for symbolic regression looks very promising.</p>
<h3 id="benchmarks">Benchmarks</h3>
<p>Several participants raised the question: “What benchmarks should we use or what are characteristics of good benchmark problems?”. There seems to be a consensus that most of the AI Feynman problem instances are too easy as they are very short expressions that can be recovered easily with exhaustive search. We should question whether it is worthwhile to devise intricate SR systems to be able to discover such simple equations. Probably we should construct much more complex synthetic benchmark functions to really challenge our current SR systems. On the other hand, if such complex target functions never occur in real-world situations directing efforts into systems that are able to rediscover such equations might also be wasted. We should not dump all problem instances (and algorithms) into the same bin but instead could use groups of characteristically similar instances.</p>
<h3 id="more">More</h3>
<p>We discussed the aims of SR implementations. Currently, SR is often considered as a solver or a system giving you a solution for a problem, instead SR could be more useful as an exploration tool (such as <a href="https://github.com/folivetti/reggression">rEGGression</a> which was presented in another GECCO track). Both use cases are beneficial.</p>
<p>Another topic was the smoothness of mutation in genetic programming. Typical mutation operators are rather disruptive, and the hypothesis was raised that a smoother mutation operation could improve search.</p>
<div class="row">
    <div class="col-lg-7 col-md-12 text-center">
        <figure class="image-box">
            <img src="/blog/resources/2025-07-18-symbolic-regression-workshop-gecco/symreg_workshop.jpg" id="workshop-room" alt="Audience and speakers at the symbolic regression workshop at GECCO 2025" loading="lazy">
        </figure>
    </div>
    <div class="col-lg-7 col-md-12 text-center">
        <figure class="image-box">
            <img src="/blog/resources/2025-07-18-symbolic-regression-workshop-gecco/gabe_fabricio.jpg" id="workshop-organizers" alt="Workshop organizers Gabriel Kronberger and Fabrício Olivetti de França at GECCO 2025" loading="lazy">
        </figure>
    </div>
</div>
<p>Gabriel Kronberger and Fabrício Olivetti de Franca</p>]]></content><author><name>Gabriel Kronberger and Fabrício Olivetti de França</name></author><category term="workshops" /><summary type="html"><![CDATA[This year's workshop on Symbolic Regression at GECCO (Genetic and Evolutionary Computation Conference) saw a record number of submissions and was very well received. We had two marvelous sessions with nine contributed talks and a 30-minute long lively discussion round. The overall quality of talks was high, spanning a good mix of topics including benchmarking, efficiency improvements, theoretical considerations, and applications. Thanks to all the speakers and participants for their contributions.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://symreg.at/blog/resources/2025-07-18-symbolic-regression-workshop-gecco/gabe_fabricio.jpg" /><media:content medium="image" url="https://symreg.at/blog/resources/2025-07-18-symbolic-regression-workshop-gecco/gabe_fabricio.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Report on the Royal Society Discussion Meeting on Symbolic Regression in the Physical Sciences</title><link href="https://symreg.at/blog/2025/royal-society-discussion-meeting-symreg-in-physics/" rel="alternate" type="text/html" title="Report on the Royal Society Discussion Meeting on Symbolic Regression in the Physical Sciences" /><published>2025-05-06T11:00:00+00:00</published><updated>2025-05-06T11:00:00+00:00</updated><id>https://symreg.at/blog/2025/royal-society-discussion-meeting-symreg-in-physics</id><content type="html" xml:base="https://symreg.at/blog/2025/royal-society-discussion-meeting-symreg-in-physics/"><![CDATA[<p>The meeting on <a href="https://royalsociety.org/science-events-and-lectures/2025/04/symbolic-regression/"><em>Symbolic Regression in the Physical Sciences</em></a> was held on 28th and 29th of April 2025 at Royal Society in London. Two days of insightful talks highlighted several applications of symbolic regression and gave some hints about future developments of symbolic regression methods. We provide our personal summary of the main topics in this post.</p>
<!--more-->
<p>Symbolic regression is a branch of machine learning that attempts to find interpretable mathematical expressions which can accurately approximate a data set. This meeting brought together practitioners of symbolic regression with physicists who are tackling problems which are particularly amenable to their analysis.</p>
<div class="col-md-12 text-center">
    <figure class="image-box">
        <img src="/blog/resources/2025-05-06-royal-society-discussion-meeting-symreg-in-physics/rs_group_cropped.jpg" id="royal-society-speakers-group-picture" alt="Group photo of speakers at the Royal Society symbolic regression meeting" loading="lazy">
    </figure>
</div>
<p>Left to right: C. Cornelio, E. Kabliman, S. Manti, A. Lucantonio, L. Kammerer, G. Kronberger, H. Desmond, A. Soltani, D. Bartlett, G. Bomarito, N. Kutz, F. Olivetti de Franca, P. Ferreira, B. Burlacu, W. La Cava, A. Constantin</p>
<h2 id="schedule">Schedule</h2>
<p>The workshop had a mixture of talks focussing either on applications of symbolic regression in physical sciences and engineering or on symbolic regression methods.</p>
<h3 id="monday-28th-of-april">Monday 28th of April:</h3>
<ul>
<li>Harry Desmond, University of Portsmouth, <strong><em>(Exhaustive) Symbolic Regression and model selection by minimum description length</em></strong> <a href="https://youtu.be/fC5Q-kRr9_Y?feature=shared" target="_blank">Video</a></li>
<li>Steven Abel, Durham University, <strong><em>Symbolic regression in beyond Standard Model physics</em></strong> <a href="https://youtu.be/lrrzglxRPOI?feature=shared" target="_blank">Video</a></li>
<li>Evgeniya Kabliman, University of Bremen &amp; Leibniz Institute for Materials Engineering, <strong><em>Constitutive modelling using symbolic regression</em></strong> <a href="https://youtu.be/jWfX2x5x_Fw?feature=shared" target="_blank">Video</a></li>
<li>Roger Guimerà, Universitat Rovira i Virgili <strong><em>Physics for symbolic regression, Symbolic regression for physics</em></strong> <a href="https://youtu.be/JPm2cwduP6M?feature=shared" target="_blank">Video</a></li>
<li>William La Cava, Boston Children's Hospital <strong><em>Brush: incorporating split-wise functions and multi-armed bandits into symbolic regression</em></strong> <a href="https://youtu.be/zkTKmsksOhM?feature=shared" target="_blank">Video</a></li>
<li>Tariq Yasin, University of Oxford, <strong><em>Empirical dark matter profiles with symbolic regression</em></strong> <a href="https://youtu.be/nJMendHOtUs?feature=shared" target="_blank">Video</a></li>
<li>Cristina Cornelio, Samsung AI, <strong><em>Derivable scientific discovery</em></strong> <a href="https://youtu.be/7Wm1emhz8S4?feature=shared" target="_blank">Video</a></li>
<li>J. Nathan Kutz, University of Washington, <strong><em>Sparse regression for symbolic representations in latent space dynamics</em></strong> <a href="https://youtu.be/rhGiTCMGX4Y?feature=shared" target="_blank">Video</a></li>
</ul>
<h3 id="tuesday-29th-of-april">Tuesday 29th of April:</h3>
<ul>
<li>
<p>Deaglan Bartlett, Institut d'Astrophysique de Paris, <strong><em>Accelerating cosmological modelling with symbolic regression</em></strong> <a href="https://youtu.be/j1IYemcdRgo?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Miles Cranmer, University of Cambridge, <strong><em>Concept evolution and SymbolicRegression.jl as a modular research platform</em></strong> <a href="https://youtu.be/g8HJ__rsFgE?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Etienne Russeil, Stockholm University, <strong><em>Multi-view Symbolic Regression: from independent experiments to general laws</em></strong> <a href="https://youtu.be/ItMv-Mwb9r4?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Geoffrey Bomarito, National Aeronautics and Space Administration (NASA), <strong><em>Symbolic regression via posterior sampling</em></strong> <a href="https://youtu.be/Ft0pDaoP0Fs?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Andrei Constantin, University of Birmingham &amp; University of Oxford, <strong><em>Statistical patterns in the equations of physics and the emergence of a meta-law of Nature</em></strong> <a href="https://youtu.be/zKcFNDejR5I?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Bogdan Burlacu, University of Applied Sciences Upper Austria, <strong><em>Zobrist hash-based duplicate detection in symbolic regression</em></strong> <a href="https://youtu.be/yazT7IBkqqQ?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Fabricio Olivetti de França, Universidade Federal do ABC, <strong><em>Equality graph assisted symbolic regression</em></strong> <a href="https://youtu.be/hIeMY8BQUb4?feature=shared" target="_blank">Video</a></p>
</li>
<li>
<p>Panel Discussion and Closing</p>
</li>
</ul>
<h2 id="summary">Summary</h2>
<p>Several speakers gave excellent examples showcasing the power of symbolic regression and its ability to produce fast and accurate models. Several issues and ideas were raised repeatedly by different speakers. These recurring themes include <strong>additional quality criteria</strong> for SR models for instance to preferably produce physically plausible and interpretable models, <strong>hierarchical models</strong> with global parameters and local fitting parameters for each dataset, and <strong>systematic handling of data and model uncertainty</strong>.</p>
<h3 id="additional-quality-criteria">Additional quality criteria</h3>
<p>Measurements of accuracy, such as the mean of squared errors, capture how well a certain model fits data but cannot always tell if such models are going to be useful when put into practice. Because of that, a recurrent topic in the workshop was the use of additional quality criteria for candidate expressions.</p>
<p>For example, in <a href="https://arxiv.org/abs/2211.11461" target="_blank">Exhaustive Symbolic Regression as explained by Harry Desmond</a>, minimizing the description length can bias the search toward a balance between accuracy and complexity while taking the uncertainty of the data into consideration. The minimum description length principle is connected to maximizing Bayesian evidence under different model priors. Using what they called the <a href="https://arxiv.org/abs/2304.06333" target="_blank">Katz prior</a> they tried to produce expressions with a similar distribution of operators as exhibited by a list of named equations collected from Wikipedia.</p>
<p>The talk of <a href="https://www.science.org/doi/10.1126/sciadv.aav6971" target="_blank">Roger Guimerà about the Bayesian Machine Scientist</a> was similar in idea. He discussed a prior for the structure of the function based on the already established physics equation to ensure that the accumulated knowledge throughout history is taken into consideration for biasing the search of expressions.</p>
<p>If we have prior knowledge about logical constraints and axioms which the final model must follow, it is possible to select hypotheses that conform to such constraints or to create a feedback for the search engine to sample new candidates. Cristina Cornelio argued that this guidance helps to find correct models in their systems called <a href="https://www.nature.com/articles/s41467-023-37236-y">AI Descartes</a> and <a href="https://www.nature.com/articles/s41467-024-50074-w" target="_blank">AI Hilbert</a>.</p>
<p>There was a lively discussion about the ability of SR to discover physical equations, which often exhibit certain specific characteristics (the formula looks &quot;physical&quot;). Andrei Constantin presented his thoughts on <a href="https://arxiv.org/abs/2408.11065" target="_blank">a meta-law of Nature</a> circling around peculiar statistical patterns that occur in the equations of physics.</p>
<p>The aim to find <em>interpretable</em> models is closely connected with the idea of using priors to produce natural or physical expressions. William La Cava showed some examples in the medical domain, where he used an implementation of symbolic regression and genetic programming called <a href="https://github.com/cavalab/brush">Brush</a> to produce interpretable models similar to decision trees that help physicians and patients understand the reasoning for diagnoses. Additionally, he argued for the need for a benchmark or competition that evaluates interpretability of symbolic regression results. Discussion revolved around the problem of defining and measuring <em>interpretability</em>.</p>
<p>Sampling from the posterior distribution of expressions can lead to a Bayesian view of how to handle uncertainties. Geoffrey Bomarito showed how this can be exploited to gradually introduce the effect of data into the search promoting an improved capability of retrieving the true expression under limited, noisy, and sparse data.</p>
<p>Steven Abel used symbolic regression tools in the context of finding extensions to the Standard Model of particle physics by trying to find accurate and efficient emulators for computationally heavy numerical simulations. He presented a huge expression produced by PyOperon spanning a whole slide. To produce an expression that is accurate for inputs which are most relevant for the numerical simulation they used a simple weighting scheme with PyOperon to weight those data more heavily.</p>
<p>The execution speed of the symbolic regression models is another relevant quality criterion, for example when using SR models in the form of emulators in larger optimization pipelines. This was raised for instance by Deaglan Bartlett when he presented his results for finding emulators for the <a href="https://arxiv.org/pdf/2311.15865" target="_blank">linear</a> and <a href="https://arxiv.org/abs/2402.17492" target="_blank">non-linear power spectrum</a> of pairwise galaxy distances and again when he presented the beautiful new approximation for a hypergeometric function that was more accurate than the human-derived approximation which has been used for decades. In this talk on <a href="https://arxiv.org/abs/2305.01582" target="_blank">SymbolicRegression.jl and PySR</a>, Miles Cranmer expressed that he thinks that probably the best criterion for model complexity is the speed of evaluating the expressions on an FPGA.</p>
<p>Overall, with that many possibilities of calculating the quality of the obtained solutions, there is a need for a customizable experience with symbolic regression tools. Miles Cranmer showed his recent improvements with <a href="https://github.com/MilesCranmer/PySR" target="_blank">PySR</a> and how it is capable of incorporating customized loss functions, operators, and function templates in the form of standard Julia code even allowing the importing of external libraries (such as ODE solvers). As some decisions can be made post-hoc, there may be a need for a structured database of hypothesis that can be easily explored by the user; this can be accomplished with the <a href="https://arxiv.org/abs/2501.17848" target="_blank">equality graphs, presented by Fabricio Olivetti de França</a>, allowing the automatic derivation of properties (i.e., monotonicity), pattern matching, and <a href="https://arxiv.org/abs/2501.17859" target="_blank">statistics on common patterns observed during the search</a>.</p>
<h3 id="hierarchical-models">Hierarchical models</h3>
<p>In most of the talks, symbolic regression models were used as one component embedded within a larger pipeline or hierarchical simulation model. Different ways of handling this were mentioned in several talks.</p>
<p>For example Roger Guimerà showed ordinary differential equations produced by the Bayesian Machine Scientist which describe the growth behaviour of bacterial strains on different media. The system found a common expression which was accurate for all growth curves but had fitting parameters that were fit to each of the individual growth curves. Similarly, the expressions found by the Bayesian Machine Scientists for predicting mobility patterns between larger cities included fitting parameters tuned for each city.
Etienne Russeil called this approach multi-view symbolic regression and he highlighted results for example for the observed light intensity curves of supernovae over time where symbolic regression was used to find a common model structure with parameters that are fit to each supernova light curve.</p>
<p>Tariq Yasin also mentioned a similar approach with global parameters and local parameters fit to each of the approximately 150 galaxies in the dataset that they used.</p>
<p>Evgeniya Kabliman presented the idea to <a href="https://www.sciencedirect.com/science/article/pii/S2666496821000182" target="_blank">use symbolic regression to find short expressions that can be used to calculate the local parameters</a> from other known variables instead of fitting the parameters to each dataset. Her work is focused on the development of constitutive models explaining mechanical properties of metallic materials. In this domain, several physics-based models exist to describe stress-strain behaviour but all models still have fitting parameters that must be estimated from costly measurements. She proposed using SR to improve such physics-based models by finding expressions which allow to replace fitting parameters. A main issue in these models seems to be that uncertainty of measurements and variability of samples used in experiments is often ignored.</p>
<p>Nathan Kutz presented an approach called <a href="https://arxiv.org/abs/2301.12011" target="_blank">Sensing with shallow recurrent decoder networks (SHRED)</a> and it combination with <a href="https://arxiv.org/abs/1509.03580" target="_blank">sparse identification of nonlinear dynamics (SINDy)</a> to produce sparse spatio-dynamical models.
SHRED uses a recurrent neural network architecture (LSTM) with a final decoder layer to learn and predict noisy dynamical processes. The data is compressed into a latent space which makes it easier to produce accurate and robust predictions. He also repeatedly mentioned the unexpected difficulty of numerically approximating derivatives of noisy functions.</p>
<h3 id="systematic-handling-of-data-and-model-uncertainty">Systematic handling of data and model uncertainty</h3>
<p>One potential shortcoming of current SR research, highlighted in the workshop, is the insufficient consideration given to the issue of uncertainty quantification. Looking at the data and models in terms of likelihoods provides a principled way for dealing with overfitting and selecting generalizable models. Unfortunately, this aspect is often ignored and hardly discussed in current symbolic regression work. During the workshop, the main presented approaches to handle uncertainty was the minimization of description length, presented in Harry's talk and the Bayesian approach by Geoffrey that incrementally take the data uncertainty into consideration.</p>
<h3 id="efficiency-and-usability-of-sr-tools">Efficiency and usability of SR tools</h3>
<p>As SR becomes more popular, it is necessary to ensure a good experience for the final user. This points to efficiency, ease of use, and customization. Regarding efficiency, PyOperon already provides an optimized implementation often orders of magnitude faster than other approaches. Bogdan Burlacu showed that it is still possible to improve the runtime by caching the fitness values for already visited expressions using the Zobrist hash. With this approach, he avoided evaluating repeated expressions along the search. Similar to this idea, Fabricio Olivetti also exploited the fact that equality graphs can represent equivalence relationships, thus stimulating the generation of unique expressions and improving the speed of convergence. He also argued that many implementations contain too many hyper-parameters, which are not often intuitive to the user, and he showed that a minimum set of hyper-parameters can be enough to achieve competing results with the popular implementations.
Finally, regarding customization, as already mentioned, Miles Cranmer introduced many new features to PySR enabling the user to adapt the main components to fit their personal demands. A briefly presented alternative was r🥚ression (aka rEGGression) that exploits equality graphs to offer a post-analysis navigation of multiple models found by a combination of SR algorithm executions.</p>
<h3 id="operon-and-pyoperon">Operon and PyOperon</h3>
<p>Operon seems to be a popular framework for astrophysics. It has been used in many works presented at the workshop.</p>
<h4 id="application-examples">Application examples</h4>
<ul>
<li>Deaglan Bartlett et al. used PyOperon to develop a symbolic emulator for the linear matter power spectrum
<ul>
<li><a href="https://github.com/DeaglanBartlett/symbolic_pofk" target="_blank"><a href="https://github.com/DeaglanBartlett/symbolic_pofk">https://github.com/DeaglanBartlett/symbolic_pofk</a></a></li>
<li><a href="https://arxiv.org/abs/2311.15865" target="_blank"><a href="https://arxiv.org/abs/2311.15865">https://arxiv.org/abs/2311.15865</a></a></li>
</ul>
</li>
<li>Steve Abel et al. used Operon to develop analytical expressions for beyond Standard Model physics</li>
<li>Etienne Russeil et al. used PyOperon for Multi-View Symbolic Regression with applications to phenomenological modeling <a href="https://arxiv.org/abs/2405.18471" target="_blank"><a href="https://arxiv.org/abs/2405.18471">https://arxiv.org/abs/2405.18471</a></a></li>
<li>Evgeniya Kabliman et al. used PyOperon for modeling stress-strain curves of aluminium and steel alloys</li>
</ul>
<h4 id="feature-requests">Feature requests</h4>
<p>In general, it would seem that the current scikit-learn interface provided by pyoperon is not very flexible and more attention should be paid to ergonomics, ease-of-use and customization.</p>
<p>Summary of requested features:</p>
<ul>
<li>support for a wider range of likelihoods, and the possibility to fully specify the data uncertainties in the form of a covariance matrix</li>
<li>support for custom loss functions (note: this is already possible with the UserDefinedEvaluator, but it poses some issues in the Python wrapper due to the GIL/concurrency issues)</li>
<li>support for constraining the number of model parameters</li>
<li>the ability to perform restarts during parameter tuning</li>
<li>support for warm starts and, more generally, seeding the initialization or resuming the search with an existing population</li>
</ul>
<h2 id="future-activities">Future Activities</h2>
<ul>
<li><a href="https://heal.heuristiclab.com/research/symbolic-regression-workshop" target="_blank">Symbolic Regression Workshop</a> at the <a href="https://gecco-2025.sigevo.org/HomePage" target="_blank">Genetic and Evolutionary Computation Conference (GECCO)</a> 14th-18th of July, Malaga</li>
<li><a href="https://drive.google.com/file/d/1sQE80uWEmnN15XZELUWZPp97DASWrq8b/view" target="_blank">Advancing Computational Mechanics with Symbolic Regression</a>, <a href="https://usnccm18.usacm.org/" target="_blank"> U.S. National Congress on Computational Mechanics</a>, Chicago July 20-24, 2025</li>
<li>We plan to organize a workshop proposal at NeurIPS in December 2025</li>
</ul>
<p>We had a great time in London and enjoyed the insightful talks. We thank the Royal Society for hosting and funding this meeting.</p>
<div class="col-md-8 text-center">
    <figure class="image-box">
        <img src="/blog/resources/2025-05-06-royal-society-discussion-meeting-symreg-in-physics/gabriel-fabricio-bogdan.jpg" id="gabriel-fabricio-bogdan-london" alt="Gabriel Kronberger, Fabricio Olivetti de Franca, and Bogdan Burlacu in London" loading="lazy">
    </figure>
</div>
Gabriel, Fabrício, Bogdan]]></content><author><name>Gabriel Kronberger, Fabrício Olivetti de França and Bogdan Burlacu</name></author><category term="workshops" /><category term="physics" /><summary type="html"><![CDATA[The meeting on Symbolic Regression in the Physical Sciences was held on 28th and 29th of April 2025 at Royal Society in London. Two days of insightful talks highlighted several applications of symbolic regression and gave some hints about future developments of symbolic regression methods. We provide our personal summary of the main topics in this post.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://symreg.at/blog/resources/2025-05-06-royal-society-discussion-meeting-symreg-in-physics/rs_meeting_orga_cropped.png" /><media:content medium="image" url="https://symreg.at/blog/resources/2025-05-06-royal-society-discussion-meeting-symreg-in-physics/rs_meeting_orga_cropped.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>