# Category : Science and Education

Archive : CC4.ZIP

Filename : UPDATE.CC

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

415-338-2199

6/6/90

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.

6/19/90

changed exit key to ^Q, deleted confirmation, but added "do you want to

save your work"

fixed it so

6/22/90

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).

7/7/90

added Xor to list of operators. Works on booleans and integers. Also

have broken CC up into a large number of overlays.

8/7/90

have added lots of matrix operations. See below. Also now error in

execution of subroutine puts you in subroutine window with bad line

highlighted.

Three-d graphing commands redone completely. The basic commands are

simplified by the assumption of defaults in place of required

parameters. NOTE: WHEN OPTIONAL PARAMETERS ARE USED, THE SEMICOLON

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])

MatrixG(a[,z1,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

used.

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)

Curve3d(cos(t),sin(t),sin(3t),t=0,2pi)

MatrixG(a)

8/15/90

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:

{a,b,c;d,e,f}

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

MATRIX.

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.

9/1/90

Editing

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

marked text as well.

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

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.

9/10/90

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:

PrintGraph

To save the last graph for later reloading, use:

SaveGraph(filename)

The filename must be a string (path allowed) surrounded by single quotes

or a variable containing such a string. You could use either:

SaveGraph('pix.cc')

or

pixfile = 'pix.cc'

SaveGraph(pixfile)

To load a saved graph and display it, use:

LoadGraph(filename)

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:

PrintVar(variable-name)

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.

9/20/90

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.

9/28/90

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,

AXISOFF, KEEPLINE and VARYLINE

10/2/90

Crosshair color now determined by AxisColor

Fixed Div and Mod to work with negative integers.

10/11/90

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

change some commands.

COLOR becomes SETCOLOR

SETCOLOR(BLUE) makes the next line or graph blue

CURRENTCOLOR becomes COLOR

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

BKCOLOR becomes SETBKCOLOR

SETBKCOLOR(BLUE) makes the graphics background blue

CURRENTBKCOLOR becomes BKCOLOR

this is the one that was too long. BKCOLOR is a function that

returns the current graphics background color

10/12/90

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.

10/25/90

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.

10/30/90

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)) .

A NOTE ON LISTS AND MATRICES

(********* 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. **********)

11/7/90

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)

11/9/90

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.

11/13/90

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

minutes.

11/15/90

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

can)

11/23/90

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

x.

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:

SetSolveTol(x)

SetInTol(x)

SetInDepth(x)

SetMatrixTol(x)

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:

SolveTol

InTol

InDepth

MatrixTol

all return the current values of the corresponding parameter. Previously,

these commands set the parameters.

11/29/90

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

COND(A).

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

window(0,3,-1,1)

graphics

qu(cos(x),x)

sk(x,x)

solve(cos(b)=b,b=1)

Write@(.1,-.6,'Enter x-coordinate where curves intersect')

repeat

input@(.3,-.8,5,x)

ok = x > b-.05 and x < b+.05

if not ok

beep

end

until ok

Write@(.1,-.7,x)

Write@(.1,-.8,'You got it!!')

text

end

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.

12/11/90

IMPORTANT NOTE ON CONFIGURATION FILES

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

Control-F9.

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).

12/12/90

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.

12/20/90

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:

MEDIT(A)

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

matrix.

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)

1/2/91

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

manipulated.

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

returned.

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***

1/3/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.

1/4/91

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

EVALPOLY(p,x)

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))

f(x)

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

1/7/91

Finally, there is a ZOOM feature for graphics. To magnify part of a graph

(only the part drawn with GRAPH, DOTGRAPH, QUICKG, SKETCH, PARAMG POLARG,

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

magnified.

If you want to cancel the zoom command, press

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 ***

1/9/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.

1/15/91

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. ***

1/27/90

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.

Examples:

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 ***

1/29/91

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

1/31/90

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

displayed

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.

2/7/91

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

2/8/91

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

file:

TEXT

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

screen:

Procedure Display

// Display contents of TEXTFILE.CC on graphics screen

LoadVar(a,'TEXTFILE.CC');

Axisoff

Window(0,1,0,1)

graphics

for i = 1 to 4 do

Write@(0.1,1-i/5,a[i],3)

end

text

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.

2/9/91

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:

ssf/5

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:

TRAJ(-y,x,x,y,300,-2)

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

2/10/91

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.

2/16/91

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:

DISPLAY(X)

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

variables.

The Config (Control-F9) routine has been slightly changed so that pressing

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

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:

THICKTEXT

THINTEXT

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.

2/19/91

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

time, you have been able to move either way on a row of a matrix you are

editing with the

Also, if a matrix is displayed after creating or DISPLAYing it, you can

return to the calculator screen by pressing

you have called up the matrix with MEDIT, then you must terminate the

session with

formula into the matrix editor, to terminate the formula with

2/24/91

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

transitivity.

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.

2/29/91

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.

3/14/91

I've altered the input routines considerably, so that lines up to 2048

characters can be entered. You can enter (with spaces, not

carriage-returns):

x = {1,2,3,4;

5,6,7,8;

9,10,11,12}

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.

3/17/91

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

entry.

3/19/91

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

element.

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.

3/20/91

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

forget the whole thing.

3/27/91

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.

4/1/91

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

4/9/91

changed LoadVar to Load, to correspond to change to SaveVar. See 3/27/91.

Also fixed Save, so it would work.

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

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

But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/