Category : Science and Education
Archive   : CC4.ZIP
Filename : UPDATE.CC

Output of file : UPDATE.CC contained in archive : CC4.ZIP
This file records the changes I have made to the published program CC-The
Calculus Calculator. The new version is called CC4 and should be treated as
experimental. Everything about CC is copyrighted by my this year, 1991--the
source code, the object code, the help file, even this file. For more
information about CC, call or write me:

David Meredith
Department of Mathematics
San Francisco State University
1600 Holloway Ave.
San Francisco, CA 94132

completed altering saving of last graph to list of graphics commands.
Also fixed vertical write so correct area blanked before writing, and
correct area checked for off/screen.
Now last graph takes much less space for EGA,VGA screens. speed is ok.

changed exit key to ^Q, deleted confirmation, but added "do you want to
save your work"
fixed it so cancels printing of long variable list.

changed display so only first 10 items in list are displayed. Also
eliminated hide and show as no longer necessary. When variables printed
with F2 only first ten items of list are printed followed by ...more... .
To print entire variable, use F8 or PRINTVAR (cf. 9/19/90).

added Xor to list of operators. Works on booleans and integers. Also
have broken CC up into a large number of overlays.

have added lots of matrix operations. See below. Also now error in
execution of subroutine puts you in subroutine window with bad line

Three-d graphing commands redone completely. The basic commands are
simplified by the assumption of defaults in place of required
SEPERATOR MUST ALSO BE USED. Otherwise there is not enough
information in the input for CC to parse it.

The step parameter is the NUMBER OF STEPS, not the size of a step.

Here are the three-d graphing commands with options:

Paramg3d(f(s,t),g(s,t),h(s,t),s=a to b [step c]; t = e to f [step g]
[; x1 to x2,y1 to y2,z1 to z2])
if the any of the optional x,y,z limits are present, all
msut be. Without them, CC uses the min and max of f,g,h
respectively as the x,y,z limits.

Graph3d(f(x,y),x=a to b [step c];y=e to f [step g][;z1 to z2]);

Curve3d(f(t),g(t),h(t),t=a to b [step c]
[; x1 to x2,y1 to y2,z1 to z2])

This is the graph of a matrix. You can optionally
specify the vertical limits of the graphing space,
otherwise the max and min of the matrix elements are

One improvement over CC3 is that the two parameters can have a
different number of subdivisions. Also curves are drawn directly, not
faked. The default step is 15. the total number of points that can be used
--(step1+1)(step2+1)--is 1600.

Here are sample minimal 3d graphing commands.

graph3d(x^2 - y^2, x=-1 to 1, y = -1 to 1)
Paramg3d(sin(s)cos(t), sin(s)sin(t),cos(s),s=0 to pi, t=0 to 2pi)


Matrix Commands

Matrix commands include arithmetic + - * / \ .* ./. . +, -, * are as
expected. A/B = A*B^(-1). A\B = A^(-1) * B . A^n is defined for positive
and negative integers n if A is square. To get the inverse of a matrix,
you can enter A^(-1), but it is easier to enter 1/A .

The operators A .* B and A ./ B
operate between same size matrices and multiply or divide elementwise.

Scalar functions like SIN and EXP work
inside matrices unless specified to work on entire matrix. New functions
include Rank, RREF, LU (invertible matrices only), QR, Balance (temporary
--will be hidden), Det,.

To define a matrix, either enter the data surrounded by braces and rows
seperated by semicolons:


or use the command MATRIX(a(i,j),i=....j= ...). See below for more on

Special matrices can be defined with

Diag(x) where x is a list or an n x 1 or 1 x n matrix
Eye(n) n x n identity
Zero(n,m) Ones(n,m) n x m matrix of zeros or ones.

To define a submatrix of a matrix A, use A[i:j, k:l]. The i,j element
of a matrix A is A[i,j].

Matrices can be defined with the command MATRIX as follows. If the
step is not used, the semicolon can be any seperator and the default
step will be 1.

Matrix(f(x,y),x=a to b [step c]; y = e to f [step g])

Here the step parameter is the SIZE of the step.

to mark text, move the cursor to the beginning of the text to be marked,
then push F3. Move cursor to end, then push either or .
moves text to save buffer; does the same but deletes the
marked text as well.

To mark an entire entry, push Shift-F3, then or .

To insert the saved text, move the cursor to the point of insertion and
push F4.

When new text is saved, the original text is moved to a new buffer.
There are ten buffers, which are accessed by F4, Alt-1, Alt-2,...,
Alt-9. When new text goes into the F4 buffer, each existing buffer
moves up one, and the Alt-9 buffer is discarded.

(**********) This material is changed. See 1/31/91
***Pushing F3 twice inserts a blank line.
(**********) This material is changed. See 1/31/91
Lines can be erased without saving with Control-Y.
Shift-F4 erases all text buffers--if you need to recover the memory.

Improved the solver routine to take care of functions singular at their
roots. Done by replacing f(x) = 0 with f(x)/f'(x) = 0. When this routine
entered, the phrase Super Solver appears on the screen.

9/19/90 (revised 11/15/90)
Data files

To print the last graph, issue the command:


To save the last graph for later reloading, use:


The filename must be a string (path allowed) surrounded by single quotes
or a variable containing such a string. You could use either:



pixfile = ''

To load a saved graph and display it, use:


This will erase the current Last Graph.

To save a list (or single datum or matrix) from a variable to a file, use:

SaveVar(variable-name, filename)

To load a variable from a file (like the file saved above):

LoadVar(variable-name, filename)

Note that the entries can be numerical formulas as well as numbers. CC will
read and evaluate any legal CC numerical formula (no variables or user-
defined functions) found in the file.

To print the values of a variable, use:


When CC saves a variable, it creates an ASCII file beginning with a line
containing one of the words LIST VARIABLE MATRIX. If the file starts with
VARIABLE, it should have one more line with a value or formula. If the file
starts with LIST, it should consist of a series of lines with one number or
formula per line. If the file begins with MATRIX, there will be several
values or formulas on each line seperated by commas, with the same number on
each line.

You can create your own files for loading into CC by following these rules.

Added command WAIT(n), which causes computer to pause n seconds. Useful
in between GRAPHICS and TEXT to pause a picture. To pause until a key is
pressed, use PAUSE.

Changed command BKCOLOR to CURRENTBKCOLOR. This returns current
background color. Added two commands BKCOLOR(color number) which sets
the background color, and AXISCOLOR(color number), which sets the
color of the axes. Presently the color of the crosshairs cannot be
changed. These commands should be used in conjunction with AXISON,

Crosshair color now determined by AxisColor

Fixed Div and Mod to work with negative integers.

Due to self-imposed limitation on the length of function names, I have had to
change some commands.

SETCOLOR(BLUE) makes the next line or graph blue

COLOR is a function that returns the color of the next graph

SETBKCOLOR(BLUE) makes the graphics background blue

this is the one that was too long. BKCOLOR is a function that
returns the current graphics background color

added bignums--infinite precision integers and fractions. To enter a
bignum, precede it with &, eg &123456789. Bignums can be added,
subtracted, multiplied and divided with each other and with integers.

A note on differentiation which is not covered in any of my manuals.
Certain operators are invisible to differentiation. For example,
d/dx(Hex(f(x)) = hex(df/dx). Same for the operators Integer, Bin,
Transpose, Fix, Float.

Bignums now work pretty well. You can enter a bignum with or without a
decimal: &35.8 = 179/5. Bignums can be added, subtracted, multiplied and
divided. You can raise them to integral (but not bignum) powers or take
their factorials. Try &3^100 and &100! . Bignums combined with integers
result in bignums,but bignums combined with non-integral reals or with
complex numbers result in floating point values.

When transcendental functions are applied to bignums, like SIN, the bignum
is first changed to its floating point equivalent, then the function is
computed on the floating point value.

Any bignum can be changed to its floating point equivalent with the functin
FLOAT(x). If x is not a bignum, it is unchanged. Any real or complex
decimal can be changed to a bignum equivalent with the function FIX(x). Be
careful with this function. If you want 1/3, enter &1/^&3 (or &1/3 or
1/&3 or 1/fix(3) ), not fix(1/3). Fix(1/3) is a horrible fraction whose
denominator is 2^40. CC first changes 1/3 into an approximating floating
binary number, then converts this to a fraction.

Matrices with ALL bignum or integer entries
can be added, multiplied, subtracted and divided with bignum results. Also
the functions LU, DET, RANK, and RREF can be applied to bignum matrices
with bignum results. Because squareroots are involved, QR and BALANCE
always return a floating point result.

Lists can also have bignum entries. SUM, PRODUCT, MAX, MIN and AVERAGE
return bignum result when applied to a list of bignums and integers, but
STANDEV and REGR return floating point results, again because square roots
are involved.

Here's a special problem: to define the Hilbert matrix, you could say:

H(n) = Matrix(&1/(i+j-1), i = 1 to n, j = 1 to n)

but this won't work. CC changes this into &1*(i+j-1)^(-1), and the second
factor gets evaluated to a real which, when multiplied by &1, yields a
floating point real. You must say:

H(n) = Matrix(1/fix(i+j-1), i=1 to n, j = 1 to n)

Bignums are slow to compute with. On my medium speed AT, it took over one
minute to compute det(H(10)) .


(********* this paragraph is now superceded. see 1/3/91. The comments are
still correct.
List operations work on matrices, going across the rows one by one. You can
say SUM(A) or MAX(A) or even STANDEV(A) when A is a matrix. You can do
regression against two matrices (of the same size) or apply LISTG to a pair
of matrices. **********)

added a function SOLVEPOLY with eye to developing eigenvalue
routines. The syntax is SOLVEPOLY(x) where x is a list of
coefficients for a polynomial with constant coefficient listed
first. The function returns a list of roots. It fails on
polynomials with coefficients of very different sizes or very small
coefficients (work in progress) but works on reasonable polynomials.
User beware. Example:

x = (1,-3,3,1)
SOLVEPOLY(x) // returns (1,1,1)

Still finishing up SOLVEPOLY. I think it will have to fail on the
following example, which seems very hard:

x^5+1000x^4+x^3+x^2+x+1 = 0

I can solve this by hand--it has one large root near -1000 which can
be gotten at with a binary search, and four small complex roots.
These are best found by finding their inverses as roots of

x^5+x^4+x^3+x^2+1000x+1 = 0

I've also removed one annoyance. Now, if you enter x(y+1) meaning
x*(y+1), CC will recognize that x is a variable, not a function and
instead of returning an error message will perform the
multiplication. If this causes any ambiguities or other problems,
please let me know.

Added two functions. LOG10(x) is log base 10. It only works on positive
reals. TRACE(x) is the trace function for matrices.

I've been experimenting with eigenvalues and SOLVEPOLY. I coded
Fadeveev's (sp?) algorithm for the characteristic polynomial in the
subroutine window, then used SOLVEPOLY on the result to get the eigenvalues
of a matrix. I created the hilbert matrix with bignums (so the
characteristic polynomial consisted of bignums too, but of course the
solutions returned by SOLVEPOLY were real), found the eigenvalues, and
computed the rank of matrix-eigenvalue*I . Up to size 5, the rank was one
less than the size. For size 6 and larger, the eigenvalues were not so
accurate. The computation for size 6, using bignums, required about 15

The commands LOADM SAVEM PRINTM have been eliminated. CC is smart enough
to use LOADVAR SAVEVAR PRINTVAR and know when a matrix is involved. See
revised comment following 9/19/90.

Note that bignums cannot be saved and read back yet. (11/23/90 now they

Matrix algorithms are coming along. I've added CHARPOLY(x) which takes a
matrix as an argument and returns a list representing a polynomial
(constant term first). If x is Hermitian, CHARPOLY is forced to return
real coefficients.

I've also added EIGENVAL(x), which takes a matrix x as an argument and
returns a list of eigenvalues, sorted in order of decreasing magnitude. If
x is Hermitian, the eigenvalues are forced to be real.

We also have EIG(x), which takes a matrix x as an argument and returns a
list of two matrices. If you enter

e = EIG(x)

then e[1] is a diagonal matrix with the eigenvalues on the diagonal, and
e[2] has the corresponding eigenvectors in its columns. If x has repeated
eigenvalues, then the eigenvectors for repeated eigenvalues are selected to
be orthogonal. If the matrix is deficient (some eigenvalue has an
insufficient number of eigenvectors) then the matrix of eigenvectors has
columns of zeros replacing the missing eigenvectors. So long as x is not
dificient, x = ev[2]*ev[1]/ev[2] . That is, the command EIG diagonalizes

Bignums can be saved with SAVEVAR and loaded with LOADVAR.

I added some display features to EIG, SOLVEPOLY, CHARPOLY, EIGENVAL, SOLVE,
IMPLICIT and IN so that the user would have something to watch while these
relatively slow commands work.

Finally, for today, I changed the commands that set some of CC's
parameters. Now we have commands to set the parameters:


Setting x = 0 in these commands (or using any other illegal value) causes
the corresponding parameter to be reset to its default value. No longer
need you look up the default values in the manual.

The commands:


all return the current values of the corresponding parameter. Previously,
these commands set the parameters.

Just finished singular values. If A is an n x m matrix of rank r, the
command S = SVD(A) returns a list of three matrices:
S[1] is n x r with orthonormal rows
S[2] is r x r diagonal with the singular values on
the diagonal. The singular values are always
positive real numbers.
S[3] is m x r with orthogonal rows

Moreover, A = S[1]*S[2]*S[3]"

The command P = PINV(A) returns the pseudo-inverse of A, which is
P = S[3]/S[2]*S[1]"

Remember, B" is the conjugate transpose (Hermitian) of B.

The ratio of the largest and smallest singular values is called the
condition number of A, and can be computed directly with the command

As suggested by Professor Alex Calders of Duffel, Belgium, I've added two
new input commands. Previously, when you executed INPUT or INPUTS on a
graphics screen, you got a large box which obscured much of the screen.
The new commands are INPUT@(x,y,n,a) and INPUTS@(x,y,n,a), where (x,y) is
the coordinate of the lower-left corner of the region where you want the
user to type the input, n is the number of characters room is made for, and
a is the variable which will receive the input. INPUT@ gets numerical
input; INPUTS@ gets string input. INPUT@ only works in subroutines when
GRAPHICS is active.

Note that this new input command does not include provision for a message
to the user. This command should be used in conjunction with WRITE@. Use
WRITE@ to put instructions on the screen, then create the input box at a
convenient point on the screen where the user can type a response.

If you try to place the input box too high on the screen,it will be
automatically lowered, and if you try to place it to far to the right for
the number of characters you wish to accomodate, it will be automatically
shifted to the left.

Note that the graphics cursor is alive while waiting for a response to
INPUT@--the graphics cursor is not active while waiting for a response to
INPUT or while a message created by WRITE is on the screen.

Here's a simple example:

procedure test
Write@(.1,-.6,'Enter x-coordinate where curves intersect')
ok = x > b-.05 and x < b+.05
if not ok
until ok
Write@(.1,-.8,'You got it!!')

The procedure graphs two curves on the screen and asks the user to input
the x-coordinate of their intersection. The request repeats until the user
inputs an answer within 0.05 of the correct one.



Altered the configuration (Control-F9) routine to allow you to add page
length (in lines), as requested by European correspondent. Also recently
fixed some bugs in config routines, so you MUST remake your config files if
you are using one. Do this by erasing the configuration file CC.CFG while
outside of CC, then creating a new one from within CC by pressing

Note: you set the total number of lines on your page; CC will allow for a
top and bottom margin.

Also added a form-feed or skip-to-top-of-page command to the print (F2)
menu. This will be useful for laser-jet users, but beware: CC not only
skips to top of page but starts the next page, positioning the print head
to write the first character on the next page.

Changed the effect of F8. Now you can no longer load a graph through this
key, only a file of commands, so you will not be prompted to choose G for
graph or C for command file. After pushing F8, you will be asked directly
for the name of the command file to load. Graphs must be loaded with the
command LOADGRAPH(filename).

Changed the directory command from shift-F1 to shift-F8, since F8 is my
file input key. After viewing the directory, you have the opportunity to
make that directory your primary directory. Also added Control-F8, which
is a simple change directory command.

Added commands ROWVECTOR(X) and COLVECTOR(X), which take a list X and turn
it into a 1-row or 1-column matrix. If X is not a list, the result is a
1x1 matrix whose sole entry is X.

Fixed 3d graphs so that (a) axis labels print horizontally, not paralell to
the axes, and (b) if the axis points in the negative direction, a negative
sign is added to the axis name.

Merry Christmas. The matrix editor is completed. Now, when you compute a
matrix, it will be shown in spreadsheet format. You can cursor around it
with the arrow keys, the control-left and right keys, pgup and pgdn,
control-home and control-end. The highlighted element is displayed at the
bottom of the screen, so even if it isn't completely displayed in the
matrix you can see it by highlighting it.

If you produce a formula with more than one matrix, each will be shown in
turn. For example, if you compute A/B, with B a matrix with symbolic
entries, both A and B will be displayed, and the result
Matrix(.,.)/Matrix(.,.) shown in the Output Window.

You can also edit matrices with the spreadsheet. To create or change a
matrix A, execute the command:


If A is not a matrix, its contents will be lost. You can move around A
with the arrow keys, etc, as above, adding or changing elements in the

This command can also be used to view a matrix.

If a matrix is displayed as a result, without possibility of editing, the
highlighted element is shown in boldface or a different color. In this
case you cannot cursor beyond the boundaries of the matrix. If the matrix
is displayed as a result of the MEDIT command, the highlighted element is
reversed and can be changed. In this case you can cursor beyond the
current boundaries of the matrix and make the matrix larger by adding
elements. You do not need to fill in all the elements--blank elements will
be filled with zeros.

Now there are four ways to create a matrix:
Surround its elements with braces: {1,2,3;4,5,6}
Use a formula: Matrix(1/(i+j-1,i=1,5,j=1,5)
Read it from a disk file: LoadVar(A,'filename')
Create it with MEDIT: MEdit(A)

Happy New Year. Just added some string operators. Strings are entered by
surrounding them with apostrophes: x = 'abcde' . Now they are displayed
with apostrophes to distinguish them in the output from undefined variable
names. Strings can be used in WRITE and INPUT statements, they can be
compared for position in alphabetical order, and now they can be

To extract the third character from a string, use x[3]. The result is a
string of length 1, unless x has fewer than 3 characters. In that case the
result is the empty string '', or the string of length 0. To extract the
substring consisting of characters 4..7, use x[4:7] or x[4,7]. If x has
fewer than 7 characters, then all characters of x, beginning with the 4th,
will be returned. If x has fewer than 4 characters, the empty string is

Strings can be concatenated with | just like lists. 'abc' | 'de' returns
'abcde' .

To determine if one string x is a substring of another string y, use the
function POS(x,y). (POS means position.) POS returns 0 if x is not a
substring of y, otherwise it returns the position of y corresponding to the
starting point of the substring x. POS('abc', '12abcde') returns 3.

The length of a string can be determined with the function LENGTH(x).

The function UPCASE(x) returns a string y which is the same as x except
that all lower case letters a..z are replaced with upper case letters A..Z.

If x is a string, then ASC(x) returns a list of integers that are the
ASCII codes of the characters of x. If x is a string of length 1, then
ASC(x) is an integer, not a list of length 1.

Conversely, if x is an integer or a list of integers in the range 32..255,
then CHR(x) is a string whose character codes are in x. If x has entries
outside the required range, they are ignored. NOTE: strings with
characters in the range 129..255 will not print on the graphics screen.
Turbo Pascal does not support them in graphics mode. ***now they do
see 1/27/91***

Changed the statistical functions for matrices. Now SUM MAX MIN AVERAGE
STANDEV, applied to a matrix, return a row vector containing the
appropriate value for each column of the matrix. If matrix has only one
column, a scalar rather than a 1 x 1 matrix is returned.

REGR(m), for a matrix m, works as follows. Let p be the same as m, but
replace the last column by 1's, and let b be the last column of m. Then
REGR(m) = pinv(p)*b. Thus REGR is a column vector whose length = the # of
columns of m. If m is r x 2, then if we think of the rows of m as points,
the elems of regr(m) = (c,d)" and y = cx+d is the regression line through
the points. More generally, REGR(m) = (r1,...,rn) where the hyperplane
most nearly approximating the rows of m is

xn = r1 x1 + r2 x2 + ... + rn-1 x-1 + rn

Added a sorting routine for matrices. The function SORT(m,i) sorts the
rows of the matrix m on the data in column i and returns a sorted matrix.
m is unchanged, unless you use the command m = SORT(m,i) .

To sort on two columns, first sort on the secondary key, then on the
primary key.

The command SOLVEPOLY (11/7/90 and following) now has a complement: if p
is a list representing a polynomial, and x is a value, then


returns the the value p(x). EVALPOLY uses Horner's method, so it will be
faster on large polynomials than defining a function equal to p and
evaluating it:

f(t) = SUM(p[i]*x^(i-1), i = 1 to length(p))

The difference can be seen if you take p = LIST(1,i=1,100) and x = 2.

Finally, there is a ZOOM feature for graphics. To magnify part of a graph
DIFFG and INTEG, not LINE, FILL, WRITE, etc.) move the crosshairs to one
corner of the region to be magnified. Press control-Z (the crosshairs
change to Z) and use the cursor keys to move the Z to the opposite corner
of the region to be magnified. Press and your graph will be

If you want to cancel the zoom command, press . To restart the
window at the current location of the Z, press Control-Z again.

After zooming your window, the window parameters WINDOWLEFT etc. will be
changed to reflect the new window.

If you zoom on a curve drawn with PARAMG or POLARG, much of the curve may
be outside the zoomed window, since you won't have changed the limits of
the parameters.

Now you can use WINDOW(0,0,0,0) to restore the window limits to their
original values, which were WINDOW(-1.4,1.4,-1,1) . *** this is changed
see 2/10/91 ***

To complement CHR and ASC, I've added VAL and STR. If s is a
string, then VAL(s) returns the numerical value of s. s may be any
legal CC formula. Conversely, if x is a value or CC formula, then
STR(x) returns a string representing the value of x. Examples:

VAL('12') = 12
VAL('Cos(PI)') = -1
STR(3) = '3'
STR(Cos(PI)) = '-1'

Complex values and bignums can be used with VAL and STR.

Added a new command: FIELD(f(x,y),g(x,y),x,y) draws vector field (f,g) in
current window. Example: FIELD(-y,x,x,y)

The resulting vectors are not strictly proportional to their true lengths.
Although longer vectors appear longer, at least if they are parallel, the
proportion between longest and shortest vector has been reduced so that
individual vectors aren't reduced to single points. However, if one vector
is very long, the others may virtually disappear. This will happen, in
particular, if there is a singularity at the origin of the vector field.
Then, if you draw one vector very close to the origin, it will dwarf the
others. To avoid this, see the next comment.

Normally 15 x 15 vectors are drawn. You can change this value by adding a
different number of vectors in each direction after the direction
parameter: FIELD(-y,x,x,10,y,10) . If your window is symmetric about the
origin, you can avoid placing a vector near the origin by choosing an even
number of vectors in each direction.

Also, to complement Zoom, after zooming you can press Control-U to
UnZoom--go back to prior window. *** See 2/8/91 for information on
expanded UnZoom. ***

We are at war.

I've started compiling with Turbo Pascal 6.0. This gives me new stroked
fonts with all the characters with codes 32-255. I've changed from the
triplex font to the small font for all writing, including the text which
was previously written in the default (bitmapped) font. Internally I'm
using sizes 4-10, but externally, you should use size codes 1..7 for
Write@, VWrite@, Write@c and VWrite@c. The default size is 2, matching the
text used by CC to label the ends of the axes, the coordinates of the
crosshairs, and the message at the lower left of the graphics screen.

I've also added two commands to complement vector fields:

TRAJ(f(x,y),g(x,y), x = a, y = b)

draws a trajectory through the vector field (f,g) beginning at (a,b).
Normally 50 segments are used to draw the trajectory. You can change this
number by adding a value after b.

LEVELC(f(x,y)=g(x,y), x = a, y = b)

draws the graph of f(x,y) = g(x,y) both ways from the solution point
closest to (a,b) . Normally 50 segments are used to draw each half of the
solution curve; you can change this value by adding a different number
after b.

TRAJ(-y,x,x=.5, y=.5, 100)
LEVELC(x^2+y^2 = 1, x=.7, y=.7, 30)

*** see 2/9/91 for a step size parameter ***

I seem to have neglected to list a couple of matrix commands.

TRANS(a) transpose of a
CONJ(a) conjugate of a
a" conjugate transpose or Hermitian of a
rows(a) number of rows of a
cols(a) number of columns of a
rank(a) rank of a
it may be necessary to jigger matrixtol a bit to get
this value to come out right.
det(a) determinant of a

A minor fix: previously the INPUT(a,b) command required a specific string
in apostrophes at a and a variable name at b. The variable name is still
required, but the first entry can be any expression at all:

'input third value' a string
x a variable
(where previously we executed
x = 'input third value' )
Cos(4.5) an expression--the value is
Cos(4.5t) an expression with undefined terms

It is particularly useful to be able to store the input prompt in a
variable and use the variable as the prompt in the input statement.

Changed the InsertLine key from F3 F3 to Control-Enter. This is easier and
more natural, and you don't have to count the number of times you push F3
to get an even number. This required changing the mnemonic info at the top
of the screen.

Added protected lines. If you save a file with Alt-F7, then reload it with
F8, you won't be able to alter any of the non-blank lines. You can,
however, add lines where there are blank lines and open up new lines with
Control-Enter. If you save the file with F7 after adding more to it, the
added material will not be protected, but the original protected lines stay
protected. To protect the entire file, save with Alt-F7.

To unprotect a file for editing protected lines, load it with Alt-F8.

Protected lines are useful for writing lessons, etc. You can prepare a
lesson that the student can't write over, leaving blank space for the
student to write in.

Added five operations to the editor:

Control-RightArrow and Control-LeftArrow now move by words, stopping
at spaces and the characters ( = + - * / \ [ { ^ < >

Control-Backspace erases an entire word to the left, stopping at the
same set of characters.

Control-PgUp and Control-PgDn move the cursor up and down one entry
at a time.

I tried to add Control-Delete to erase an entire word to the right, but
Turbo won't recognize this key when compiled under TPC, although it does
recognize it in the IDE. I've written to Borland.

Sometime earlier, I added but forgot to note:

Control-B -- delete left of cursor to beginning of line
Control-T -- delete right of cursor to end of line
Controy-Y -- delete entire line

Fixed the data file loading routines LOADVAR. Added the capability of
reading text files into lists of strings. To create a textfile for input,
begin it with the line TEXT, then put any lines you want. Here's a sample

Put any information that you
want into these lines.

Blank lines can be included.

Suppose that these lines were stored in a file called TEXTFILE.CC. The
following subroutine would read the file and display it on the graphics

Procedure Display
// Display contents of TEXTFILE.CC on graphics screen
for i = 1 to 4 do
end // Display

UnZoom has been improved. If your window was created by zooming, UnZoom
(Control-U) returns you to the previous window. You can zoom, then unzoom
through a number of windows. If there is no previous window, then UnZoom
quadruples the size of the current window by expanding each of the axes by
2 from the center.

TRAJ and LEVELC have been modified. You can use a second optional
parameter after the optional step number (but the second parameter cannot
be used without the first). The second parameter, a real between -5 and 5,
specifies a "step size" for the trajectory and level curve algorithms. The
default is step size 0, and the step sizes are related exponentially to the
step size factor. If s0 is the default step size, and if ssf is the step
size factor, then the resulting stepsize factor is:

10 *s0

Thus the minimum step size is 1/10 of the default, and the maximum is 10
times the default. Here are two examples using the second factor:

LEVELC(x^3+x=y^2, x=0,y=0, 100, -1)

To restore the original window [-1.4,1.4] x [-1,1] , use the command
WINDOW without parameters.

The algorithms for TRAJ and LEVELC have been improved. TRAJ now uses a
predictor-corrector method to compute each step. It traces a circle
through the field (-y,x) pretty accurately. Try TRAJ(-y,x,x=1,y=0,222)
in the standard window.

LEVELC(f=g,x=a,y=b) now computes a new approximation (x,y) by following a
vector perpendicular to grad(f-g), then (this is the improvement) follows
the gradient vector back to the level curve. I stopped using the built-in
solver, and instead wrote a special Newton's method solver for this last
step. Given a point (a,b) and a function h(x,y), to move along the
gradient field grad(h) from (a,b) to a solution of h(x,y) = 0, we create a
function of one variable k(t) = h(a+r*t,b+s*t) where
(r,s) = grad(h)(a,b). Then using Newton's method to solve k(t)=0, we
begin with t = 0 and correct to t = -h(a,b)/(rý+sý). We just go one step,
construct new values of a = a+r*t, b=b+s*t, new values of r and s, and do
it again until the pixel representing (a,b) doesn't change from one step
to the next.

New command has been added to display a value on demand. Previously, when
you had a list or matrix stored in a variable, the only way to view the
object was to execute the variable name, which duplicated the value in the
variable in the variable ANS. This cost extra memory if the value was a
long list or large matrix and destroyed the current value of ANS. Now you
can enter the command:
where X is a variable name or any other legal CC expression, and the value
of X will be displayed without changing the value of any of CC's

The Config (Control-F9) routine has been slightly changed so that pressing
at each step leaves the value of the choice unchanged. In fact,
all the Y/N questions have been altered. The query now shows Y/n or y/N
or y/n. If one of the choices is capitalized, then that it the default
choice and can by selected by pressing . The only place where
there is not a default choice is when the program ends (^Q). The user
must specify whether or not to save the work. Neither alternative is an
attractive default--no save default is too dangerous, and save default may
confuse beginning users.

It's been a busy day. Two cars washed and the oil changed, waste paper
recycled, and still time for more innovations. Jim Smith pointed out that
the new graphics font, Borland's SmallFont, doesn't transfer very well to
WordPerfect. Its strokes are only one pixel wide, and they can get lost
when the graph is Grabbed and reduced. To overcome this difficulty, I've
added two commands:


After executing THICKTEXT, all graphics text of size larger than the
default size (3 or more) will be printed with lines two-pixels wide.
Actually the text is printed three times, once, then move up one pixel and
print again, then move right one pixel and print again. This only applies
to large text, since it doesn't look very good on smaller text. To return
to ordinary graphics characters, enter the command THINTEXT.

Sometime back, I forgot to note when, I completely revised the help
facilty. There is a new help file twice as big as the one in CC3 and new
routines to run it.

I just made minor changes in the matrix editor. Now, if you cursor to a
position in the matrix where an element is defined and start typing a new
element, the old element disappears. Previously, whatever you typed was
added to the end of the old element. If you begin by pressing or
, you will preserve the old element and edit it. For some
time, you have been able to move either way on a row of a matrix you are
editing with the key.

Also, if a matrix is displayed after creating or DISPLAYing it, you can
return to the calculator screen by pressing or . However, if
you have called up the matrix with MEDIT, then you must terminate the
session with . That is because it is too easy, after entering a
formula into the matrix editor, to terminate the formula with .

The last three days were spent in an exhaustive rewrite of the algebraic
simplification algorithms. They are now much cleaner and easier to
understand, and the bugs which gave rise to the rewrite have been
eliminated. One quirk has been introduced. Since CC does not factor, a
choice must be made for the order of application of the following two
rules: (a+b)c = ac + bc and a^n a^m = a^(n+m). (CC has an algorithm to
determine when two expressions are equal, so it can combine their
exponents.) The situation arises here. The second rule is now applied
first, so that (x+y)*(x+y)^(-1) gets converted to 1 instead of
x*(x+y)^(-1) + y(x+y)^(-1). However, this order of application can have
strange (but correct) results. If x is undefined and you try
PRODUCT(1+N*X,N=1,5), you will find that CC catches the factor (1+3X) and
retains it, while the other factors are expanded by the rule of

Changed the default number of steps in FIELD to 14 from 15, so that there
is no vector in the center of the field, which will often be (0,0) and may
be a singularity of the field. Including the singularity doesn't cause a
crash, but may cause all other vectors to be reduced to points.

Minor changes today. Decided that SAVEVAR should not save bignums, since
once saved they could not be read back in if they were very big. They can
be saved by F2-7, save all input, subroutines and variables to disk.

Changed REGR(m), where m is a matrix. Now REGR(m) returns a column vector
which is a least squares solution to the equation Ta = b, where T is the
matrix formed by deleting the last column of m and adding a new first
column of 1's, and b is the last column of m. Thus, if each row of m is
the data x1,x2,...,xn,y, the column vector a gives the best linear fit:
a0 + a1x1+...+anxn = y. Previously the constant term was at the end of
the linear approximation.

I've altered the input routines considerably, so that lines up to 2048
characters can be entered. You can enter (with spaces, not

x = {1,2,3,4;

The tab key moves the cursor to the next line and places it under the
first non-blank character, which is a help in creating entries like the
one above.

You can also enter much longer bignums now. You can also save (with
SAVEVAR) and reload (with LOADVAR) large bignums and large matrices. If
you look at the file they are saved in, you will see that the file
contains lines up to 240 characters in length, and if that isn't enough
for one bignum or row of a matrix, a continuation character (#220) is
placed at the end of the line and the entry continues on the next line.

Now I have to start rewriting the manual.

But not quite yet. Wordwrap has been added. Now you can enter very long
comments by starting them with // and just typing. Wordwrap also works in
formulas, so your long formulas won't break in the middle of variable
names or leave an opening parenthesis on the previous line.

Note: if you have an entry like this:

lkjlk ljljlk ljjlkj ljlkj ljlkj klX
dsfasf dsfsadf afdsa fsafsda

and you delete the X or push backspace with the cursor at the beginning of
the second line, the first word on the second line will not come up to the
first line until there is room for it.

I've modified ^B and ^T so they just erase the beginning or end of the
line you are on. However, ^Y still erases an entire multi-line entry.
You can recover the last ^Y with alt-Y--a primitive UnDo command. I'm
considering changing ^Y to just affect one screen line, not an entire

Wordwrap is user-controllable. The command WORDWRAPON turns on wordwrap
(the default), and WORDWRAPOFF turns it off. The initial state of
wordwrap can be altered in the configuration file.

The matrix editor has some unrecorded commands and two new ones. The
unrecorded ones are ^End and ^Home, which move you to the beginning or end
of matrix. ^RightArrow and ^LeftArrow move one screen at at a time, as
does PgUp and PgDn. Home and End move to beginning and end of individual

The new ones are ^R and ^C. ^R adds a row of zeros above the current row,
and ^C adds a column of zeros to the left of the current column.

A slight modification to the routines that add rows and columns.
Now, after pressing Control-R or Control-C, CC will ask if you want
to add or delete a row. Press I or D to indicate, or to
forget the whole thing.

SaveVar, FSaveVar, PrintVar have been changed to Save, FSave, Print.
Instead of saving a variable name, you can save any expression, including
a variable. This is useful, for now in subroutines you can add a line
Print('state 1 reached')
and it will print.

Fixed a few small bugs. Now the minimal number of lines per page is 50.

changed LoadVar to Load, to correspond to change to SaveVar. See 3/27/91.
Also fixed Save, so it would work.

  3 Responses to “Category : Science and Education
Archive   : CC4.ZIP
Filename : UPDATE.CC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: