HP48 FAQ Section 5: Questions about Math, Plotting, and Equations
Previous | Contents | Next |
This is due to the way numbers are typically represented by computers and calculators. There are infinitely many numbers, like `1/3' and `pi', that cannot be exactly represented internally (their decimal representations go on forever, and often cannot even be represented as a fraction, as in the example of `pi'). As a result, any calculations that use these numbers are bound to be off.
Some claim that 0^0 is defined as 1, some claim it is indeterminate. The HP mathematicians decided to use the definition. Here is some more concrete info shamelessly lifted from the Sci.Math-FAQ:
What is 0^0 ?
According to some Calculus textbooks, 0^0 is an "indeterminate form". When evaluating a limit of the form 0^0, then you need to know that limits of that form are called "indeterminate forms", and that you need to use a special technique such as L'Hopital's rule to evaluate them. Otherwise, 0^0=1 seems to be the most useful choice for 0^0. This convention allows us to extend definitions in different areas of mathematics that otherwise would require treating 0 as a special case. Notice that 0^0 is a discontinuity of the function x^y.
Rotando & Korn show that if f and g are real functions that vanish at the origin and are analytic at 0 (infinitely differentiable is not sufficient), then f(x)^g(x) approaches 1 as x approaches 0 from the right.
From Concrete Mathematics p.162 (R. Graham, D. Knuth, O. Patashnik):
"Some textbooks leave the quantity 0^0 undefined, because the functions x^0 and 0^x have different limiting values when x decreases to 0. But this is a mistake. We must define:
x^0 = 1 for all x,
If the binomial theorem is to be valid when x=0, y=0, and/or x=-y. The theorem is too important to be arbitrarily restricted! By contrast, the function 0^x is quite unimportant."
Published by Addison-Wesley, 2nd printing Dec, 1988.
H. E. Vaughan, The expression '0^0', Mathematics Teacher 63 (1970), pp.111-112.
Louis M. Rotando & Henry Korn, "The Indeterminate Form 0^0", Mathematics Magazine, Vol. 50, No. 1 (January 1977), pp. 41-42.
L.J. Paige, A note on indeterminate forms, American Mathematical Monthly, 61 (1954), 189-190; reprinted in the Mathematical Association of America's 1969 volume, Selected Papers on Calculus, pp. 210-211.
Jan Lukasiewicz wrote a book on formal logic in 1951 that showed that mathematical expressions could be specified without parentheses by placing the operators before (Polish Notation) or after (Reverse Polish Notation) the operands. For example, the expression:
(4 + 5) * 6
Could be expressed in RPN as:
4 5 + 6 *
6 4 5 + *
Polish Notation is also known as prefix notation and Reverse Polish Notation (RPN) is also known as postfix notation.
From: Dave Hicks <dgh@hpmuseum.org>
In the years that followed Lukasiewicz's book, computer scientists realized that RPN or postfix notation was very efficient for computer math. As a postfix expression is scanned from left to right, operands are simply placed into a last-in, first-out (LIFO) stack and operators may be immediately applied to the operands at the bottom of the stack. By contrast, expressions with parentheses and precedence (infix notation) require that operators be delayed until some later point. Thus, the compilers on on almost all modern computers converted statements to RPN for execution. (In fact, some computer manufacturers designed their computers around postfix notation.)
At the time that the HP-35 was introduced, other pocket calculators typically used a partial algebraic model. That meant they could evaluate trivial expressions like 4+5 but couldn't handle anything that involved parentheses or algebraic precedence. The technology of the time didn't allow for full algebraic compilers in pocket calculators.
RPN allowed HP to produce a pocket calculator that could evaluate arbitrary expressions using the available technology. For many, learning a new style of entry was a small price to pay to be able to evaluate arbitrary expressions on a calculator. Once the technology to produce algebraic compilers could fit into a pocket calculator, most RPN users had decided that RPN was more efficient and consistent for the user as well as for the calculator. Also, because subexpressions are evaluated as they are entered, entry errors are more obvious with RPN.
Another advantage to RPN is consistency between machines. Early algebraic models had differing limits of the complexity of the expressions they could evaluate. For example, TI catalogs from the late 70's listed how many levels of parentheses and pending operations each model could handle. Even today if you begin to use an algebraic calculator, you need to determine just "how algebraic" it really is. For example, some switch to RPN for unary operators (ie 5 SIN rather than SIN(5)) and some can't directly enter an expression like:
4+5
-----
6+7
Many people just can't get used to the interaction with the stack to do calculations. A simple alternative is to place your equation in tic marks like '8+10*3' and to use the EVAL as an equals key. This way you can enter numbers just as you would write them on paper.
Example: I add two temperatures like 34 deg.F and 11 deg.F, and I get 504.67 deg.F. Why don't I get 45 deg.F?
This occurs with the S/SX only. This behaviour changed in the G/GX. With the G/GX, adding 34 deg.F and 11 deg.F will give 45 deg.F using TINC and TDELTA. However, the G/GX will only add or subtract temperatures if the units are the same; it is now an error if they are not.
If the units attached to the number consists only of a temperature and nothing else, operations are done using an absolute temperature scale (relative to absolute zero). If the units consists of a temperature and something else, such as degrees/minute, the operation will not be done using an absolute temperature scale.
It also does not make any physical sense to add two temperatures. You can't add a cup of water at 20 degrees C to a cup of water at 30 degrees C and end up with two cups of water at 50 degrees C.
Note: Some later editions of the G/GX series manuals have some similar information on this subject.
Another feature is the generic unit, 1_?. It seems to be intended as a generic unit, to allow you to make new units not based upon any of the built-in ones. You could use it to create a conversion utility for currencies or bits and bytes. Before you create either, check the FTP sites to see what others have done in this regard.
Here's an example. Convert this using ASC\-> and save it as 'sample'.
"69A20FF78E000000005046F6E6574750ADA209C2A2C2A2070000F368B01B2130
E20005046F6A756E650ADA20339201000000000000210C2A20F000046F6E6574
768B01B2130640005086F6D6562750ADA20339200000000000000510C2A20F00
0046F6E65747C2A20B0000D696E686B0168B01B2130B5000303435453047A204
7A20C2A20F000046F6E65747ADA209C2A2C2A20F000046F6E6574768B01B2130
B213047A20C2A20F000046F6A756E6ADA209C2A2C2A20F000046F6A756E668B0
1B2130B213047A20C2A20F000086F6D65627ADA209C2A2C2A20F000086F6D656
2768B01B2130B2130B2130F0DA"
This is a sample directory with a custom menu. Enter the directory and press the CST key. Here you will see three units (truncated to fit the softkeys): donut, dozen, and homer. A dozen is defined as 12_donut, and a homer is a rate of 1.5_donut/min (not part of the SI system). These units may take SI prefixes described on page 10-5 of the User's Guide, so you may convert the value of 3_MW*h/kdonut into units of erg/mdozen using CONVERT, for example. The items in the CST menu have the usual abilities of unit menu objects as described on pages 10-2 and 10-3 of the User's Guide. These units can be used for math operations described on page 10-7 of the User's Guide, such as adding 2_donut to 1_dozen.
Example: At your power plant, you have four control room operators who have a combined consumption rate of 2.28 homers. How many donuts will they use in 5 minutes and 17 seconds?
2.28 [homer]
Right-shift UNITS [TIME]
5 [min]
17 [s] +
CST Left-shift [dozen]
You are using "Numeric Constants Mode". To turn this mode on or off:
Type -2 SF
. This turns the numeric constants mode on.
To turn it off, type -2 CF
.
Go to the MODES menu (press green/right-shift MODES). Hit the key for FLAG submenu. Toggle the second flag "Constant -> symb" to turn on and off.
You can build up a matrix by rows using \GS+. You can take a matrix apart by rows using \GS- These two commands (\GS is Sigma (Greek E)) add and subtract rows from the SigmaDAT Statistics matrix. \GS+ takes a vector row and adds it to SigmaDAT, and \GS- takes the bottom row away from SigmaDAT. \GS+ is accessible from the STAT menu with its own softkey. \GS- can be obtained by pressing left-shift /GS+, or by typing it in at the command line.
The GX has many matrix functions built in. See Appendix B-1.
Try lowering the plotting resolution by typing #2 RES
. You can
use larger values for faster speed at the expense of number of points
plotted. In the GX Plotting Options Menu this setting is known as the
"STEP" rate.
Alternatively, if you have a G series machine, you could try SpeedGraph, a fast assembly language plotter replacement. See http://www.hpcalc.org/ for a copy.
In the user's manual, inequalities are referred to as "truth plots". They are defined as expressions that return true (any nonzero real number) or false (0) results. In a truth plot, a pixel is turned on if the expression is true, it's unchanged if the expression is false.
For example to plot the simple inequality 'X>0' you could do:
'X>0' 'EQ' STO
TRUTH
-20 20 XRNG
-10 10 XRNG
ERASE DRAX DRAW
For more complicated examples see your manual, or on a G/GX you can type TEACH to look at some of the built-in examples. It may also be useful to plot the lines defining the outline true region. This is easily done by changing the plotting style to FUNCTION or CONIC and plotting again, taking care not to erase any previous plot.
Note that unless otherwise specified, every pixel in the display must be evaluated. As such, truth plots can be very slow. If you have a general idea on which values are going to return true, you can speed up plotting by specifying a smaller x and y plotting range. You can do this by setting the "LO" and "HI" input forms on a G/GX, which can be different than the actual display range.
If you are plotting the area between two equations, you speed up plotting dramatically by avoiding a TRUTH plot entirely. Store the two equations as the first two items in the current EQ list. Using NXEQ in the FCN menu will rotate the list as desired to plot both functions. Then the area between them can filled in very quickly using the SHADE key of the FCN menu (in the PICTURE environment).
Another hint for speeding up Truth plots is to set the resolution, say to 2 pixels or more, which also results in a different "shading pattern". The resolution can be set with the RES command.
To take the log of a number other than base 10 or e, say log x base y, you use the formula:
ln x
-------- where ln is natural log (log works too)
ln y
A quick program to do it would be: << SWAP LN SWAP LN / >>
With the input of:
2: x
1: y
The QUAD
command is designed to solve expressions at degree up to two. One
would expect the result of the simple expression 5=x/(1+x)
to be
x=-5/4
. But using the QUAD
command, the HP gives the complex
solution (0.5, 2.17944947177) i.e. the principal value (with flag 1 set).
What is the reason for this?
The QUAD
command is designed to solve quadratic equations. If the equation
is not of the form:
a*x^2 + b*x + c = d*x^2 + d*x + e
The HP48 calculates a quadratic taylor series expansion which is then solved
like a normal quadratic equation. The HP does the same when the equation is
of a higher order. In the example above, the equation x/(1+x)-5=0
has
the expansion:
-x^2 + x - 5 = 0,
Which has two complex conjugate solutions. However, if you multiply the
equation by (1+x)/
, you get:
x = 5 * (1+x)
Which can be solved directly with QUAD
. If the equation contains the
variable only once, it's the best way to use the ISOL
command instead.
This typically occurs for the (2n+1) roots of negative numbers, where n is a positive integer. For example, to calculate the fifth root of -3125 you can enter:
-3125^0.2
The result is the complex number (4.04508497187, 2.93892626146) or in DEG mode (4.99999999999, >36). The reason for this answer is that -3125^(1/5) has five different answers - arranged in a pentagon in the complex plane. In general, y^(1/x) has x different answers (y^x with x irrational has an infinite set of answers forming a circle on the complex plane).
Since 180/5 = 36 [degrees], this is the correct principal "5th root" of the negative argument in the complex plane; the HP48, unlike older calculators, does not turn "complex mode" on or off, so all "analytic" functions in the HP48 always accept complex arguments, and always return valid complex answers if suitable.
To calculate the desired solution, you have to use the right-shifted V-key with input like this:
2: -3125
1: 5
Or you can use 'XROOT(5,-3125)' since XROOT is defined to both accept and return real values only.
From: John Meyers
The reason is that the function ^
accepts and returns complex values
whenever appropriate, and also always returns the "principal" answer in the
complex plane, which may not be real if the argument is negative, even if
there exist other real-valued possible results.
Here are some UserRPL programs which handle this sort of general "real power of real" question, even with fractional powers, including the sticky issue of getting the right sign.
Note that the "power" argument (level 1) may be either a fraction or a real
number; we use \->Q
in all cases to convert it to a fraction, which may be
necessary to determine the correct sign of the answer.
\<< \->NUM DUP SIGN SWAP ABS \->Q
IF DUP TYPE THEN OBJ\-> DROP2 ELSE 1 END
4 ROLLD * ^ SWAP XROOT \>>
The version above is generally satisfactory for fractional powers which do not have a large numerator; otherwise an intermediate result might overflow, giving an invalid result.
The next version is overflow-resistant, but there is sometimes a slight
roundoff error from using ^ ABS
:
\<< \->NUM DUP2 ^ ABS SWAP ABS \->Q
IF DUP TYPE THEN OBJ\-> DROP2 ELSE 1 END
4 ROLL SIGN ROT ^ SWAP XROOT * \>>
Neither of the above programs ensures that its arguments are actually real;
other arguments (e.g. complex) can sneak by, possibly producing meaningless
answers. You can prevent this in either program by following \->NUM
with
OVER R\->B OVER R\->B DROP2
For example, with -8 and '2/3' as arguments, (or even -8 and .666666666667 as arguments), the answer is 4. To make the above into a user-defined function which can be used in algebraic expressions:
\<< \-> p r \<< r p \->NUM \->Q IF ... END \>> \>> 'XPOWR' STO
Then 'XPOWR(2/3,-8)' EVAL ==> 4 [using XPOWR() just like XROOT()]
Note: There are actually two different XROOT functions in the HP48; the algebraic version of XROOT expects its arguments in the opposite order from the stack-based version of XROOT (which inadvertently gave rise to a list-processing bug in early G-series ROM versions: K, L, M and P).
If you define XPOWR for yourself, as above, you will have to make sure that you use a consistent argument order for both algebraic and stack usage, unless you either make two separate functions or get into some fancy library-making, to duplicate something akin to the built-in "dual" XROOT functions.
Another fast way to solve quadratic equations (or polynominals of higher
degree) is by using the PROOT
command. Place a vector with the
coefficients of the polynominal on the stack.
For example:
x^3 - 9*x^2 + 26*x - 24
Would look like:
[1 -9 26 -24]
Then press left shift, SOLVE (key 7), POLY (key C), PROOT (key A). The result is [2 3 4], which are the roots of the equation.
Excerpt of postings from John Meyers
You must replicate the individual values or you can use a weighted analysis. For weighted analysis, Joe Horn's WEIGHT2 directory which can be found on Goodies Disk 8.
For weighted mean of numeric grades (or grade equivalents), with the number of credits for each course being the weight, you can use the program below.
First, fill in the statistics matrix, using any of the built-in statistics applications, entering each numeric grade equivalent in column 1, and the corresponding number of credits in column 2. Then press the key for the program below, which returns three results:
If you select an "X-Column" and/or a "Y-Column" different from the defaults (columns 1 and 2), then the results reflect the values in the "X-Column" using weights from the "Y-Column".
The program below is a slight improvement upon WEIGHT3, in that it no longer requires SigmaPAR to exist (the standard default columns are assumed if not). Credits go to Bob Wheeler for coming up with the algorithm, and to John Meyers for implementing the following program:
%%HP: T(3); @ \-> is right-arrow, \v/ is Square Root, \GS is Sigma
@ WMS - Weighted Mean and Standard Deviation, HP48G/GX
@ Stack diagram: ( SigmaDAT and SigmaPAR ) --> Mean, SDev(S), SDev(P)
@ If SigmaPAR does not exist, then
@ Col 1 (XCOL) is value and Col 2 (YCOL) is weight, by default
\<< '\GSPAR' DUP VTYPE 0 < { DROP 1 2 } { RCL 1 2 SUB EVAL } IFTE
0 0 DUP2 \-> x f w d m v
\<< RCL\GS x COL- SWAP DROP ARRY\-> EVAL \->LIST
RCL\GS f COL- SWAP DROP ARRY\-> EVAL \->LIST
2 \<< DUP2 'w' STO+ m - * DUP 'd' STO
w / 'm' STO+ m - d * 'v' STO+ \>> DOLIST
m v w DUP2 1 - / \v/ ROT ROT / \v/
\>> \>>^
If all you want is the weighted mean, and not the standard deviations, then you can dispense with all of the above, and just use a shortcut posted in GD7/MATH/WEIGHT.DOC by Joe Horn (basically, it is Sum(X*Y)/Sum(Y), where Y is the weight for X).
If you would rather replicate data points, then read on - however, if the "weights" associated with your data points are either very large or non-integers, then the following will be either very cumbersome or not possible, respectively. Press left-shift STAT DATA (on G/GX) to get to the menu containing the "Sigma+" "Sigma-" and "ClearSigma" commands.
Press "ClearSigma" to remove the old SigmaDAT. The first data must be entered as a vector: For example [2 4] and pressing "Sigma+". Now all other data pairs are entered without the brackets just as a pair separated by a space: e.g. 4 3 and pressing "Sigma+" and so on.
"Sigma-" in the HP48 does not accept data; rather, it simply removes the last-entered data point/row, popping it back onto the stack for you (the result is always one vector or scalar). If every point is removed, the statistics matrix is also deleted.
Now we can understand Joe Horn's program which accepts a data point/row, in whatever form the HP48 is prepared to accept it (single number, vector, or group of numbers), plus a frequency (integer only) on stack level 1, and then appends the data point/row the given number of times. Note that you must always supply a frequency, even if it is 1, and that any meaningless "frequency" less than 1 will be treated as 1.
\<< -55 CF 1 SWAP START \GS+ LASTARG NEXT DROP \>>
Obviously, \GS+ and \GS- represent the "Sigma+" and "Sigma-" commands.
Example: If the Statistics Matrix (SigmaDAT) already has two columns, and if we want to enter the new data pair [ 3 4 ] five times, we can simply type 3 4 5 and then press the key for the above program (don't forget to use a data vector for the very first data row).
For large frequencies, as noted, you will find this to be slow, not to mention the memory required for the multiple matrix rows; however, once you have literally entered every single data row, you can then do all the regression analysis and plotting you want, without the need for additional programming.
An easy and versatile way is to use the powerful list processing capabilities of the HP48. Generate a list with the x values, then perform the operations on that list. For example:
{ .1 2 2.5 5 123.4 } SQ will output { .01 4 6.25 25 15227.56 }
There are also several programs/libs to create a function table. Take a look at http://www.hpcalc.org/ and search for "MathTools" by Jack Levy or "Table" by Diego Berge.
If you are low on memory or want a customizeable program you can use a tiny User-RPL program. Here are two suggestions with different forms of the output. All programs use the SEQ command, which is the key command here! (for further information read the manual). Input is for example:
5: 'SQ(x)'
4: x
3: 11 (start)
2: 25 (end)
1: 1 (step)
The first mini program will output a matrix with the calculated values
%%HP: T(3)A(R)F(.);
\<< SEQ OBJ\-> COL\-> 1
COL\->
\>>
The second one will give x and f(x) in an array
%%HP: T(3)A(R)F(.);
\<< 4 DUPN 4 PICK 4
ROLLD SEQ OBJ\-> COL\->
6 ROLLD SEQ OBJ\->
COL\-> 2 COL\->
\>>
Previous | Contents | Next |