|
Prev: HP28S (ROM)
Next: how to solve integrals
From: John H Meyers on 22 Jan 2006 05:56 In this post we will illustrate a \PI (product) function, written in UserRPL with a little help from library 256. When implementing any user-defined function of symbolic arguments, a serious problem is that the arguments of user-defined functions are not normally quoted, hence they will be evaluated if possible, even before the user function is invoked. This is equally true of HP48 and HP49, E.g. '\GS(a=b,c,d)' @ built-in function, @ key arguments remain symbolic when compiled: SYMBOL SYMBOL ID a ; ID b ID c SYMBOL ID d ; xSUM ; '\PI(a,b,c,d)' @ user-defined, @ all args are unfortunately pre-evaluated: SYMBOL ID a ID b ID c ID d SYMBOL ID \PI ; BINT4 xFCNAPPLY ; A second problem for some user functions, such as a complete \PI [product] function to complement the built-in \GS [summation] function, is that when args 'b' and 'c' above are not numeric when evaluated, then it may be desirable to return an unevaluated symbolic result, identical if possible to the original expression, hence that result must be built again from the original arguments, which again requires that args 'a' and 'd' remain unevaluated. It is possible to solve the first problem by ensuring that the "stepping variable" does not exist, or by quoting the first and last arguments to the user function, e.g. 'X' PURGE '\PI(X,2,3,SQ(X))' EVAL or '\PI(QUOTE(X),2,3,QUOTE(SQ(X)))' EVAL It is even possible to solve it by evaluating the expression in another context where user variables can not be found, such as the hidden directory context. However, in this post we supply yet another method, which is to write the formula as if it were a summation, e.g. '\GS(X=2,3,SQ(X))' and then apply the program SIGPI to change \GS into \PI; this takes advantage of the built-in compiler's understanding of how to quote the original arguments properly. Any of these methods works, so take your pick; it would of course be nicer to put it into an installed library with whatever would make the compiler and decompiler treat \PI the same as they treat the built-in summation function, but that detail is left to the interested reader as an exercise :) I haven't tried it on any "nested" instances, such as that proposed elsewhere in this thread (neither have I bothered to try those nested summations on the 48G or 49G), so there's something else to pursue later. I even have yet another idea in mind, which is to provide a product function via the summation function itself, e.g. via a form such as '\GS(X=2,3,PROD(SQ(X)))' What PROD would have to do is to interact with the internals of the \GS implementation -- yep, you guessed it, it would have to grab the currently saved sum from its lambda variable, replace it by the current product, and then return a zero value for \GS to "add" to what it thinks is the running "sum." Of course, one more hack would be necessary, to recognize the very first iteration and start off at 1, rather than at zero. Here are SIGPI and \PI user functions, whipped up for this demonstration in UserRPL, to illustrate that nothing is beyond the realm of possibility. You must first install the "extable" library, then perform HOME 256 ATTACH, then you may transfer or type the following (on HP49 series calcs): \<< \->LST 1. \<< CASE DUP { \GS } HEAD SAME NSUB ENDSUB == AND THEN DROP { \PI } \->ALG 4. R~SB "xFCNAPPLY" GETADR A\-> END NSUB 1. == NSUB 4. == OR THEN "symcomp" GETADR SYSEVAL END END \>> DOSUBS \->ALG \>> 'SIGPI' STO \<< \-> n. t. u. v. \<< t. I\->R TYPE u. I\->R TYPE OR { n. t. u. v. ::\GS DTAG 5. \->LIST SIGPI } { n. DUP TYPE 9. == { \->LST HEAD } IFT DUP ::n. STO DUP TYPE 6. \=/ { STOVX } IFT 1. R\->I DUP ROT "CREATE" GETADR SYSEVAL IFERR t. u. FOR i. i. n. STO v. EVAL * NEXT THEN 1. ELSE 0. END n. PURGE { ERRN DOERR } IFT } IFTE \>> \>> '\PI' STO @ To create some test cases: '\GS(X=2,3,SQ(X))' SIGPI '\GS(X=2,3,Y^X)' SIGPI '\GS(X=W,Z,SQ(X))' SIGPI 123 'X' STO @ an existing 'X' is no obstacle { Y Z } PURGE @ let 'Y' and 'Z' be undefined 2 'W' STO @ but 'W' doesn't have to be @ [r->] [OFF]
|
Pages: 1 Prev: HP28S (ROM) Next: how to solve integrals |