 The Museum of HP Calculators

HP Forum Archive 17

 Apologies to Vincze (symbolic differentiation on the 35S)Message #1 Posted by Peter Niessen on 7 Sept 2007, 11:28 a.m. Vincze, my friend, recently you asked how to do symbolic differentiation on the HP35S. I though this was easy, but it actually is harder than I thought. I know symbolic differentiation is pressty easy once you have your algebraic expression assembled as a tree, e.g. for ```x + sin (x*x) ``` which would look like ``` + x sin * x x ``` and where the rules are: ```1. x -> 1 2. + -> diff (left branch) + diff (right branch) 3. sin -> diff (below branch) * cos (branch) 4. * -> diff (left) * right + left * diff (right) ``` resulting in ``` + 1 * + cos * * * 1 x x 1 x x ``` by applying the above recursively. I thought this would be easy to convert from the tree notation to RPN, but it was not so easy. Storage of the expression on the 35S however seems pretty straightforward, by using the indirect registers and representing the operands as negative numbers (so you can e.g. solve for x by storing -24 in I), and representing the operators as positive numbers, +=1, -=2, *=3 ... sin=21, cos=22, ... or whatever. ```x x x * sin + ``` would thus become ```I 1 2 3 4 5 6 (I) -24 -24 -24 3 21 1 ``` This way you could write a routine which evaluates the indirect variables and leaves the result in the X register. The trouble is now that when you're working your way through from right to left, you don't know yet where the operands finish yet (unlike in the case of the tree). Therefore I did not succeed in providing the symbolic differentiation on the 35S. Cheers, Peter. Edited: 7 Sept 2007, 11:29 a.m.

 Re: Apologies to Vincze (symbolic differentiation on the 35S)Message #2 Posted by Vincze on 7 Sept 2007, 12:03 p.m.,in response to message #1 by Peter Niessen My friend Peter. That make sense, and I surprised you went through all work to do. I think I conclude that it not something easily done on 35S because it not designed for that. I have to relegate myself to use 48gx that I have to do this if need be. In most cases though, symbolic differentiation is not that hard to do using different rules, so it is more academic to see if 35s could do or not.

 Re: Apologies to Vincze (symbolic differentiation on the 35S)Message #3 Posted by Peter Niessen on 16 Sept 2007, 1:19 p.m.,in response to message #2 by Vincze Vincze, my friend, there actually is hope! So, to find out how "deep" an expression is in the stack, on has to count how many operators and operands there are. E.g. ```(x+1) * x x 1 + x * ``` Actually, every two valued operator needs two operands, so the mumber of operands should exceed the number of operators by 1: ```expression x 1 + x * #operators 2 1 #operands 3 2 1 ``` When seeing that the number of operands exceeds the number of operators by 1, we know that the expression is terminated. Thus, we can now write our differentiation function. Here I chose a C(++)-like language which differentiates the expression between the positions from and to. ```std::string diff (std::string expression, int from, int to) { switch (expression[from]) { case "constant": // constant is easily differentiated, is 0 return "0"; break; case "x": return "1"; // variable diffs to 1 break; case "+": eox_1 = find_end_of_expression (expression, from + 1); eox_2 = find_end_of_expression (expression, eox_1 + 1); return diff (expression, from + 1, eox_1) + diff (expression, eox_1 + 1, eox_2) + "+"; break; case "-" // basically same as - case "*": eox_1 = find_end_of_expression (expression, from + 1); eox_2 = find_end_of_expression, eox_1 + 1); ex1 = copy (expression, from + 1, eox_1); ex2 = copy (expression, eox_1 + 1, eox_2); return diff (ex1, from + 1, eox_1) + ex2 + "*" + ex1 + diff (ex2, eox_1 + 1, eox_2) + "*" + "+"; break; // and so on for /, sin, cos, ... } } ``` As an implementation, one could use the indirect registers for "expression", coding +, -, *, / as .2, 1.2, 2.2, 3.2, sin, cos, tan, exp, ln as .1, 1.1, 2.1, 3.1, ... so that the fractional part gives the valuedness of the operator. The variables would be represented by A = -1, ... Z=-26 (you can't have numerical literals, I'm afraid). Our example would thus become (using A to store 1) ```clear text x 1 + x * I 1 2 3 4 5 (I) -24 -1 .2 -24 2.2 ``` Now we have all the ingredients... On the 32S with only 6 levels of XEQ nesting, this would not be very much fun, but on the 35s with its 20 levels, one actually stands a chance. Happy programming, whoever takes this challenge! Cheers, Peter. Go back to the main exhibit hall