From 7773c79d6f52f5124ca555eb446322686e055fb9 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Sat, 26 Sep 2026 13:58:12 +0100 Subject: [PATCH] Update development log --- LOG.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/LOG.md b/LOG.md index 84d6c73..5271d9a 100644 --- a/LOG.md +++ b/LOG.md @@ -193,3 +193,48 @@ the evaluators were run in sequence on any input expression. To combine more than two evaluators, I created a `pipeline` macro that constructs nested compositions of evaluators with Rust's `macro_rules` system. + +### Differentiator + +The differentiation pass itself was very easy to implement given the +simplications made by first having a normalisation pass. I also had +decided to only support constant exponents, which simplifies things +too. In the end, it ended up being more-or-less a fairly direct +translation of the sum rule and product rule into code, along with the +power rule and chain rule combined for handling exponents. + +### Simplification + +The output of the differentiation pass was correct but contained a lot +of noise such as terms multiplied by zero and other similar things. I +therefore implemented a basic simplification pass that applied various +identities such as `x + 0 = x`, `0x = 0` and `1x = 1`. Expression +simplification is famously a very complex problem, but I kept this +pass quite limited in scope and only implemented the most high-payoff +features. + +### Canonicalisation + +To make the output a little easier to read, the final evaluation pass +I implemented was a limited multiplication reordering canonicalisation +pass that ensured that products had the constants first. This is +still incomplete as the re-ordering only takes place within binary +products (so `x*4` becomes `4x`, but `x*(y*4)` would become `x*4y` not +`4xy`), and terms in a sum were not re-ordered at all. However, I +decided full canonicalisation would be excessively complex for this +project and decided to leave it there, as the output was acceptably +readable at this point anyway. + +### Wrapping up + +The final pipeline I ended up with was: + +1. Normalisation +2. Differentiation +3. Constant folding +4. Simplification +5. Constant folding again +6. Canonicalisation + +I then created an `evaluator` function to wrap this up in the `eval` +module, to allow for a simple interface to the whole library.