Update development log

This commit is contained in:
cdo committed 2026-09-26 13:58:12 +01:00
1 parent 7a8ef1a485
commit 7773c79d6f
1 file changed
+45
+45
View File
@@ -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.