diff options
Diffstat (limited to 'site/content/gsoc/differentiating_code_addendum.typ')
| -rw-r--r-- | site/content/gsoc/differentiating_code_addendum.typ | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/site/content/gsoc/differentiating_code_addendum.typ b/site/content/gsoc/differentiating_code_addendum.typ new file mode 100644 index 0000000..b6dcfa5 --- /dev/null +++ b/site/content/gsoc/differentiating_code_addendum.typ @@ -0,0 +1,52 @@ +#import "/common.typ": post, link-self + +#show: post.with( + title: "Differentiating code – addendum", + date: datetime(year: 2020, month: 7, day: 14), +) + +This post describes how to the compute derivatives mentioned in an #link-self("gsoc/differentiating_code")[earlier post] using Maxima, a computer algebra system. Code is listed in a monospaced font and answers are written directly below, in LaTeX. *Ending lines with dollar signs in Maxima (instead of semicolons) surpresses the output,* which is very useful for definitions. + +Start by defining the reflectance model. +``` +U: c_0 * lambda^2 + c_1 * lambda + c_2$ +R: 1 / 2 + U / (2 * sqrt(1 + U^2))$ +``` +Differentiate `R` with respect to `c_0`. The expansion of `U` appears a few times in the result. Substitute `U_` for `U` to simplify it. (The underscore is there so it doesn't expand back to the full expression.) +``` +diff(R, c_0)$ +subst(U_, U, %); +``` +$ + (dif R) / (dif c_0) = lambda^2 / (2 sqrt(U^2 + 1)) - (U^2 lambda^2) / (2 (U^2 + 1)^(3 / 2)) +$ + +This can be further simplified by substituting $t_1 = sqrt(U^2 + 1)$. Unfortunately `subst` won't recognize $(U^2 + 1)^(3 / 2)$ as $t_1^3$ so I recommend doing this manually. +$ + (dif R) / (dif c_0) = lambda^2 / (2 t_1) - (U^2 lambda^2) / (2 t_1^3) +$ + +Repeating the process for the other coefficients reveals a pattern. Let $t_2 = 1 / (2 t_1) - U^2 / (2 t_1^3)$. +$ + (dif R) / (dif c_0) &= lambda^2 t_2 \ + (dif R) / (dif c_1) &= lambda t_2 \ + (dif R) / (dif c_2) &= t_2 +$ + +After skipping trivial derivatives, which can be easily done by hand, one will find themselves having to differentiate the final expression for $Delta E$. Normally an expression like $(dif L) / (dif c_0)$ (`diff(L, c_0)`) would be treated as a derivative of a constant in Maxima and reduced to zero. One can use `depends` to tell the program that the L\*a\*b\* coordinates are functions of the model parameters. The result will then contain derivatives of the coordinates themselves. + +An alternative approach is typing out the coordinates as functions explicitly. Instead of using `depends`, replace `L` with `L(c_0, c_1, c_2)` (and so on for `a` and `b`) in the code below. The downside is that the function arguments will appear in the end result, cluttering it and making a mess. + +``` +depends([L, a, b], [c_0, c_1, c_2])$ +delta_E: sqrt((L - L_target)^2 + (a - a_target)^2 + (b - b_target)^2)$ +``` +Use the same `subst` trick as before to simplify. +``` +diff(delta_E, c_0)$ +subst(delta_E_, delta_E, %); +``` +$ + ((b - b_"target") (dif b) / (dif c_0) + (a - a_"target") (dif a) / (dif c_0) + (L - L_"target") (dif L) / (dif c_0)) / (Delta E) +$ +The other derivatives look the same. Simply substitute $c_1$ or $c_2$ for $c_0$ in the expression above to get obtain them. |
