How to use symbolic mathematics and calculus
Using this library you can use even complex calculations which include algebraic
manipulations, calculus, etc. Everything you need is to build up the expression on
the expressions stack in RPN (Reverse Polish Notation) form using various functions
from estack.h header file, then to evaluate the expression
using functions NG_approxESI or
NG_rationalESI.
You need to know what is RPN (also known as Postfix Notation) to do this (see
estack.h for a list of RPN tokens). Symbolic
mathematics will be ilustrated through various examples. First example will be a simple
program which takes two polynoms (or more general expressions) as arguments, multiplies them,
then returns a new polynom as the result. In TI-Basic, you can perform such calculations using
TI-Basic function
expand (arg1 * arg2)
where arg1 and arg2 are arguments. This may be represented in RPN form as
arg2 arg1 * expand
So, here is a program (note that arg2 and arg1 are already on the stack before
entering the program):
#define RETURN_VALUE
#include <estack.h>
#include <error.h>
int _ti89, _ti92plus;
void _main (void)
{
TRY
push_quantum_pair (MUL_TAG, EXPAND_TAG);
NG_rationalESI (top_estack);
ONERR
push_quantum (UNDEF_TAG); // return "undef" in a case of error
ENDTRY
}
It is highly recommended to use TRY...ONERR...ENDTRY
constructions when performing symbolic calculations, because a lot of functions for advanced
mathematics throws errors which must be catched. After compiling this program (assuming that its name is
"polymul.c") try this from TI-Basic:
polymul (x+y, x-y)
But note that returning values from ASM programs to TI-Basic is not without severe limitations.
See the section about returning values to the TI-Basic.
estack.h contains two very useful functions which convert ordinary
algebraic expressions (given in a string) to tokenized RPN form and vice-versa, named
push_parse_text and display_expressions
(although they are somewhat slow, so if you want fast calculations, force RPN as much as possible).
They are very useful if you want to process algebraic data accepted from the keyboard, or to display
algebraic data on the screen. Also, a function Print2DExpr
is implemented, which "pretty prints" the expression in a window. Here is an example of the program
which calculates the ingegral of 1/((x-3)(x^2+4)) in respect to x and "pretty prints" the result
on the screen:
#include <estack.h>
#include <wingraph.h>
#include <kbd.h>
int _ti89, _ti92plus;
void _main(void)
{
push_END_TAG ();
push_quantum (VAR_X_TAG);
push_parse_text ("1/((x-3)(x^2+4))");
push_quantum (INTEGRATE_TAG);
NG_rationalESI (top_estack);
WinClr (DeskTop);
Print2DExpr (Parse2DExpr (top_estack, FALSE), DeskTop, 0, 50);
ngetchx ();
}
As already mentioned above, powerful applications should avoid push_parse_text
as much as possible, and use RPN as much as possible. This will be ilustrated through an example.
The expression
Integral (1/((x-3)(x^2+4)), x)
may be expressed in the RPN form (see estack.h) as shown below:
x 1 x 3 - 2 x ^ 4 + * / Integral
In according to this representation, previous program may be rewritten as:
#include <estack.h>
#include <wingraph.h>
#include <kbd.h>
int _ti89, _ti92plus;
void _main(void)
{
static unsigned char rpn[] = {END_TAG, VAR_X_TAG, 1, 1, POSINT_TAG,
VAR_X_TAG, 3, 1, POSINT_TAG, SUB_TAG, 2, 1, POSINT_TAG, VAR_X_TAG,
POW_TAG, 4, 1, POSINT_TAG, ADD_TAG, MUL_TAG, DIV_TAG, INTEGRATE_TAG};
NG_rationalESI (rpn + sizeof (rpn) - 1);
WinClr (DeskTop);
Print2DExpr (Parse2DExpr (top_estack, FALSE), DeskTop, 0, 50);
ngetchx ();
}
Maybe you want to find an integral of the function which is passed as the argument
of the program in respect to x, and to print the result using ordinary
printf function (i.e. without "pretty printing")? OK, why not?
Here is an example:
#define SAVE_SCREEN
#include <stdio.h>
#include <alloc.h>
#include <error.h>
#include <estack.h>
#include <kbd.h>
int _ti89, _ti92plus;
void _main(void)
{
ESI argptr = top_estack;
HANDLE h;
clrscr ();
TRY
push_END_TAG ();
push_quantum (VAR_X_TAG);
push_expr_quantum (argptr, INTEGRATE_TAG);
NG_rationalESI (top_estack);
h = display_statements (top_estack, 1, FALSE);
printf ("The integral is: %s", HeapDeref (h));
HeapFree (h);
ONERR
printf ("Error!");
ENDTRY
ngetchx();
}
A lot of extremely powerful math functions are implemented in estack.h
header file, which are never seen in TI-Basic: accessing various part of expressions, extracting
factors, terms, etc. Of course, don't try to make any program for symbolic math before studying
carefully estack.h header file!