home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
misc
/
icalc.lzh
/
icalc
/
icalc.doc
< prev
next >
Wrap
Text File
|
1992-01-29
|
29KB
|
859 lines
¢3micalc ¢0m¢1mversion 1¢0m.¢1m1a
¢0mA complex-number expression parser
by Martin W.Scott
User Guide
icalc User Guide icalc
¢1mIntroduction
¢0m¢3micalc ¢0mis a terminal-based calculator; the ¢1mi ¢0mstands for
¢1mimaginary¢0m, denoting the fact that the calculator works with
complex numbers. There are many calculator programs for the
Amiga, but to my knowledge, none with this ability. ¢3micalc
¢0malso performs real (normal) calculations too, and you can
completely ignore the complex number facility if you wish.
¢1mComplex Numbers
¢0mA complex number is made up of two components: a real part,
and an imaginary part. The imaginary part is just a real
number multiplied by the special number i, which is defined
to be the square root of -1. Thus, i*i = -1. This may all
seem very artificial, but it's not; complex numbers exist as
surely as real numbers do (or don't, depending on your
mathematical philosophy). It's just that our notion of real
numbers is based upon our experience of measurement and
arithmetic. However, it is not the purpose of this guide to
teach the basics of complex numbers - if you don't know
about them, you probably don't need to, but you may still
find ¢3micalc ¢0museful, because real numbers are just a subset of
complex numbers, and can thus be manipulated by this program
as in an ordinary calculator-type program. Don't be put off
- I hardly ever need to use complex numbers; I just like the
facility to be there for the odd occasion when I do use
them.
¢1mExpressions
¢0m¢3micalc ¢0maccepts expressions in the usual form for computer
expressions, i.e. multiplication must be explicitly shown
by '*', and function arguments enclosed within parentheses.
The exception to this is the method of inputing imaginary
parts of complex numbers. If you want to enter the number 3
+ 4i, you can type either
3 + 4i
or
3 + 4*i
but ¢3mnot
¢0m3 + i4
since this would give an ambiguous grammar - is it i*4 or
the variable "i4"?
In almost all circumstances, the algebraic "4i" is
preferred, but there is one exception, exponentation "^". If
you want 3*i^3, you must type
3*i^3
icalc -2- version 1.1a
icalc User Guide icalc
and not
3i^3
The former gives the correct result, -3i, whilst the latter
gives -27i. This is because the grammar sees "3i" as a
number in its own right, and not an implicit
multiplication.
See the appendices for the complete list of commands,
operators, constants and builtin functions that ¢3micalc
¢0msupports.
Expressions are separated by newlines or semi-colons ';'.
You may also split an expression over multiple lines using a
backslash '\' to indicate continuation to the next input
line. Comments are introduced by '#', and the rest of the
input line is ignored. You may also place comments after
backslashes.
¢1mSample Expressions
¢0mx=1-iá# an assignment statement
assigns to variable x the value 1-i.
# and now, two statements separated by a semi-colon
sqr(x); x*sqr(x);
displays the values -2i and -2-2i. The next example
demonstrates a problem inherent in machine calculations:
2*sin(x)*cos(x) - sin(2*x)
displays the value 4.4408920985e-16 + 4.4408920985e-16 i.
The answer should be 0, and indeed is very close to that.
The inaccuracy results because each term has a value as
close to the actual value as the computer's internal
representation of numbers can hold.
¢1mStarting icalc
¢0m¢3micalc ¢0mmay be started from either the CLI or Workbench. It
will process the the file "s:icalc.init" if it exists,
before doing anything else. It is recommended that you use
NEWCON: or ConMan to provide editing and history
facilities.
CLI Usage
The synopsis for icalc is
icalc [file-list]
icalc -3- version 1.1a
icalc User Guide icalc
where file-list is a list of input files. ¢3micalc ¢0mwill read
(process) the files in the list and exit. If a file-list is
specified, ¢3micalc ¢0mwill assume that you do not wish to use the
program interactively. If you do, you should specify one of
the files as a dash "-"; this is taken to mean "use standard
input". If no file-list is given, ¢3micalc ¢0mstarts an
interactive session. You can obviously redirect output to a
file if you wish (and redirect input from a file, but this
is generally unnecessary). For example, if you wanted to
use definitions contained in a file called "stat.icalc", and
then type some expressions in at the terminal, you would use
icalc stat.icalc -
to start the program. Because the program makes extensive
use of recursion, I recommend you use a stack size of about
20K when running ¢3micalc.
¢0mWorkbench Usage
To start ¢3micalc ¢0mfrom the Workbench, simply double-click its
icon. You may also pass arguments (definition/command
files) to ¢3micalc ¢0min the usual Workbench manner (shift-select
etc.). ¢3micalc ¢0mwill then open a window on the Workbench
screen for an interactive session. You can specify the
window to be opened by modifying the WINDOW tooltype (click
once on the ¢3micalc ¢0micon, and select "Info" from the Workbench
menu). By default, this is a NEWCON: window.
You may also set the default tool of a definition file's
project icon to be ¢3micalc. ¢0mThen simply double clicking the
project icon will launch ¢3micalc ¢0mand read the definition
file. Remember, however, to set the project icon's stack to
20000, or you may get a stack overflow error.
Exiting icalc
To end an interactive session of ¢3micalc ¢0m(from either CLI or
Workbench) use the commands "quit" or "exit". You can also
type ^\ (press the control key and '\' simultaneously).
¢1mVariables
¢0mVariables in ¢3micalc ¢0mcan be named arbitrarily, as long as no
name conflicts with a pre-defined symbol name, such as sin
or PI. The standard conventions apply: the first character
must be a letter or underscore, followed by a string of
letters, digits and underscores. Case is significant.
Variables are introduced by using them; If a variable is
used before it has been initialized (i.e. has had a value
assigned to it), ¢3micalc ¢0mwill warn the user and use the value
zero. Assignments can appear anywhere in an expression, and
are in fact expressions in their own right (as in the
programming language C). So, you can do things like
apple = banana = apricot = 34
icalc -4- version 1.1a
icalc User Guide icalc
to assign the value 34 to these variables. Since
assignments are expressions, their value being the
assignment value, you can also do
apple = sqr(banana = 12)
which assigns the value 12 to "banana", and 144 to "apple".
You can of course assign new values to existing variables.
¢1mConstants and ans
¢0m¢3micalc ¢0mcomes with several predefined constants, e.g. PI,
GAMMA etc, which by convention are all in upper-case. You
cannot assign a new value to a constant. There is a special
constant, "ans", which isn't really a constant at all, but
is made so to prevent assignments to it. "ans" contains the
value of the previously evaluated expression, and so is
useful when splitting a calculation up into smaller chunks.
1 + 2 + 3
6
ans * 12
72
You can also use it for recursive formulas. For example,
the logistic equation xnext = rx(1-x) for parameter r = 3.5,
initial x = 0.4 could be iterated as follows:
rá=á3.5;á0.4á# initialize r and ans
3.5
0.4
r*ans*(1-ans)
0.84
r*ans*(1-ans)
0.4704
r*ans*(1-ans)
0.87193344
r*ans*(1-ans)
0.390829306734
and so on. Of course, you needn't use "ans" here; you could
just use assignments to "x", but it illustrates the point.
Note that once the necessary variables have been
initialised, the same expression is evaluated repeatedly.
Thus, if you are using a window with history capabilities
(such as NEWCON:) you can save a lot of typing.
There are other ways to perform repeated calculations in
¢3micalc. ¢0mThese are explained in the section "Special
Functions".
icalc -5- version 1.1a
icalc User Guide icalc
¢1mBuiltin Functions
¢0m¢3micalc ¢0mcomes with many builtin functions, for example sin,
cos, sqrt, exp, ln etc. There are some special functions
for complex numbers too, namely Im, Re, arg, norm. All
functions take real or complex arguments, which can be any
expression. Consider
sin(12-3i)
-5.40203477 - 8.45362342 i
asin(ans)
-0.56637061 - 3 i
sin(ans)
-5.40203477 - 8.45362342 i
Here we see a property of inverse trigonometric functions,
their many-valuedness, due to their periodicity on the real
line. The function asin returns a value in its PVR
(principal value range) as do all many-valued functions in
¢3micalc. ¢0mSee the file 'TechNotes' for exact definitions of
PVRs of the inverse trigonometric functions used in ¢3micalc.
¢0mOther functions owe their many-valuedness to the fact that
the argument of a complex number is 2*PI-periodic. In ¢3micalc
¢0mthe argument always falls in the range -PI < arg <= PI.
Another thing to bear in mind if you intend working with
reals is that things like
ln(-1)
return a value, 3.14159265359*i (PI*i) in this case.
¢1mUser¢0m-¢1mdefined Functions
¢0mUser-defined functions give ¢3micalc ¢0mits flexibility and
power. Any function that can be stated as a normal
expression (or list of expressions) may easily be defined
and used like a builtin function. Functions are defined in
the following manner:
func <name> ( <parameter-list> ) = <expr>
so to define the function f(z) = sin(sqrt(z)), simply type
func f(z) = sin(sqrt(z))
Note that z is ¢3mlocal ¢0mto the function, not a global
variable. Thus, if z has been defined as a variable before
defining f(z), it is unaltered when you call f(z). There
are a number of sample definition files included with
¢3micalc. ¢0mYou may find it instructive to examine them.
Multi-parameter functions may also be defined. For example,
the volume of a right-circular cone is given by the formula
icalc -6- version 1.1a
icalc User Guide icalc
volume = 1/3*PI*sqr(r)*h
where r is the radius of the base, and h is the height of
the cone. We can define a function to compute the volume as
follows:
func conevol(r,h) = 1/3*PI*sqr(r)*h
conevol(1,3)
3.14159265
It is also possible (though of limited use) to declare
functions that take no parameters. Examples of
multi-parameter functions are given in the sample definition
files.
As with most programming languages, don't write circular
definitions; ¢3micalc ¢0mdoes not detect them, and will swiftly
run out of stack space. Recursive functions fall into this
category, as there is no way to specify terminal cases.
¢1mSpecial Functions
¢0mCertain builtin functions in ¢3micalc ¢0mare called ¢3mspecial
¢0mbecause of the way they use their arguments. Normally, when
you `call' a function, its arguments are first evaluated and
then the function is called. With special functions
however, the arguments are not evaluated; this means that
the expressions themselves (and not just their values) can
be used by the function in a number of ways. Some special
functions take integers as arguments; if you supply an
expression with a non-integral value, this value will be
stripped of it's imaginary component, and the remaining real
number rounded to the nearest integer. Currently, the
special functions are as follows.
Sum(var,upto,expr)
This command calculates finite sums. The variable `var' is
the index of summation, with an optional assignment. While
the value of the index is less than or equal to the value of
the upto argument, the value of expr is added to an internal
summation variable, which is initially zero. Examples will
help to clarify usage.
To evaluate the sum of the first 100 natural numbers
(naively) we could do
Sum(n=1,100,n)
which gives the answer as 5050 (which is 100/2*(100+1)).
Note the initial assignment of 1 to n. If no initial value
is specified, a value of zero is assumed (and the user is
notified of this). When a summation is complete, the index
variable holds a value 1 greater than the value of upto. We
can also use Sum() to provide approximations to infinite
sums.
icalc -7- version 1.1a
icalc User Guide icalc
Sum(n=1, 100, 1/sqr(n))
1.6349839
Using the fact that n will now hold the value 101, we can
continue the summation to 200 by the following:
ans + Sum(n, n+99, 1/sqr(n))
1.63994655
and continue to obtain closer answers by repeating the last
line,
ans + Sum(n, n+99, 1/sqr(n))
1.64160628
which is getting there (the infinite series sums to PI^2/6 =
1.64493407). One last example, to evaluate the sum of the
all even numbers upto 100.
Sum(n=1, 50, 2*n)
2550
Prod(var,upto,expr)
This command calculates finite products, in an analogous way
to the Sum() special function. Examples will demonstrate
its use.
Prod(n=1, 10, n)
calculates 10!, which is 3628800. We can also use Prod() to
investigate infinite products, although care should be
taken. Consider Wallis's product for PI/2:
PIááá 2╫2╫4╫4╫6╫6╫...
-- = ---------------
2áááá 1╫3╫3╫5╫5╫7╫...
Here the product is 2/1 * 2/3 * 4/3 * 4/5 * ... and so we
must find a method of producing the numerators and
denominators from an index. It is easiest to evaluate the
product in pairs of terms. Thus, for each term our
numerator will be sqr(2*n), and our denominator will be
(2*n-1)*(2*n+1) = sqr(2*n)-1. Note that sqr(2*n) appears in
both the numerator and denominator. We can therefore
optimise the calculation by using a temporary variable to
hold this value. We proceed as follows:
Prod(n=1, 100, (t = sqr(2*n))/(t-1))
1.56689375
ans * Prod(n, n+99, (t = sqr(2*n))/(t-1))
1.56883895
ans * Prod(n, n+99, (t = sqr(2*n))/(t-1))
1.56949005
icalc -8- version 1.1a
icalc User Guide icalc
every(var,upto,expr) and vevery(var,upto,expr)
These functions preform more general iterations than Sum()
and Prod(). They return the value of the last expression
evaluated, ie. expr evaluated when var = upto. The
difference between every() and vevery() is that the latter
produces verbose output - it prints the value of the index
and the result of the expression for every iteration.
Example: evaluate sin(sin(...(sin(z))...)) with sin()
applied 10 times. Here we'll take z to be 1-i.
last = 1-i; every(n=1, 10, last = sin(last))
0.51856952 - 0.01039404 i
Although every() and vevery() are useful in some situations,
most iterations are more easily performed by using Sum() and
Prod().
multi(expr1, expr2, ... , exprN)
This special function takes an arbitrary number of
arguments, and evaluates each of them from left to right.
It returns the value of it's last argument, exprN. multi()
was added to make the addition of certain user-functions
possible. For example, the one-variable statistical
analysis suite given in the file "stat.icalc" uses multi()
to update the values of many variables with one function
call. If output has not been switched off with the silent
command, a call to multi() will print the result of it's
last argument. In order to print the results of other
arguments, the builtin function print() is supplied.
print() takes one argument, prints it to the display, and
returns its argument as a result. In this way, expressions
can appear to return more than one result.
An example: write a function that converts Cartesian
coordinates into polar form, returning the radius and angle
in degrees, and setting the variables r and theta to these
values.
func rec2pol(x,y) = multi(r = print(sqrt(x*x+y*y)), \
theta = DEG*arg(x+i*y) )
rec2pol(3,4)
5
53.13010235
Note the use of complex argument to obtain the correct
quadrant.
Examples of the many uses of these special functions can be
found in the example icalc script file "stat.icalc" and the
startup file "icalc.init".
icalc -9- version 1.1a
icalc User Guide icalc
¢1mCommands
¢0m¢3micalc ¢0mhas a few commands to make life easier.
quit
exit
not surprisingly, these commands terminate ¢3micalc.
¢0msilent
stops generation of any further output. However, errors and
warnings are still displayed. It is useful for
initialization files containing lots of definitions.
verbose
restores generation of output.
help
reminds you what other commands are available.
vars
lists all currently defined variables and their values.
consts
lists all predefined constants and their values.
builtins
lists all built-in functions available, including special
functions.
functions
lists all user-defined functions, with their parameter
lists.
¢1mBugs
¢0mOne major bug has been fixed in this release - the sqrt()
builtin was not returning values in the correct quadrant.
Consequently, the inverse trigonometric functions, which are
defined using sqrt(), broke. This has now been corrected.
Thanks to Pierre Ardichvili for pointing this out.
I hope that's all the major bugs ironed out, but there may
be the odd little bug in there somewhere -- if you find any,
PLEASE let me know and I'll try to fix them.
If there's something you hate about ¢3micalc ¢0mand would like
changed, or something you'd love that's not in, drop me a
line (at the address below), or email me.
¢1mCompiling
¢0m¢3micalc ¢0mwas written using Lattice C (version 5.10a) but should
compile with no problems with Manx C. I use the version of
bison on Fish #136; if you're using a later version or Yacc,
you may need to change the makefile.
icalc -10- version 1.1a
icalc User Guide icalc
The code is meant to be portable, so Amiga-specific code
(there's not much) is #ifdef'd. Also, to implement the
WINDOW tooltype, I've used a slightly modified version of
Lattice's _main function; since I'm probably not permitted
to distribute the modified source, I've included just the
compiled module, myumain.o.
¢1mCredits
¢0mThanks to the GNU team for bison (it makes these things so
much easier to write and modify) and to William Loftus for
the Amiga port.
Thanks also to Steve Koren for Sksh, and Mike Meyer et al
for Mg3; together they make a great development
environment.
This is my first bison-based project, and I learnt a lot
from "The Unix Programming Environment" by Brian Kernighan
and Rob Pike. Their "hoc" taught me a lot about using Yacc.
¢1mDistribution
¢0m¢3micalc ¢0mis not public domain. You are permitted to distribute
it at only a nominal charge to cover costs. All files
should be included, with the exception of the source files
(in the "src" directory). Under no circumstances should a
modified version of ¢3micalc ¢0mbe distributed. If you make
modifications which you feel may be useful, send a copy to
me and I'll (probably) include them with the next release.
¢1mThe Bottom Line
¢0mAlthough contributions are not required, they would be most
welcome (I'm a poor student). Don't let that inhibit you
from sending bug reports, praise, suggestions, neat programs
etc. I'd get most pleasure from hearing if anyone actually
uses this bloody program! And thanks to those kind people
(small in number) who have written to me.
I can be contacted via snail mail at:
Martin W. Scott,
23 Drum Brae North,
Edinburgh, EH4 8AT
SCOTLAND.
or you can email me - my address is mws@castle.ed.ac.uk
Thanks for reading this far. The appendices follow.
icalc -11- version 1.1a
icalc User Guide icalc
¢1mAppendix 1 ¢0m- ¢1mOperators ¢0m(¢1min increasing order of precedence¢0m)
=áááá assignment
+áááá addition
-áááá subtraction, unary minus
*áááá multiplication
/áááá division
^áááá exponentation
'áááá conjugate: z' = conjugate of z
¢1mAppendix 2 ¢0m- ¢1mConstants
¢0mPIááá 4*atan(1) (that's one definition)
Eáááá exp(1)
GAMMA Euler's constant, 0.57721566...
DEGáá Number of degrees in one radian
PHIáá Golden ratio 1.61803398...
LOG10 ln(10)
LOG2á ln(2)
¢1mAppendix 3 ¢0m- ¢1mBuiltin functions
¢0mSingle-argument functions: (* = new in version 1.1a)
sináá trigonometric functions
cos
tan
asiná inverse trigonometric functions
acos
atan
sinhá hyperbolic trigonometric functions
cosh
tanh
expáá exponential function
lnááá natural logarithm
sqráá square
sqrtá square root
conjá conjugate (see also ' operator)
absáá absolute value (sqrt(norm(z))
normá not really norm; if z=x+iy, norm(z) = x▓+y▓
argáá principal argument (in [-PI,PI))
Reááá real part of complex number
Imááá imaginary part of complex number
min * returns minimum real part in args (eg. min(1,2,3-i) = 1)
max * returns maximum real part in args (eg. min(1+4i,2,3) = 3)
intáá return real part rounded to nearest integer
ceilá ceil of real part (eg. ceil(1.2) = 2)
floor floor of real part (eg. floor(1.2) = 1)
sgn * sign of real part (eg. sgn(-1.6) = -1)
time * returns system time in seconds, less its argument
print prints and returns the value of its argument
precá adjust number of decimal places displayed
icalc -12- version 1.1a
icalc User Guide icalc
Special functions (for more details, see the section headed
"Special Functions" above):
Sumáá calculate a finite sum
Prodá calculate a finite product
every perform a general iteration quietly
vevery perform a general iteration verbosely
multi evaluate many expressions
icalc -13- version 1.1a