home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / calculat / cc4_9206.zip / UPDATE.CC < prev    next >
Text File  |  1992-06-07  |  76KB  |  1,632 lines

  1. This file records the changes I have made to the published program CC-The
  2. Calculus Calculator.  The new version is called CC4 and should be treated as
  3. experimental.  Everything about CC is copyrighted by my this year, 1991--the
  4. source code, the object code, the help file, even this file.  For more
  5. information about CC, call or write me:
  6.  
  7.                 David Meredith
  8.                 Department of Mathematics
  9.                 San Francisco State University
  10.                 1600 Holloway Ave.
  11.                 San Francisco, CA 94132
  12.                 415-338-2199
  13.  
  14.  
  15. 6/6/90
  16.   completed altering saving of last graph to list of graphics commands.
  17.   Also fixed vertical write so correct area blanked before writing, and
  18.     correct area checked for off/screen.
  19.   Now last graph takes much less space for EGA,VGA screens.  speed is ok.
  20.  
  21. 6/19/90
  22.   changed exit key to ^Q, deleted confirmation, but added "do you want to
  23.   save your work"
  24.   fixed it so <ESC> cancels printing of long variable list.
  25.  
  26.  
  27. 6/22/90
  28.   changed display so only first 10 items in list are displayed.  Also
  29.   eliminated hide and show as no longer necessary.  When variables printed
  30.   with F2 only first ten items of list are printed followed by ...more... .
  31.   To print entire variable, use F8 or PRINTVAR (cf. 9/19/90).
  32.  
  33. 7/7/90
  34.   added Xor to list of operators.  Works on booleans and integers.  Also
  35.   have broken CC up into a large number of overlays.
  36.  
  37. 8/7/90
  38.   have added lots of matrix operations.  See below.  Also now error in
  39.   execution of subroutine puts you in subroutine window with bad line
  40.   highlighted.
  41.  
  42.   Three-d graphing commands redone completely.  The basic commands are
  43.   simplified by the assumption of defaults in place of required
  44.   parameters.  NOTE:  WHEN OPTIONAL PARAMETERS ARE USED, THE SEMICOLON
  45.   SEPERATOR MUST ALSO BE USED.  Otherwise there is not enough
  46.   information in the input for CC to parse it.
  47.  
  48.   The step parameter is the NUMBER OF STEPS, not the size of a step.
  49.  
  50.   Here are the three-d graphing commands with options:
  51.  
  52.            Paramg3d(f(s,t),g(s,t),h(s,t),s=a to b [step c]; t = e to f [step g]
  53.                               [; x1 to x2,y1 to y2,z1 to z2])
  54.               if the any of the optional x,y,z limits are present, all
  55.               msut be.  Without them, CC uses the min and max of f,g,h
  56.               respectively as the x,y,z limits.
  57.  
  58.            Graph3d(f(x,y),x=a to b [step c];y=e to f [step g][;z1 to z2]);
  59.  
  60.            Curve3d(f(t),g(t),h(t),t=a to b [step c]
  61.                                                [; x1 to x2,y1 to y2,z1 to z2])
  62.  
  63.            MatrixG(a[,z1,z2])
  64.                  This is the graph of a matrix.  You can optionally
  65.                  specify the vertical limits of the graphing space,
  66.                  otherwise the max and min of the matrix elements are
  67.                  used.
  68.  
  69.   One improvement over CC3 is that the two parameters can have a
  70.   different number of subdivisions.  Also curves are drawn directly, not
  71.   faked.  The default step is 15.  the total number of points that can be used
  72.   --(step1+1)(step2+1)--is 1600.
  73.  
  74.   Here are sample minimal 3d graphing commands.
  75.  
  76.       graph3d(x^2 - y^2, x=-1 to 1, y = -1 to 1)
  77.       Paramg3d(sin(s)cos(t), sin(s)sin(t),cos(s),s=0 to pi, t=0 to 2pi)
  78.       Curve3d(cos(t),sin(t),sin(3t),t=0,2pi)
  79.       MatrixG(a)
  80.  
  81. 8/15/90
  82.  
  83. Matrix Commands
  84.  
  85.   Matrix commands include arithmetic + - * / \ .* ./.   .  +, -, * are as
  86.   expected.  A/B = A*B^(-1).  A\B = A^(-1) * B .  A^n  is defined for positive
  87.   and negative integers n if A is square.  To get the inverse of a matrix,
  88.   you can enter A^(-1), but it is easier to enter 1/A .
  89.  
  90.   The operators  A .* B  and A ./ B
  91.   operate between same size matrices and multiply or divide elementwise.
  92.  
  93.   Scalar functions like SIN and EXP work
  94.   inside matrices unless specified to work on entire matrix.  New functions
  95.   include Rank, RREF, LU (invertible matrices only), QR, Balance (temporary
  96.   --will be hidden), Det,.
  97.  
  98.   To define a matrix, either enter the data surrounded by braces and rows
  99.   seperated by semicolons:
  100.  
  101.                    {a,b,c;d,e,f}
  102.  
  103.   or use the command  MATRIX(a(i,j),i=....j= ...).  See below for more on
  104.   MATRIX.
  105.  
  106.   Special matrices can be defined with
  107.  
  108.          Diag(x)  where x is a list or an n x 1 or 1 x n matrix
  109.          Eye(n)   n x n identity
  110.          Zero(n,m)  Ones(n,m)    n x m matrix of zeros or ones.
  111.  
  112.   To define a submatrix of a matrix A, use A[i:j, k:l].  The i,j element
  113.   of a matrix A is A[i,j].
  114.  
  115.   Matrices can be defined with the command MATRIX as follows.  If the
  116.   step is not used, the semicolon can be any seperator and the default
  117.   step will be 1.
  118.  
  119.            Matrix(f(x,y),x=a to b [step c]; y = e to f [step g])
  120.  
  121.   Here the step parameter is the SIZE of the step.
  122.  
  123.  
  124. 9/1/90
  125. Editing
  126.   to mark text, move the cursor to the beginning of the text to be marked,
  127.   then push F3.  Move cursor to end, then push either <ENTER> or <DEL>.
  128.   <ENTER> moves text to save buffer; <DEL> does the same but deletes the
  129.   marked text as well.
  130.  
  131.   To mark an entire entry, push Shift-F3, then <ENTER> or <DEL>.
  132.  
  133.   To insert the saved text, move the cursor to the point of insertion and
  134.   push F4.
  135.  
  136.   When new text is saved, the original text is moved to a new buffer.
  137.   There are ten buffers, which are accessed by F4, Alt-1, Alt-2,...,
  138.   Alt-9.  When new text goes into the F4 buffer, each existing buffer
  139.   moves up one, and the Alt-9 buffer is discarded.
  140.  
  141.   (**********)  This material is changed.  See 1/31/91
  142.   ***Pushing F3 twice inserts a blank line.
  143.   (**********)  This material is changed.  See 1/31/91
  144.   Lines can be erased without saving with Control-Y.
  145.   Shift-F4 erases all text buffers--if you need to recover the memory.
  146.  
  147. 9/10/90
  148.   Improved the solver routine to take care of functions singular at their
  149.   roots.  Done by replacing f(x) = 0 with f(x)/f'(x) = 0.  When this routine
  150.   entered, the phrase Super Solver appears on the screen.
  151.  
  152. 9/19/90  (revised 11/15/90)
  153. Data files
  154.  
  155.   To print the last graph, issue the command:
  156.  
  157.                            PrintGraph
  158.  
  159.   To save the last graph for later reloading, use:
  160.  
  161.                            SaveGraph(filename)
  162.  
  163.   The filename must be a string (path allowed) surrounded by single quotes
  164.   or a variable containing such a string.  You could use either:
  165.  
  166.                             SaveGraph('pix.cc')
  167.  
  168.   or
  169.  
  170.                             pixfile = 'pix.cc'
  171.                             SaveGraph(pixfile)
  172.  
  173.  
  174.   To load a saved graph and display it, use:
  175.  
  176.                            LoadGraph(filename)
  177.  
  178.   This will erase the current Last Graph.
  179.  
  180.   To save a list (or single datum or matrix) from a variable to a file, use:
  181.  
  182.                            SaveVar(variable-name, filename)
  183.  
  184.   To load a variable from a file (like the file saved above):
  185.  
  186.                            LoadVar(variable-name, filename)
  187.  
  188.   Note that the entries can be numerical formulas as well as numbers.  CC will
  189.   read and evaluate any legal CC numerical formula (no variables or user-
  190.   defined functions) found in the file.
  191.  
  192.   To print the values of a variable, use:
  193.  
  194.                            PrintVar(variable-name)
  195.  
  196.  
  197.   When CC saves a variable, it creates an ASCII file beginning with a line
  198.   containing one of the words LIST VARIABLE MATRIX.  If the file starts with
  199.   VARIABLE, it should have one more line with a value or formula.  If the file
  200.   starts with LIST, it should consist of a series of lines with one number or
  201.   formula per line.  If the file begins with MATRIX, there will be several
  202.   values or formulas on each line seperated by commas, with the same number on
  203.   each line.
  204.  
  205.   You can create your own files for loading into CC by following these rules.
  206.  
  207.   For a further update on this topic, see 3/27/91
  208.  
  209.  
  210. 9/20/90
  211.   Added command WAIT(n), which causes computer to pause n seconds.  Useful
  212.   in between GRAPHICS and TEXT to pause a picture.  To pause until a key is
  213.   pressed, use PAUSE.
  214.  
  215. 9/28/90
  216.   Changed command BKCOLOR to CURRENTBKCOLOR.  This returns current
  217.   background color.  Added two commands BKCOLOR(color number) which sets
  218.   the background color, and AXISCOLOR(color number), which sets the
  219.   color of the axes.  Presently the color of the crosshairs cannot be
  220.   changed.  These commands should be used in conjunction with AXISON,
  221.   AXISOFF, KEEPLINE and VARYLINE
  222.  
  223. 10/2/90
  224.   Crosshair color now determined by AxisColor
  225.  
  226.   Fixed Div and Mod to work with negative integers.
  227.  
  228. 10/11/90
  229.   Due to self-imposed limitation on the length of function names, I have had to
  230.   change some commands.
  231.  
  232.       COLOR becomes SETCOLOR
  233.                 SETCOLOR(BLUE) makes the next line or graph blue
  234.  
  235.       CURRENTCOLOR becomes COLOR
  236.                 COLOR is a function that returns the color of the next graph
  237.  
  238.       BKCOLOR becomes SETBKCOLOR
  239.                 SETBKCOLOR(BLUE) makes the graphics background blue
  240.  
  241.       CURRENTBKCOLOR becomes BKCOLOR
  242.                 this is the one that was too long.  BKCOLOR is a function that
  243.                 returns the current graphics background color
  244.  
  245.  
  246. 10/12/90
  247.    added bignums--infinite precision integers and fractions.  To enter a
  248.    bignum, precede it with &, eg &123456789.  Bignums can be added,
  249.    subtracted, multiplied and divided with each other and with integers.
  250.                                                                         
  251. 10/25/90
  252.     A note on differentiation which is not covered in any of my manuals.
  253.     Certain operators are invisible to differentiation.  For example,
  254.     d/dx(Hex(f(x)) = hex(df/dx).  Same for the operators Integer, Bin,
  255.     Transpose, Fix, Float.
  256.  
  257. 10/30/90
  258.     Bignums now work pretty well.  You can enter a bignum with or without a
  259.     decimal:  &35.8 = 179/5.  Bignums can be added, subtracted, multiplied and
  260.     divided.  You can raise them to integral (but not bignum) powers or take
  261.     their factorials.  Try &3^100 and &100! .  Bignums combined with integers
  262.     result in bignums,but bignums combined with non-integral reals or with
  263.     complex numbers result in floating point values.
  264.  
  265.     When transcendental functions are applied to bignums, like SIN, the bignum
  266.     is first changed to its floating point equivalent, then the function is
  267.     computed on the floating point value.
  268.  
  269.     Any bignum can be changed to its floating point equivalent with the functin
  270.     FLOAT(x).  If x is not a bignum, it is unchanged.  Any real or complex
  271.     decimal can be changed to a bignum equivalent with the function FIX(x).  Be
  272.     careful with this function.  If you want 1/3, enter &1/^&3 (or &1/3 or
  273.     1/&3 or 1/fix(3) ), not fix(1/3).  Fix(1/3) is a horrible fraction whose
  274.     denominator is 2^40.  CC first changes 1/3 into an approximating floating
  275.     binary number, then converts this to a fraction.
  276.  
  277.     Matrices with ALL bignum or integer entries
  278.     can be added, multiplied, subtracted and divided with bignum results.  Also
  279.     the functions LU, DET, RANK, and RREF can be applied to bignum matrices
  280.     with bignum results.  Because squareroots are involved, QR and BALANCE
  281.     always return a floating point result.
  282.  
  283.     Lists can also have bignum entries.  SUM, PRODUCT, MAX, MIN and AVERAGE
  284.     return bignum result when applied to a list of bignums and integers, but
  285.     STANDEV and REGR return floating point results, again because square roots
  286.     are involved.
  287.  
  288.     Here's a special problem:  to define the Hilbert matrix, you could say:
  289.  
  290.                 H(n) = Matrix(&1/(i+j-1), i = 1 to n, j = 1 to n)
  291.  
  292.     but this won't work.  CC changes this into &1*(i+j-1)^(-1), and the second
  293.     factor gets evaluated to a real which, when multiplied by &1, yields a
  294.     floating point real.  You must say:
  295.  
  296.                 H(n) = Matrix(1/fix(i+j-1), i=1 to n, j = 1 to n)
  297.  
  298.     Bignums are slow to compute with.  On my medium speed AT, it took over one
  299.     minute to compute det(H(10)) .
  300.  
  301. A NOTE ON LISTS AND MATRICES
  302.  
  303.     (********* this paragraph is now superceded.  see 1/3/91.  The comments are
  304.     still correct.
  305.     List operations work on matrices, going across the rows one by one.  You can
  306.     say SUM(A) or MAX(A) or even STANDEV(A) when A is a matrix.  You can do
  307.     regression against two matrices (of the same size) or apply LISTG to a pair
  308.     of matrices.  **********)
  309.  
  310. 11/7/90
  311.     added a function SOLVEPOLY with eye to developing eigenvalue
  312.     routines.  The syntax is SOLVEPOLY(x) where x is a list of
  313.     coefficients for a polynomial with constant coefficient listed
  314.     first.  The function returns a list of roots.  It fails on
  315.     polynomials with coefficients of very different sizes or very small
  316.     coefficients (work in progress) but works on reasonable polynomials.
  317.     User beware.  Example:
  318.  
  319.                         x = (1,-3,3,1)
  320.                         SOLVEPOLY(x)   // returns (1,1,1)
  321.  
  322.  
  323. 11/9/90
  324.     Still finishing up SOLVEPOLY.  I think it will have to fail on the
  325.     following example, which seems very hard:
  326.  
  327.                 x^5+1000x^4+x^3+x^2+x+1 = 0
  328.  
  329.     I can solve this by hand--it has one large root near -1000 which can
  330.     be gotten at with a binary search, and four small complex roots.
  331.     These are best found by finding their inverses as roots of
  332.  
  333.                 x^5+x^4+x^3+x^2+1000x+1 = 0
  334.  
  335.     I've also removed one annoyance.  Now, if you enter x(y+1) meaning
  336.     x*(y+1), CC will recognize that x is a variable, not a function and
  337.     instead of returning an error message will perform the
  338.     multiplication.  If this causes any ambiguities or other problems,
  339.     please let me know.
  340.  
  341. 11/13/90
  342.     Added two functions.  LOG10(x) is log base 10.  It only works on positive
  343.     reals.  TRACE(x) is the trace function for matrices.
  344.  
  345.     I've been experimenting with eigenvalues and SOLVEPOLY.  I coded
  346.     Fadeveev's (sp?) algorithm for the characteristic polynomial in the
  347.     subroutine window, then used SOLVEPOLY on the result to get the eigenvalues
  348.     of a matrix.  I created the hilbert matrix with bignums (so the
  349.     characteristic polynomial consisted of bignums too, but of course the
  350.     solutions returned by SOLVEPOLY were real), found the eigenvalues, and
  351.     computed the rank of matrix-eigenvalue*I .  Up to size 5, the rank was one
  352.     less than the size.  For size 6 and larger, the eigenvalues were not so
  353.     accurate.  The computation for size 6, using bignums, required about 15
  354.     minutes.
  355.  
  356. 11/15/90
  357.     The commands LOADM SAVEM PRINTM have been eliminated.  CC is smart enough
  358.     to use LOADVAR SAVEVAR PRINTVAR and know when a matrix is involved.  See
  359.     revised comment following 9/19/90.
  360.  
  361.     Note that bignums cannot be saved and read back yet.  (11/23/90 now they
  362.     can)
  363.  
  364. 11/23/90
  365.     Matrix algorithms are coming along.  I've added CHARPOLY(x) which takes a
  366.     matrix as an argument and returns a list representing a polynomial
  367.     (constant term first).  If x is Hermitian, CHARPOLY is forced to return
  368.     real coefficients.
  369.  
  370.     I've also added EIGENVAL(x), which takes a matrix x as an argument and
  371.     returns a list of eigenvalues, sorted in order of decreasing magnitude.  If
  372.     x is Hermitian, the eigenvalues are forced to be real.
  373.  
  374.     We also have EIG(x), which takes a matrix x as an argument and returns a
  375.     list of two matrices.  If you enter
  376.  
  377.                 e = EIG(x)
  378.  
  379.     then e[1] is a diagonal matrix with the eigenvalues on the diagonal, and
  380.     e[2] has the corresponding eigenvectors in its columns.  If x has repeated
  381.     eigenvalues, then the eigenvectors for repeated eigenvalues are selected to
  382.     be orthogonal.  If the matrix is deficient (some eigenvalue has an
  383.     insufficient number of eigenvectors) then the matrix of eigenvectors has
  384.     columns of zeros replacing the missing eigenvectors.  So long as x is not
  385.     dificient, x = ev[2]*ev[1]/ev[2] .  That is, the command EIG diagonalizes
  386.     x.
  387.  
  388.     Bignums can be saved with SAVEVAR and loaded with LOADVAR.
  389.  
  390.     I added some display features to EIG, SOLVEPOLY, CHARPOLY, EIGENVAL, SOLVE,
  391.     IMPLICIT and IN so that the user would have something to watch while these
  392.     relatively slow commands work.
  393.  
  394.     Finally, for today, I changed the commands that set some of CC's
  395.     parameters.  Now we have commands to set the parameters:
  396.  
  397.                 SetSolveTol(x)
  398.                 SetInTol(x)
  399.                 SetInDepth(x)
  400.                 SetMatrixTol(x)
  401.  
  402.     Setting x = 0 in these commands (or using any other illegal value) causes
  403.     the corresponding parameter to be reset to its default value.  No longer
  404.     need you look up the default values in the manual.
  405.  
  406.     The commands:
  407.  
  408.                  SolveTol
  409.                  InTol
  410.                  InDepth
  411.                  MatrixTol
  412.  
  413.     all return the current values of the corresponding parameter.  Previously,
  414.     these commands set the parameters.
  415.  
  416. 11/29/90
  417.     Just finished singular values.  If A is an n x m matrix of rank r, the
  418.     command S = SVD(A) returns a list of three matrices:
  419.                         S[1] is n x r with orthonormal rows
  420.                         S[2] is r x r diagonal with the singular values on
  421.                                the diagonal.  The singular values are always
  422.                                positive real numbers.
  423.                         S[3]  is m x r with orthogonal rows
  424.  
  425.        Moreover, A = S[1]*S[2]*S[3]"
  426.  
  427.     The command P = PINV(A) returns the pseudo-inverse of A, which is
  428.                         P = S[3]/S[2]*S[1]"
  429.  
  430.     Remember, B" is the conjugate transpose (Hermitian) of B.
  431.  
  432.     The ratio of the largest and smallest singular values  is called the
  433.     condition number of A, and can be computed directly with the command
  434.     COND(A).
  435.  
  436.  
  437.     As suggested by Professor Alex Calders of Duffel, Belgium, I've added two
  438.     new input commands.  Previously, when you executed INPUT or INPUTS on a
  439.     graphics screen, you got a large box which obscured much of the screen.
  440.     The new commands are INPUT@(x,y,n,a) and INPUTS@(x,y,n,a), where (x,y) is
  441.     the coordinate of the lower-left corner of the region where you want the
  442.     user to type the input, n is the number of characters room is made for, and
  443.     a is the variable which will receive the input.  INPUT@ gets numerical
  444.     input; INPUTS@ gets string input.  INPUT@ only works in subroutines when
  445.     GRAPHICS is active.
  446.  
  447.     Note that this new input command does not include provision for a message
  448.     to the user.  This command should be used in conjunction with WRITE@.  Use
  449.     WRITE@ to put instructions on the screen, then create the input box at a
  450.     convenient point on the screen where the user can type a response.
  451.  
  452.     If you try to place the input box too high on the screen,it will be
  453.     automatically lowered, and if you try to place it to far to the right for
  454.     the number of characters you wish to accomodate, it will be automatically
  455.     shifted to the left.
  456.  
  457.     Note that the graphics cursor is alive while waiting for a response to
  458.     INPUT@--the graphics cursor is not active while waiting for a response to
  459.     INPUT or while a message created by WRITE is on the screen.
  460.  
  461.     Here's a simple example:
  462.  
  463.                  procedure test
  464.                    window(0,3,-1,1)
  465.                    graphics
  466.                    qu(cos(x),x)
  467.                    sk(x,x)
  468.                    solve(cos(b)=b,b=1)
  469.                    Write@(.1,-.6,'Enter x-coordinate where curves intersect')
  470.                    repeat
  471.                        input@(.3,-.8,5,x)
  472.                        ok = x > b-.05 and x < b+.05
  473.                        if not ok
  474.                            beep
  475.                          end
  476.                      until ok
  477.                    Write@(.1,-.7,x)
  478.                    Write@(.1,-.8,'You got it!!')
  479.                    text
  480.                    end
  481.  
  482.  
  483.     The procedure graphs two curves on the screen and asks the user to input
  484.     the x-coordinate of their intersection.  The request repeats until the user
  485.     inputs an answer within 0.05 of the correct one.
  486.  
  487. 12/11/90
  488.  
  489.     IMPORTANT NOTE ON CONFIGURATION FILES
  490.  
  491.     Altered the configuration (Control-F9) routine to allow you to add page
  492.     length (in lines), as requested by European correspondent.  Also recently
  493.     fixed some bugs in config routines, so you MUST remake your config files if
  494.     you are using one.  Do this by erasing the configuration file CC.CFG while
  495.     outside of CC, then creating a new one from within CC by pressing
  496.     Control-F9.
  497.  
  498.     Note:  you set the total number of lines on your page; CC will allow for a
  499.     top and bottom margin.
  500.  
  501.     Also added a form-feed or skip-to-top-of-page command to the print (F2)
  502.     menu.  This will be useful for laser-jet users, but beware:  CC not only
  503.     skips to top of page but starts the next page, positioning the print head
  504.     to write the first character on the next page.
  505.  
  506.     Changed the effect of F8.  Now you can no longer load a graph through this
  507.     key, only a file of commands, so you will not be prompted to choose G for
  508.     graph or C for command file.  After pushing F8, you will be asked directly
  509.     for the name of the command file to load.  Graphs must be loaded with the
  510.     command LOADGRAPH(filename).
  511.  
  512. 12/12/90
  513.     Changed the directory command from shift-F1 to shift-F8, since F8 is my
  514.     file input key.  After viewing the directory, you have the opportunity to
  515.     make that directory your primary directory.  Also added Control-F8, which
  516.     is a simple change directory command.
  517.  
  518.     Added commands ROWVECTOR(X) and COLVECTOR(X), which take a list X and turn
  519.     it into a 1-row or 1-column matrix.  If X is not a list, the result is a
  520.     1x1 matrix whose sole entry is X.
  521.  
  522.     Fixed 3d graphs so that (a) axis labels print horizontally, not paralell to
  523.     the axes, and (b) if the axis points in the negative direction, a negative
  524.     sign is added to the axis name.
  525.  
  526. 12/20/90
  527.     Merry Christmas.  The matrix editor is completed.  Now, when you compute a
  528.     matrix, it will be shown in spreadsheet format.  You can cursor around it
  529.     with the arrow keys, the control-left and right keys, pgup and pgdn,
  530.     control-home and control-end.  The highlighted element is displayed at the
  531.     bottom of the screen, so even if it isn't completely displayed in the
  532.     matrix you can see it by highlighting it.
  533.  
  534.     If you produce a formula with more than one matrix, each will be shown in
  535.     turn.  For example, if you compute A/B, with B a matrix with symbolic
  536.     entries, both A and B will be displayed, and the result
  537.     Matrix(.,.)/Matrix(.,.) shown in the Output Window.
  538.  
  539.     You can also edit matrices with the spreadsheet.  To create or change a
  540.     matrix A, execute the command:
  541.  
  542.                                 MEDIT(A)
  543.  
  544.     If A is not a matrix, its contents will be lost.  You can move around A
  545.     with the arrow keys, etc, as above, adding or changing elements in the
  546.     matrix.
  547.  
  548.     This command can also be used to view a matrix.
  549.  
  550.     If a matrix is displayed as a result, without possibility of editing, the
  551.     highlighted element is shown in boldface or a different color.  In this
  552.     case you cannot cursor beyond the boundaries of the matrix.  If the matrix
  553.     is displayed as a result of the MEDIT command, the highlighted element is
  554.     reversed and can be changed.  In this case you can cursor beyond the
  555.     current boundaries of the matrix and make the matrix larger by adding
  556.     elements.  You do not need to fill in all the elements--blank elements will
  557.     be filled with zeros.
  558.  
  559.     Now there are four ways to create a matrix:
  560.         Surround its elements with braces:  {1,2,3;4,5,6}
  561.         Use a formula:  Matrix(1/(i+j-1,i=1,5,j=1,5)
  562.         Read it from a disk file:  LoadVar(A,'filename')
  563.         Create it with MEDIT:   MEdit(A)
  564.  
  565. 1/2/91
  566.     Happy New Year.  Just added some string operators.  Strings are entered by
  567.     surrounding them with apostrophes:  x = 'abcde'  .   Now they are displayed
  568.     with apostrophes to distinguish them in the output from undefined variable
  569.     names.  Strings can be used in WRITE and INPUT statements, they can be
  570.     compared for position in alphabetical order, and now they can be
  571.     manipulated.
  572.  
  573.     To extract the third character from a string, use x[3].  The result is a
  574.     string of length 1, unless x has fewer than 3 characters.  In that case the
  575.     result is the empty string '', or the string of length 0.  To extract the
  576.     substring consisting of characters 4..7, use x[4:7] or x[4,7].  If x has
  577.     fewer than 7 characters, then all characters of x, beginning with the 4th,
  578.     will be returned. If x has fewer than 4 characters, the empty string is
  579.     returned.
  580.  
  581.     Strings can be concatenated with | just like lists.  'abc' | 'de' returns
  582.     'abcde' .
  583.  
  584.     To determine if one string x is a substring of another string y, use the
  585.     function POS(x,y).  (POS means position.)  POS returns 0 if x is not a
  586.     substring of y, otherwise it returns the position of y corresponding to the
  587.     starting point of the substring x.  POS('abc', '12abcde') returns 3.
  588.  
  589.     The length of a string can be determined with the function LENGTH(x).
  590.  
  591.     The function UPCASE(x) returns a string y which is the same as x except
  592.     that all lower case letters a..z are replaced with upper case letters A..Z.
  593.  
  594.     If x is a string, then ASC(x) returns a list of integers that are the
  595.     ASCII codes of the characters of x.  If x is a string of length 1, then
  596.     ASC(x) is an integer, not a list of length 1.
  597.  
  598.     Conversely, if x is an integer or a list of integers in the range 32..255,
  599.     then CHR(x) is a string whose character codes are in x.  If x has entries
  600.     outside the required range, they are ignored.  NOTE:  strings with
  601.     characters in the range 129..255 will not print on the graphics screen.
  602.     Turbo Pascal does not support them in graphics mode.  ***now they do
  603.     see 1/27/91***
  604.  
  605. 1/3/91
  606.     Changed the statistical functions for matrices.  Now SUM MAX MIN AVERAGE
  607.     STANDEV, applied to a matrix, return a row vector containing the
  608.     appropriate value for each column of the matrix.  If matrix has only one
  609.     column, a scalar rather than a 1 x 1 matrix is returned.
  610.  
  611.     REGR(m), for a matrix m, works as follows.  Let p be the same as m, but
  612.     replace the last column by 1's, and let b be the last column of m.  Then
  613.     REGR(m) = pinv(p)*b.  Thus REGR is a column vector whose length = the # of
  614.     columns of m.  If m is r x 2, then if we think of the rows of m as points,
  615.     the elems of regr(m) = (c,d)" and y = cx+d is the regression line through
  616.     the points.  More generally, REGR(m) = (r1,...,rn) where the hyperplane
  617.     most nearly approximating the rows of m is
  618.  
  619.           xn = r1 x1 + r2 x2 + ... + rn-1 x-1 + rn
  620.  
  621.  
  622.     Added a sorting routine for matrices.  The function SORT(m,i) sorts the
  623.     rows of the matrix m on the data in column i and returns a sorted matrix.
  624.     m is unchanged, unless you use the command  m = SORT(m,i) .
  625.  
  626.     To sort on two columns, first sort on the secondary key, then on the
  627.     primary key.
  628.  
  629. 1/4/91
  630.     The command SOLVEPOLY (11/7/90 and following) now has a complement:  if p
  631.     is a list representing a polynomial, and x is a value, then
  632.  
  633.                              EVALPOLY(p,x)
  634.  
  635.     returns the the value p(x).  EVALPOLY uses Horner's method, so it will be
  636.     faster on large polynomials than defining a function equal to p and
  637.     evaluating it:
  638.  
  639.                    f(t) = SUM(p[i]*x^(i-1), i = 1 to length(p))
  640.                    f(x)
  641.  
  642.      The difference can be seen if you take p = LIST(1,i=1,100) and x = 2.
  643.  
  644. 1/7/91
  645.      Finally, there is a ZOOM feature for graphics.  To magnify part of a graph
  646.      (only the part drawn with GRAPH, DOTGRAPH, QUICKG, SKETCH, PARAMG POLARG,
  647.      DIFFG and INTEG, not LINE, FILL, WRITE, etc.) move the crosshairs to one
  648.      corner of the region to be magnified.  Press control-Z (the crosshairs
  649.      change to Z) and use the cursor keys to move the Z to the opposite corner
  650.      of the region to be magnified.  Press <ENTER> and your graph will be
  651.      magnified.
  652.  
  653.      If you want to cancel the zoom command, press <ESC>.  To restart the
  654.      window at the current location of the Z, press Control-Z again.
  655.  
  656.      After zooming your window, the window parameters WINDOWLEFT etc. will be
  657.      changed to reflect the new window.
  658.  
  659.      If you zoom on a curve drawn with PARAMG or POLARG, much of the curve may
  660.      be outside the zoomed window, since you won't have changed the limits of
  661.      the parameters.
  662.  
  663.      Now you can use  WINDOW(0,0,0,0)  to restore the window limits to their
  664.      original values, which were  WINDOW(-1.4,1.4,-1,1) .  *** this is changed
  665.      see 2/10/91 ***
  666.  
  667. 1/9/91
  668.     To complement CHR and ASC, I've added VAL and STR.  If s is a
  669.     string, then VAL(s) returns the numerical value of s.  s may be any
  670.     legal CC formula.  Conversely, if x is a value or CC formula, then
  671.     STR(x) returns a string representing the value of x.  Examples:
  672.  
  673.                     VAL('12') = 12
  674.                     VAL('Cos(PI)') = -1
  675.                     STR(3) = '3'
  676.                     STR(Cos(PI)) = '-1'
  677.  
  678.     Complex values and bignums can be used with VAL and STR.
  679.  
  680. 1/15/91
  681.     Added a new command:  FIELD(f(x,y),g(x,y),x,y)  draws vector field (f,g) in
  682.     current window.  Example:  FIELD(-y,x,x,y)
  683.  
  684.     The resulting vectors are not strictly proportional to their true lengths.
  685.     Although longer vectors appear longer, at least if they are parallel, the
  686.     proportion between longest and shortest vector has been reduced so that
  687.     individual vectors aren't reduced to single points.  However, if one vector
  688.     is very long, the others may virtually disappear.  This will happen, in
  689.     particular, if there is a singularity at the origin of the vector field.
  690.     Then, if you draw one vector very close to the origin, it will dwarf the
  691.     others.  To avoid this, see the next comment.
  692.  
  693.     Normally 15 x 15 vectors are drawn.  You can change this value by adding a
  694.     different number of vectors in each direction after the direction
  695.     parameter:  FIELD(-y,x,x,10,y,10)  .  If your window is symmetric about the
  696.     origin, you can avoid placing a vector near the origin by choosing an even
  697.     number of vectors in each direction.
  698.  
  699.     Also, to complement Zoom, after zooming you can press Control-U to
  700.     UnZoom--go back to prior window.  *** See 2/8/91 for information on
  701.     expanded UnZoom. ***
  702.  
  703. 1/27/90
  704.     We are at war.
  705.  
  706.     I've started compiling with Turbo Pascal 6.0.  This gives me new stroked
  707.     fonts with all the characters with codes 32-255.  I've changed from the
  708.     triplex font to the small font for all writing, including the text which
  709.     was previously written in the default (bitmapped) font.  Internally I'm
  710.     using sizes 4-10, but externally, you should use size codes 1..7 for
  711.     Write@, VWrite@, Write@c and VWrite@c.  The default size is 2, matching the
  712.     text used by CC to label the ends of the axes, the coordinates of the
  713.     crosshairs, and the message at the lower left of the graphics screen.
  714.  
  715.     I've also added two commands to complement vector fields:
  716.  
  717.                TRAJ(f(x,y),g(x,y), x = a, y = b)
  718.  
  719.     draws a trajectory through the vector field (f,g) beginning at (a,b).
  720.     Normally 50 segments are used to draw the trajectory.  You can change this
  721.     number by adding a value after b.
  722.  
  723.                LEVELC(f(x,y)=g(x,y), x = a, y = b)
  724.  
  725.     draws the graph of f(x,y) = g(x,y) both ways from the solution point
  726.     closest to (a,b) .  Normally 50 segments are used to draw each half of the
  727.     solution curve; you can change this value by adding a different number
  728.     after b.
  729.  
  730.     Examples:
  731.                TRAJ(-y,x,x=.5, y=.5, 100)
  732.                LEVELC(x^2+y^2 = 1, x=.7, y=.7, 30)
  733.  
  734.     *** see 2/9/91 for a step size parameter ***
  735.  
  736. 1/29/91
  737.     I seem to have neglected to list a couple of matrix commands.
  738.  
  739.         TRANS(a)      transpose of a
  740.         CONJ(a)       conjugate of a
  741.         a"            conjugate transpose or Hermitian of a
  742.         rows(a)       number of rows of a
  743.         cols(a)       number of columns of a
  744.         rank(a)       rank of a
  745.                         it may be necessary to jigger matrixtol a bit to get
  746.                         this value to come out right.
  747.         det(a)        determinant of a
  748.  
  749. 1/31/90
  750.     A minor fix:  previously the INPUT(a,b) command required a specific string
  751.     in apostrophes at a and a variable name at b.  The variable name is still
  752.     required, but the first entry can be any expression at all:
  753.  
  754.               'input third value'          a string
  755.               x                            a variable
  756.                                              (where previously we executed
  757.                                              x = 'input third value' )
  758.               Cos(4.5)                     an expression--the value is
  759.                                              displayed
  760.               Cos(4.5t)                    an expression with undefined terms
  761.  
  762.     It is particularly useful to be able to store the input prompt in a
  763.     variable and use the variable as the prompt in the input statement.
  764.  
  765.  
  766.     Changed the InsertLine key from F3 F3 to Control-Enter.  This is easier and
  767.     more natural, and you don't have to count the number of times you push F3
  768.     to get an even number.  This required changing the mnemonic info at the top
  769.     of the screen.
  770.  
  771.  
  772.     Added protected lines.  If you save a file with Alt-F7, then reload it with
  773.     F8, you won't be able to alter any of the non-blank lines.  You can,
  774.     however, add lines where there are blank lines and open up new lines with
  775.     Control-Enter.  If you save the file with F7 after adding more to it, the
  776.     added material will not be protected, but the original protected lines stay
  777.     protected.  To protect the entire file, save with Alt-F7.
  778.  
  779.     To unprotect a file for editing protected lines, load it with Alt-F8.
  780.  
  781.     Protected lines are useful for writing lessons, etc.  You can prepare a
  782.     lesson that the student can't write over, leaving blank space for the
  783.     student to write in.
  784.  
  785. 2/7/91
  786.     Added five operations to the editor:
  787.  
  788.           Control-RightArrow and Control-LeftArrow now move by words, stopping
  789.           at spaces and the characters ( = + - * / \ [ { ^ < >
  790.  
  791.           Control-Backspace erases an entire word to the left, stopping at the
  792.           same set of characters.
  793.  
  794.           Control-PgUp and Control-PgDn move the cursor up and down one entry
  795.           at a time.
  796.  
  797.      I tried to add Control-Delete to erase an entire word to the right, but
  798.      Turbo won't recognize this key when compiled under TPC, although it does
  799.      recognize it in the IDE.  I've written to Borland.
  800.  
  801.      Sometime earlier, I added but forgot to note:
  802.  
  803.            Control-B   -- delete left of cursor to beginning of line
  804.            Control-T   -- delete right of cursor to end of line
  805.            Controy-Y   -- delete entire line
  806.  
  807. 2/8/91
  808.     THIS MATERIAL IS RETAINED FOR HISTORICAL PURPOSES.  SEE 8/14/91 TO USE
  809.     READTEXT TO READ TEXT FILES INTO CC.  THE METHOD SHOWN HERE IS SUPERCEDED.
  810.     Fixed the data file loading routines LOADVAR.  Added the capability of
  811.     reading text files into lists of strings.  To create a textfile for input,
  812.     begin it with the line TEXT, then put any lines you want.  Here's a sample
  813.     file:
  814.  
  815.         TEXT
  816.         Put any information that you
  817.         want into these lines.
  818.  
  819.         Blank lines can be included.
  820.  
  821.     Suppose that these lines were stored in a file called TEXTFILE.CC.  The
  822.     following subroutine would read the file and display it on the graphics
  823.     screen:
  824.  
  825.         Procedure Display
  826.           // Display contents of TEXTFILE.CC on graphics screen
  827.           LoadVar(a,'TEXTFILE.CC');
  828.           Axisoff
  829.           Window(0,1,0,1)
  830.           graphics
  831.           for i = 1 to 4 do
  832.               Write@(0.1,1-i/5,a[i],3)
  833.             end
  834.           text
  835.         end  // Display
  836.  
  837.     UnZoom has been improved.  If your window was created by zooming, UnZoom
  838.     (Control-U) returns you to the previous window.  You can zoom, then unzoom
  839.     through a number of windows.  If there is no previous window, then UnZoom
  840.     quadruples the size of the current window by expanding each of the axes by
  841.     2 from the center.
  842.  
  843. 2/9/91
  844.     TRAJ and LEVELC have been modified.  You can use a second optional
  845.     parameter after the optional step number (but the second parameter cannot
  846.     be used without the first).  The second parameter, a real between -5 and 5,
  847.     specifies a "step size" for the trajectory and level curve algorithms.  The
  848.     default is step size 0, and the step sizes are related exponentially to the
  849.     step size factor.  If  s0 is the default step size, and if ssf is the step
  850.     size factor, then the resulting stepsize factor is:
  851.  
  852.                                      ssf/5
  853.                                    10     *s0
  854.  
  855.      Thus the minimum step size is 1/10 of the default, and the maximum is 10
  856.      times the default.  Here are two examples using the second factor:
  857.  
  858.                         TRAJ(-y,x,x,y,300,-2)
  859.                         LEVELC(x^3+x=y^2, x=0,y=0, 100, -1)
  860.  
  861. 2/10/91
  862.      To restore the original window [-1.4,1.4] x [-1,1] , use the command
  863.      WINDOW without parameters.
  864.  
  865.      The algorithms for TRAJ and LEVELC have been improved.  TRAJ now uses a
  866.      predictor-corrector method to compute each step.  It traces a circle
  867.      through the field (-y,x) pretty accurately.  Try TRAJ(-y,x,x=1,y=0,222)
  868.      in the standard window.
  869.  
  870.      LEVELC(f=g,x=a,y=b) now computes a new approximation (x,y) by following a
  871.      vector perpendicular to grad(f-g), then (this is the improvement) follows
  872.      the gradient vector back to the level curve.  I stopped using the built-in
  873.      solver, and instead wrote a special Newton's method solver for this last
  874.      step.  Given a point (a,b) and a function h(x,y), to move along the
  875.      gradient field grad(h) from (a,b) to a solution of h(x,y) = 0, we create a
  876.      function of one variable  k(t) = h(a+r*t,b+s*t) where
  877.      (r,s) = grad(h)(a,b).  Then using Newton's method to solve k(t)=0, we
  878.      begin with t = 0 and correct to t = -h(a,b)/(r²+s²).  We just go one step,
  879.      construct new values of a = a+r*t, b=b+s*t, new values of r and s, and do
  880.      it again until the pixel representing (a,b) doesn't change from one step
  881.      to the next.
  882.  
  883. 2/16/91
  884.      New command has been added to display a value on demand.  Previously, when
  885.      you had a list or matrix stored in a variable, the only way to view the
  886.      object was to execute the variable name, which duplicated the value in the
  887.      variable in the variable ANS.  This cost extra memory if the value was a
  888.      long list or large matrix and destroyed the current value of ANS.  Now you
  889.      can enter the command:
  890.                                 DISPLAY(X)
  891.      where X is a variable name or any other legal CC expression, and the value
  892.      of X will be displayed without changing the value of any of CC's
  893.      variables.
  894.  
  895.      The Config (Control-F9) routine has been slightly changed so that pressing
  896.      <ENTER> at each step leaves the value of the choice unchanged.  In fact,
  897.      all the Y/N questions have been altered.  The query now shows Y/n or y/N
  898.      or y/n.  If one of the choices is capitalized, then that it the default
  899.      choice and can by selected by pressing <ENTER>.  The only place where
  900.      there is not a default choice is when the program ends (^Q).  The user
  901.      must specify whether or not to save the work.  Neither alternative is an
  902.      attractive default--no save default is too dangerous, and save default may
  903.      confuse beginning users.
  904.  
  905.      It's been a busy day.  Two cars washed and the oil changed, waste paper
  906.      recycled, and still time for more innovations.  Jim Smith pointed out that
  907.      the new graphics font, Borland's SmallFont, doesn't transfer very well to
  908.      WordPerfect.  Its strokes are only one pixel wide, and they can get lost
  909.      when the graph is Grabbed and reduced.  To overcome this difficulty, I've
  910.      added two commands:
  911.  
  912.                            THICKTEXT
  913.                            THINTEXT
  914.  
  915.      After executing THICKTEXT, all graphics text of size larger than the
  916.      default size (3 or more) will be printed with lines two-pixels wide.
  917.      Actually the text is printed three times, once, then move up one pixel and
  918.      print again, then move right one pixel and print again.  This only applies
  919.      to large text, since it doesn't look very good on smaller text.  To return
  920.      to ordinary graphics characters, enter the command THINTEXT.
  921.  
  922. 2/19/91
  923.      Sometime back, I forgot to note when, I completely revised the help
  924.      facilty.  There is a new help file twice as big as the one in CC3 and new
  925.      routines to run it.
  926.  
  927.      I just made minor changes in the matrix editor.  Now, if you cursor to a
  928.      position in the matrix where an element is defined and start typing a new
  929.      element, the old element disappears.  Previously, whatever you typed was
  930.      added to the end of the old element.  If you begin by pressing <END> or
  931.      <RIGHTARROW>, you will preserve the old element and edit it.  For some
  932.      time, you have been able to move either way on a row of a matrix you are
  933.      editing with the <TAB> key.
  934.  
  935.      Also, if a matrix is displayed after creating or DISPLAYing it, you can
  936.      return to the calculator screen by pressing <ENTER> or <ESC>.  However, if
  937.      you have called up the matrix with MEDIT, then you must terminate the
  938.      session with <ESC>.  That is because it is too easy, after entering a
  939.      formula into the matrix editor, to terminate the formula with <ENTER>.
  940.  
  941. 2/24/91
  942.      The last three days were spent in an exhaustive rewrite of the algebraic
  943.      simplification algorithms.  They are now much cleaner and easier to
  944.      understand, and the bugs which gave rise to the rewrite have been
  945.      eliminated.  One quirk has been introduced.  Since CC does not factor, a
  946.      choice must be made for the order of application of the following two
  947.      rules:  (a+b)c = ac + bc  and  a^n a^m = a^(n+m).  (CC has an algorithm to
  948.      determine when two expressions are equal, so it can combine their
  949.      exponents.)  The situation arises here.  The second rule is now applied
  950.      first, so that  (x+y)*(x+y)^(-1) gets converted to 1 instead of
  951.      x*(x+y)^(-1) + y(x+y)^(-1).  However, this order of application can have
  952.      strange (but correct) results.  If x is undefined and you try
  953.      PRODUCT(1+N*X,N=1,5), you will find that CC catches the factor (1+3X) and
  954.      retains it, while the other factors are expanded by the rule of
  955.      transitivity.
  956.  
  957.      Changed the default number of steps in FIELD to 14 from 15, so that there
  958.      is no vector in the center of the field, which will often be (0,0) and may
  959.      be a singularity of the field.  Including the singularity doesn't cause a
  960.      crash, but may cause all other vectors to be reduced to points.
  961.  
  962. 2/29/91
  963.      Minor changes today.  Decided that SAVEVAR should not save bignums, since
  964.      once saved they could not be read back in if they were very big.  They can
  965.      be saved by F2-7, save all input, subroutines and variables to disk.
  966.  
  967.      Changed REGR(m), where m is a matrix.  Now REGR(m) returns a column vector
  968.      which is a least squares solution to the equation Ta = b, where  T  is the
  969.      matrix formed by deleting the last column of m and adding a new first
  970.      column of 1's, and b is the last column of m.  Thus, if each row of m is
  971.      the data  x1,x2,...,xn,y, the column vector a gives the best linear fit:
  972.      a0 + a1x1+...+anxn = y.  Previously the constant term was at the end of
  973.      the linear approximation.
  974.  
  975. 3/14/91
  976.      I've altered the input routines considerably, so that lines up to 2048
  977.      characters can be entered.  You can enter (with spaces, not
  978.      carriage-returns):
  979.  
  980.                    x = {1,2,3,4;
  981.                         5,6,7,8;
  982.                         9,10,11,12}
  983.  
  984.      The tab key moves the cursor to the next line and places it under the
  985.      first non-blank character, which is a help in creating entries like the
  986.      one above.
  987.  
  988.      You can also enter much longer bignums now.  You can also save (with
  989.      SAVEVAR) and reload (with LOADVAR) large bignums and large matrices.  If
  990.      you look at the file they are saved in, you will see that the file
  991.      contains lines up to 240 characters in length, and if that isn't enough
  992.      for one bignum or row of a matrix, a continuation character (#220) is
  993.      placed at the end of the line and the entry continues on the next line.
  994.  
  995.      Now I have to start rewriting the manual.
  996.  
  997. 3/17/91
  998.      But not quite yet.  Wordwrap has been added.  Now you can enter very long
  999.      comments by starting them with // and just typing.  Wordwrap also works in
  1000.      formulas, so your long formulas won't break in the middle of variable
  1001.      names or leave an opening parenthesis on the previous line.
  1002.  
  1003.      Note:  if you have an entry like this:
  1004.  
  1005.              lkjlk ljljlk ljjlkj ljlkj ljlkj klX
  1006.              dsfasf dsfsadf afdsa fsafsda
  1007.  
  1008.      and you delete the X or push backspace with the cursor at the beginning of
  1009.      the second line, the first word on the second line will not come up to the
  1010.      first line until there is room for it.
  1011.  
  1012.      I've modified ^B and ^T so they just erase the beginning or end of the
  1013.      line you are on.  However, ^Y still erases an entire multi-line entry.
  1014.      You can recover the last ^Y with alt-Y--a primitive UnDo command.  I'm
  1015.      considering changing ^Y to just affect one screen line, not an entire
  1016.      entry.
  1017.  
  1018. 3/19/91
  1019.      Wordwrap is user-controllable.  The command WORDWRAPON turns on wordwrap
  1020.      (the default), and WORDWRAPOFF turns it off.  The initial state of
  1021.      wordwrap can be altered in the configuration file.
  1022.  
  1023.      The matrix editor has some unrecorded commands and two new ones.  The
  1024.      unrecorded ones are ^End and ^Home, which move you to the beginning or end
  1025.      of matrix.  ^RightArrow and ^LeftArrow move one screen at at a time, as
  1026.      does PgUp and PgDn.  Home and End move to beginning and end of individual
  1027.      element.
  1028.  
  1029.      The new ones are ^R and ^C.  ^R adds a row of zeros above the current row,
  1030.      and ^C adds a column of zeros to the left of the current column.
  1031.  
  1032. 3/20/91
  1033.      A slight modification to the routines that add rows and columns.
  1034.      Now, after pressing Control-R or Control-C, CC will ask if you want
  1035.      to add or delete a row.  Press I or D to indicate, or <ESC> to
  1036.      forget the whole thing.
  1037.  
  1038. 3/27/91
  1039.      SaveVar, FSaveVar, PrintVar have been changed to Save, FSave, Print.
  1040.      Instead of saving a variable name, you can save any expression, including
  1041.      a variable.  This is useful, for now in subroutines you can add a line
  1042.                             Print('state 1 reached')
  1043.      and it will print.
  1044.  
  1045. 4/1/91
  1046.      Fixed a few small bugs.  Now the minimal number of lines per page
  1047.      is 50 and the maximum is 200.  50 is a necessary minimum to get a
  1048.      graph on a page.
  1049.  
  1050.  4/9/91
  1051.      changed LoadVar to Load, to correspond to change to SaveVar.  See 3/27/91.
  1052.      Also fixed Save, so it would work.
  1053.  
  1054. 4/24/91
  1055.      Today I modified the regression command for lists so that it would agree
  1056.      with the regression command for matrices as well as with common
  1057.      conventions.  REGR(x,y) still returns a list of three items, but now the
  1058.      first is the y-intercept of the regression, the second is the slope, and
  1059.      the third is the correlation coefficient.
  1060.  
  1061. 6/1/91
  1062.      I've been correcting bugs, mostly in the editor.  I also fixed it
  1063.      so that, if the configuration file CC.CFG contains unexpected
  1064.      values, or if information is missing, then the file will not be
  1065.      used.  To create a valid configuration file, press control-F9 while
  1066.      in CC.
  1067.  
  1068. 6/6/91
  1069.      Some fairly major changes today.  I changed the shape of the
  1070.      graphics cursor ("crosshairs") to a circle with little arms, so
  1071.      they still look like crosshairs.  I also added a command
  1072.      SETCROSS(x,y), which moves the graphics cursor to the screen
  1073.      point (x,y).  I also changed the command AXISCOLOR to SETAXISCOLOR,
  1074.      to make this consistent with the other set-color commands.  There
  1075.      is still no "axiscolor" function that returns the current axis
  1076.      color.  I don't see a need for one.
  1077.  
  1078.      The SETAXISCOLOR command now sets only the color of axes.  You can set
  1079.      the color of the graphics cursor with SETCRCOLOR(colorword).
  1080.      Remember, the color of messages is set by SETCOLOR, the same as the
  1081.      color of graphs.
  1082.  
  1083. 6/13/91
  1084.      A user from Australia, Rex ? (I can't read his signature),
  1085.      suggested adding an "expand" command to alter the method of
  1086.      expanding algebraic formulas.  Rather than make this a function, I
  1087.      decided to set a switch within CC.  If you enter the command
  1088.      EXPANDON, CC will expand binomials of the form (a+b)^n, where n is
  1089.      a positive integer.  If you execute EXPANDOFF, then (a+b)^n will
  1090.      not be expanded.  The default is EXPANDOFF, since expressions are
  1091.      usually simpler if powers are not expanded.
  1092.  
  1093. 6/18/91
  1094.      Maybe its just that programming is more fun than writing
  1095.      documentation.  I've fixed a couple of obscure bugs that caused CC
  1096.      to crash on user errors -- (a) if one subroutine called another
  1097.      with the wrong number of variables, and (b) if the user defined a
  1098.      function recursively, then tried to EVAL the result to get another
  1099.      function, then tried to used the function again.
  1100.  
  1101.      There are two new graphics commands that might be useful.  You can
  1102.      overlay 2d graphs with a rectangular grid by executing
  1103.  
  1104.                        GRID(dx,dy)
  1105.  
  1106.       The lines come at exact multiples of dx and dy.
  1107.  
  1108.       You can also superimpose polar coordinates on the screen with the
  1109.       command
  1110.  
  1111.                     POLARGRID(dr, dΘ)
  1112.  
  1113.       The grids stay in effect until you cancel them with the command:
  1114.  
  1115.                       NOGRID
  1116.  
  1117. 6/19/91
  1118.       Graphing in polar coordinates has become even easier.  If you just
  1119.       specify the function and the variable, CC will assume default
  1120.       limits of 0 to 2π and use 200 steps in graphing.  That is, the
  1121.       following two commands are equivalent:
  1122.  
  1123.                         PolarG(f(t),t)
  1124.                         PolarG(f(t),t = 0 to 2*PI step 200)
  1125.  
  1126.        The abbreviations WI for WINDOW and IMP for IMPLICIT are no longer
  1127.        valid.
  1128.  
  1129. 6/27/91
  1130.        Mr. Calders of Belgium suggested a switch that would force all
  1131.        integers to default to exact integers.  This is a good idea, so
  1132.        I've implemented it.  When you enter EXACTON, all integers will
  1133.        act as though you had preceded them with &; entering EXACTOFF
  1134.        returns to the default, in which integers are floating point
  1135.        values that happen to be integral.  Once in this state, all
  1136.        integer arithmetic, even division, is exact.  Entering 3/4
  1137.        results in a fraction 3/4, not a decimal 0.75.
  1138.  
  1139.        If you enter EXACTON before entering matrices with integer
  1140.        entries, all calculations involving inverses, row reduction,
  1141.        rank, LU decomposition, etc, will be exact.  Eigenvalues and
  1142.        eigenvectors are still floating point calculations.
  1143.  
  1144.        To make room for this, I had to remove a couple more
  1145.        abbreviations.  PA3, QU, DTG, ≤ (alt-L), ≥ (alt-M) are no longer
  1146.        valid.
  1147.  
  1148. 7/8/91
  1149.        Major changes have been made to the axes on two dimensional
  1150.        graphs.  Now, to turn the axes off, use the command:
  1151.  
  1152.                              NOAXIS
  1153.  
  1154.        To create the default axes, with labeled tic marks at their ends,
  1155.        enter:
  1156.  
  1157.                               AXIS
  1158.  
  1159.        To create axes with labeled tic marks every dx and with nx
  1160.        unlabeled subdivisions between each labeled tic mark on the
  1161.        x-axis, and with similar subdivisions on the y-axis, enter:
  1162.  
  1163.                        AXIS(dx, nx, dy ,ny)
  1164.  
  1165.        Axes remain in effect until they are changed, even if the window
  1166.        is changed.  If the tic marks would be too dense on the axes, the
  1167.        default axis markings will be used.
  1168.  
  1169. 7/9/91
  1170.        Started working on the last letter from Alex Calders today.  He had
  1171.        discovered a bug in Turbo Pascal's line drawing operations.  When
  1172.        you set a line style that has low order 0's, and you attempt to
  1173.        draw a line from one pixel to an adjoining pixel, the line may
  1174.        not appear at all.  Turbo's line styles may start with pixels
  1175.        off, at least in EGA/VGA mode.  (He reports different results in
  1176.        Hercules mode, but I can't check that from where I'm working
  1177.        now.)  Since CC draws such lines when graphing a curve of
  1178.        slope < 1, Alex had curves disappear on him when drawing with
  1179.        linestyles 1..3.
  1180.  
  1181.        To correct this, I made my own linestyle patterns that start and
  1182.        end with bits on, and which imitate Turbo's built-in styles.
  1183.        Then, since I was using "user-defined" styles anyway, I decided
  1184.        to let users put in their own styles.  So now
  1185.  
  1186.                             LINESTYLE(n)
  1187.  
  1188.        is defined for 0 <= n <= 65535.  LineStyle(n) is the same as
  1189.        before for 0 <= n <= 3, but if you use a larger integer, it will
  1190.        be treated as a 16-bit pattern for your own line style.
  1191.  
  1192. 8/1/91
  1193.        Changed Mark so that marks appear in current color.
  1194.  
  1195. 8/10/91
  1196.        If v is a vector (n x 1   or   1 x n  matrix), then v[i] returns
  1197.        i'th component.  v[i] is the same as v[1,i] or v[i,1], whichever
  1198.        would be correct.
  1199.  
  1200. 8/14/91
  1201.        The way ASCII files are read into CC is changed.  Instead of heading a
  1202.        file with "TEXT" (which no longer works), use the command:
  1203.                           LOADTEXT(var-name, file-name)
  1204.        Any ascii file can be loaded as a list of strings this way.  Once
  1205.        loaded, it can be modified with CC.  The most powerful modification is
  1206.        to change the data to a column matrix with the command COLVECTOR, then
  1207.        use MEdit to modify the strings that were read.
  1208.  
  1209. 8/23/91
  1210.        I've changed the way the LU decomposition is presented, to agree with
  1211.        MATLAB.  Now the command B = LU(A) results in a list of matrices B[1]
  1212.        and B[2] such that (a) B[1]*B[2] = A; (b)  B[2] is upper triangular;
  1213.        (c) B[2] is a lower triangular matrix with the rows permuted.  Before
  1214.        permuting, B[1] had 1's on the diagonal.  LU is defined only for square
  1215.        non-singular matrices.
  1216.  
  1217. 9/12/91
  1218.        Your configuration file CC.CFG is no longer valid.  I've been playing
  1219.        with the configuration, adding three items and also adding labels for
  1220.        each of the item that double the number of lines in the file.  Now you
  1221.        can specify the number of characters across a page and the number
  1222.        to leave as left and right margins.  To recreate your configuration
  1223.        file, start CC and press Control-F9.  Answer the questions as they
  1224.        are asked, and a configuration file will be created.
  1225.  
  1226.        I've also added yet another command:
  1227.  
  1228.                             NewPage
  1229.  
  1230.        This causes your printer to eject a page.  It duplicates the result
  1231.        of pressing F2, then 7, but it can be used in a subroutine too.
  1232.  
  1233. 9/20/91
  1234.        I fixed the graphics print so that it always prints the crosshairs and
  1235.        their coordinates on two-dimensional screens.
  1236.  
  1237.        I altered the matrix add and subtract routines so that a constant plus
  1238.        a matrix adds the constant to every element of the matrix.  This
  1239.        eliminates the need for using ONES sometimes.  You can say A+3
  1240.        instead of A + 3*ONES(ROWS(A),COLS(A)).
  1241.  
  1242.        I also fixed a bug in the differentiation of implicit so that the
  1243.        second derivative of implicit can be taken.
  1244.  
  1245. 9/28/91
  1246.       You can add messages and lines to your graphs without leaving the
  1247.       graphics screen.  To add a message, press Control-W, tell CC how
  1248.       big you want the characters to be (1..7) and type the message
  1249.       followed by <ENTER>.  Press Control-V to write a vertical message.
  1250.       This is much easier than using Write@ or Write@C.
  1251.  
  1252.       To put a line on your graph, move the crosshairs to the start of
  1253.       the line, then press Control-L.  Move the crosshairs to the other
  1254.       end of the line (you'll see the line on the screen) and press
  1255.       <ENTER>.  To draw a sequence of lines, press Control-L at the end
  1256.       of each segment, then <ESCAPE> to end line drawing.
  1257.  
  1258.       The ability to write messages directly on graphic screens eliminates
  1259.       the need for the commands WRITE@C and VWRITE@C, so these commands have
  1260.       been removed from CC.   If you wish to place a message at the location
  1261.       of the crosshairs, use WRITE@(CROSSX,CROSSY,....) or
  1262.       VWRITE@(CROSSX,CROSSY,....).
  1263.  
  1264. 9/30/91
  1265.       Following Jim Smith's suggestion, I've added a command to set the default
  1266.       graphics font size.  To set the font size to n, execute:
  1267.  
  1268.                         FontSize(n)
  1269.  
  1270.       To reset to the default (which is 2), you can execute:
  1271.  
  1272.                         FontSize(0)
  1273.  
  1274.       This affects both 2d and 3d graphs.
  1275.  
  1276. 10/2/91
  1277.       After promising myself that there would be no more changes to CC, just
  1278.       bug fixes, I seem to be making a lot of additions.  Here's two more.
  1279.       To put date stamps on your work, or to time events and procedures, you
  1280.       can use the functions:
  1281.  
  1282.                          Date
  1283.                          Time
  1284.  
  1285.        These parameterless functions return strings representing the current
  1286.        date and time as reported by DOS.  Time is reported in 24 hour format
  1287.        to the 100th of a second.
  1288.  
  1289. 10/3/91
  1290.        Something that should have been done a long time ago--you can concatenate
  1291.        strings with + as well as with |.  'abc' + 'def' = 'abcdef'
  1292.  
  1293. 10/8/91
  1294.        The command AXIS(DX,NX,DY,NY) has been altered slightly.  If DX=0
  1295.        then the default axis style is used on the x-axis, with tic mark
  1296.        and coordinate at the end.  If DX=-1, then no tic marks or
  1297.        coordinates are written.  Otherwise coordinates are written every
  1298.        DX with the divisions of length DX subdivided into NX subregions
  1299.        by tic marks.  Similarly for the y-axis.  The command AXIS without
  1300.        parameters is equivalent to AXIS(0,0,0,0)--default x and y-axes are
  1301.        used.
  1302.  
  1303. 10/24/91
  1304.        I've added a minor wrinkle to laser printing of graphs.  Now that I'm
  1305.        using my own laser printer, I'm also learnng what makes it easier to
  1306.        use.  When you select HP as your printer type, you will be given
  1307.        additional options.  You must select the size of your printed
  1308.        graphics:  2" wide (300 dots/inch), 4" wide (150 dots/inch) or 6"
  1309.        wide (100 dots/inch).  You can change the size by reselecting the
  1310.        printer.  Push F2 then 9 (change printer type).  Choose (H)P,
  1311.        then select the size you want.  You can't (yet) do this while
  1312.        viewing a graphic screen.  If you want to print a graphic using a
  1313.        certain size, first you must leave the graphic screen by pressing
  1314.        <ENTER>, choose the graph size for printing as explained above,
  1315.        then press <F9> to restore the graph.  Then print the graph by
  1316.        pressing <F2>.  Or you could select the printing size, then
  1317.        execute PRINTGRAPH from the text screen.
  1318.  
  1319.        I want to make note here of a bug I'm wrestling with.  If anyone
  1320.        has a suggestion about it, I would appreciate hearing it.  When
  1321.        using a Genoa VGA board, sometimes part of the screen is erased.
  1322.        For example, if you start CC and then push <ENTER>, the line
  1323.        above the Input and Output Windows, beginning at the middle of
  1324.        the screen, is erased.  It appears that the internal Pascal
  1325.        commands CLREOL and CLRSCR are not operating on the correct parts
  1326.        of the screen.  This only happens, so far as I know, with this
  1327.        one brand of video board.  Moreover, if I modify my Pascal code
  1328.        to execute a WRITE command on the variables WINDMIN or WINDMAX
  1329.        just before executing CLREOL, then the error disappears.
  1330.        Assigning a value to these variables or extracting a value from
  1331.        them doesn't do the job, but writing them causes CLREOL to work
  1332.        correctly.
  1333.  
  1334.        HELP.
  1335.  
  1336. 10/25/91
  1337.        I've put in a temporary fix for the Genoa problem, namely my own
  1338.        CLRSCR and CLREOL functions.  This inflates the code only
  1339.        slightly and causes no visible slowdown.  I still want to know
  1340.        why I had trouble with the Genoa board.
  1341.  
  1342. 10/26/91
  1343.        After several requests, the latest from Martin Flashman at
  1344.        Humbold State, I've added the ability to specify that a sublist
  1345.        or a submatrix uses the entire range in one index position by
  1346.        putting a colon in that place.  Thus, if A is a list of the form
  1347.        A = ((1,2,3),(4,5,6)), then A[:,2] is the second element from
  1348.        every sublist, or (3,5).  In a matrix A, A[:,3] is the third
  1349.        column; A[2,:] the second row; and A[2:3,:] the submatrix
  1350.        consisting of the entire second and third rows.
  1351.  
  1352.        I've also added the ability to replace a submatrix (but not a
  1353.        sublist) with a command like  A[2:3,2] = ... .  This will replace
  1354.        the specified submatrix with the right hand side, provided that
  1355.        the right hand side is the right size (a 2 x 1 matrix in this
  1356.        case).  You can use the colon notation here as well.  A[:,3] =
  1357.        ... will replace the third column of A.
  1358.  
  1359.        My reluctance to add the second feature stems from the use that
  1360.        many want to make of it.  Now you can manually row reduce a
  1361.        matrix easily, with commands like A[2,:] = A[2,:]-2*A[1,:] ;
  1362.        which replaces the second row of A with the second row less twice
  1363.        the first row,  I have received requests to make manual row
  1364.        reduction easier in CC.  Of course, CC will row reduce a matrix
  1365.        for you with the command RREF(A), and that is the way to do it if
  1366.        you need to row reduce a matrix.  My own philosophy is that
  1367.        students shouldn't be doing operations that a computer can do,
  1368.        and that they certainly should not be using a computer to do such
  1369.        operations.  I ask my linear algebra students to row reduce a few
  1370.        matrices by hand, which is easier than doing it with CC.  Very
  1371.        soon in the course, however, I try to emphasize questions about
  1372.        row reduction that require understanding the process and its
  1373.        meaning, but which do not require reducing matrices step by step.
  1374.        I encourage users of CC to do the same.  I wrote CC to give
  1375.        students a modern tool to extend their power; let's teach them to
  1376.        do mathematics the most efficient way possible.
  1377.  
  1378.        (Added 11/19/91.)  In the above paragraph, I don't mean to imply
  1379.        that Dr. Flashman misunderstands how to use CC.  He is one of the
  1380.        most progressive and innovative teachers that I know, and I very
  1381.        much appreciate his willingness to use CC with students even when
  1382.        it was less than adequately debugged.  He has pointed out to me
  1383.        that many mathematical operations with matrices, including those
  1384.        associated with linear programming, require row operations such
  1385.        as have just been added to CC.  In my own work during the last
  1386.        few weeks I have found myself making frequent use of these
  1387.        operations.  So I shouldn't have jumped so quickly at those who
  1388.        asked for them--they saw better than I did how useful row and
  1389.        column operations could be.
  1390.  
  1391. 10/29/91
  1392.        I don't usually report bug fixes here, but I just fixed one that
  1393.        has laid unnoticed in the code for over a year until it was found
  1394.        by my student Ruth Radetsky.  In some cases the eigenvectors for
  1395.        multiple eigenvalues were wrong, although the eigenvalues were
  1396.        correct.  I've corrected the algorithm.
  1397.  
  1398. 11/19/91
  1399.        Another bug squashed.  The eigenvector command was modifying the
  1400.        argument--an entirely undesirable side effect.  This will no
  1401.        longer happen.
  1402.  
  1403. 11/29/91
  1404.        A major league apology to all beta testers.  I've changed several
  1405.        commands to agree with CC3, so that the upgrade--when it
  1406.        comes--will require fewer changes in CC subroutines.
  1407.  
  1408.     old CC4 (as of yesterday)        new CC4            meaning
  1409.  
  1410.          SetColor(..)                Color(..)       choose graphing color
  1411.          SetBkColor(..)              BkColor(..)     choose graphing background
  1412.          SetCrColor(..)              CrColor(..)     choose crosshair color
  1413.          SetAxisColor(..)            AxisColor(..)   choose axis color
  1414.  
  1415.          Color                       GetColor        current graphing color
  1416.          BkColor                     GetBkColor      current graph backgrnd
  1417.  
  1418.          SetInDepth                  InDepth         max integration depth
  1419.          SetInTol                    InTol           integration tolerance
  1420.          SetSolveTol                 SolveTol        solving tolerance
  1421.          SetMatrixTol                MatrixTol       matrix tolerance
  1422.  
  1423.          InDepth                     GetInDepth      current max int depth
  1424.          InTol                       GetInTol        current int tolerance
  1425.          SolveTol                    GetSolveTol     current solve tolerance
  1426.          MatrixTol                   GetMatrixTol    current matrix tolerance
  1427.  
  1428.        My second reason for these changes is that the commands to set colors
  1429.        and other factors are used much more often than the commands to query
  1430.        them.  The more frequently used command should be shorter.
  1431.  
  1432. 12/10/91
  1433.        The way in which abbreviations are handled within the program code has
  1434.        been altered, so that now an unlimited number can be included.
  1435.        Previously, the abbreviations were counted with the other
  1436.        commands, and the total could not exceed 255.  Currently, the
  1437.        following abbreviations are recognized:
  1438.  
  1439.             Gr          Graph
  1440.             Qu          QuickG
  1441.             Sk          Sketch
  1442.             Po          PolarG
  1443.             Pa          ParamG
  1444.             Gr3         Graph3D
  1445.             √ (alt-q)   Sqrt
  1446.             Σ (alt-s)   Sum
  1447.             π (alt-p)   Pi
  1448.             Wi          Window
  1449.  
  1450.        suggestions for additional abbreviations are welcome.
  1451.  
  1452.        One new command has been added, at the suggestion of Jonathan
  1453.        March.  You can suppress the display of matrices and other long
  1454.        formulas by entering the command:
  1455.  
  1456.                           DISPLAYOFF
  1457.  
  1458.        To return to the default state, in which long formulas are
  1459.        displayed, enter the command:
  1460.  
  1461.                           DISPLAYON
  1462.  
  1463.        While DisplayOff is in effect, you can view a matrix or other
  1464.        complex value with the command Display(..).
  1465.  
  1466. 12/29/91
  1467.        After wrestling with expressions like sum(v), where v is a column
  1468.        vector, I've decided to make all 1 x 1 matrices automatically
  1469.        revert to scalars.  If you enter:  {3} , CC will return  3 .  If
  1470.        someone has a good reason (not mathematical purity) to avoid this
  1471.        default, I need to hear it.  Now, when v is a column vector,
  1472.        sum(v) is a scalar.
  1473.  
  1474.        This change--really a relaxation in the rules of mathematical
  1475.        rigor--required another.  Now, if x is a scalar, x[1] and x[1,1]
  1476.        both return x, just as though x were a list with one entry or a 1
  1477.        x 1 matrix.  This takes care of the following situation, which I
  1478.        encountered.  I wrote a general matrix algorithm, and when I
  1479.        tried to run it in the one-dimensional case, some of my
  1480.        intermediate results turned into scalars.  Yet I still referred
  1481.        (correctly) to x[i], when (in the one-dimensional case) i was
  1482.        always 1.  Thus I needed x[i] to return x in case x was a scalar
  1483.        that had been a 1 x 1 matrix.
  1484.  
  1485. 1/28/92
  1486.        I've just finished a week of intensive reprogramming.  Some
  1487.        numerical research I was doing required a better singular value
  1488.        algorithm than CC had.  So I replaced it with the standard one
  1489.        from LINPAK.  It worked so well that I decided to replace the
  1490.        eigenvalue routine with a standard one as well.  Done.  However,
  1491.        here's a caution.
  1492.  
  1493.        The standard shifted QR algorithm for finding eigenvalues doesn't
  1494.        work very well on defective matrices.  On non-defective matrices
  1495.        it is much faster and at least as accurate as finding and solving
  1496.        the characteristic polynomial, which is the algorithm I used to
  1497.        use.  However, for defective matrices not already in Jordan
  1498.        canonical form, the shifted QR algorithm isn't very good.  For
  1499.        example, consider:
  1500.  
  1501.                                0   1   0   0   0
  1502.                                0   0   1   0   0
  1503.                     A   =      0   0   0   1   0
  1504.                                0   0   0   0   1
  1505.                                1   5  10  10   5
  1506.  
  1507.        A has eigenvalue -1 repeated 5 times but only one eigenvector, so
  1508.        it is highly defective.  CC will construct its characteristic
  1509.        polynomial and solve it for the five roots with a high degree of
  1510.        accuracy.  However, if you use the EIGVAL command, which invokes
  1511.        the shifted QR algorithm, CC finds 5 different complex
  1512.        eigenvalues, all differing from 1 by about 0.001 or more.
  1513.        Moreover, these eigenvalues are not all that bad numerically.
  1514.        Subtracting any of them from A and taking the determinant or rank
  1515.        of the result results in the expected value of 0 or 4.
  1516.  
  1517.        The moral is:  CC's new algorithm is excellent for most matrices,
  1518.        but beware of using it on defective matrices.  (Note added 3/3/92:
  1519.        Matlab suffers from the same problem.  I don't feel so bad.  To
  1520.        find the eigenvalues of a defective matrix, use the polynomial
  1521.        root solver on the characteristic polynomial.  This is a very
  1522.        accurate method.)
  1523.  
  1524. 2/13/92
  1525.        Only a few weeks to Deadline Day (4/1/92), but we're still making
  1526.        improvements.  Now, after marking a block of text, you can save
  1527.        it to a file by pressing F7.  Once saved, the text can be
  1528.        reloaded by pressing Shift-f4.  This works like the block move
  1529.        (and uses much of the same code), but the buffer is on disk
  1530.        instead of in memory, so text can be passed from one CC session
  1531.        to another.  In particular, individual subroutines can be saved
  1532.        on disk for reloading.
  1533.  
  1534.        Previously, shift-F4 erased all the text buffers.  That function
  1535.        has been passed to Control-F4.
  1536.  
  1537. 3/23/92
  1538.        Two users have reported in the last week that animated graphics
  1539.        created difficulties with the graphics save feature.  Too much is
  1540.        saved, and saved unnecessarily since much of what is saved is
  1541.        overwritten.  It is now possible to block the graphics save
  1542.        feature with the command:
  1543.  
  1544.                         GSAVEOFF
  1545.  
  1546.        While this is in effect, no graphics elements will be saved.  To
  1547.        start saving graphs again, execute:
  1548.  
  1549.                          GSAVEON
  1550.  
  1551. 3/29/92
  1552.        I've changed the integration algorithm to a much better one, the
  1553.        Gauss-Kronrod algorithm from Kahaner, Moler and Nash, Numerical
  1554.        Methods and Software (Prentice Hall 1989) pp. 153-160.  Much
  1555.        faster for the same level of accuracy, especially on improper
  1556.        integrals.  I've added a command:
  1557.  
  1558.                          INERROR
  1559.  
  1560.         returns the estimated error of the last integral.  It is very
  1561.         conservative, and could easily overestimate the error by a
  1562.         factor of 10 or more.
  1563.  
  1564. 5/27/92
  1565.         CC has changed its name to X(PLORE).  I'm busy changing all screen
  1566.         displays and the manual.
  1567.  
  1568. 5/28/92
  1569.         OK.  This is really, truly the last major change.  Based on an article
  1570.         by Knuth in the MONTHLY and a couple of requests from users and
  1571.         some work I'm doing with a pre-calculus text, I've removed the
  1572.         boolean type from CC.  Now true and 1 are equal; both are real
  1573.         values.  You can say
  1574.  
  1575.                             While 1
  1576.  
  1577.         just like
  1578.  
  1579.                             While true
  1580.  
  1581.         The constants true and false remain in CC, but they equal 1 and
  1582.         0.  Boolean expression like x < 3 or x > 4 return a real value 1
  1583.         or 0.  Numerical expressions can replace boolean ones, provided
  1584.         they evaluate to 1 or 0.  The advantage here is that you can
  1585.         define the step function that is 0 for x < a and 1 for x > a by
  1586.         entering:
  1587.  
  1588.                          step(x,a) = x > a
  1589.  
  1590.         To define the function:
  1591.  
  1592.                          f(x) = x-1    if x < 1
  1593.                               = x^2-x  if x >= 1
  1594.  
  1595.         enter:
  1596.  
  1597.                          f(x) = (x-1)*(x < 1) + (x^2-x)*(x >= 1)
  1598.  
  1599.         Neat, huh?  I think it's worth it, especially since I have to
  1600.         redo the manual anyway to change CC to X(PLORE).
  1601.  
  1602. 6/2/91
  1603.         The new, integer-valued versions of true and false screw up the
  1604.         application of boolean operators to integers.  Specifically, not(1)
  1605.         is 0 if 1 if true, but not(1) is $FFFFFFFE if 1 is $00000001.  Also
  1606.         short-circuit evaluation of 1 or ... and 0 and ... is ok if 1 and 0
  1607.         and true and false, but not if they are integers.  So I've invented
  1608.         new operators, iand, ior, ixor and inot to use with integers, reserving
  1609.         and, or, xor and not for booleans 0 and 1.  Thus 1 or 8 = 1 (X(PLORE)
  1610.         never even looks at the 8--1 or ... = 1 always by short-circuit
  1611.         evaluation) but 1 ior 8 = 9.
  1612.  
  1613. 6/3/91
  1614.         I've had to consider order of operations for inequalities. Let
  1615.         log  be logical operator,   com  be comparison,  alg be +-*/
  1616.         then from last done to first we have log,alg,com.  Exponents are
  1617.         performed after comparisons for technical reasons.
  1618.         Thus  a<b and c<d is ok,  a<b-1 is (a<b)-1 which you don't
  1619.         want.  a<b<c will compile, but it means a<(b<c) or a<(1 or 0),
  1620.         which you also don't want.  SEE NEXT REMARK.
  1621.  
  1622. 6/7/91
  1623.         I've reconsidered the order of operations.  They are as follows,
  1624.         from first performed to last:
  1625.           exponentiation, multiplication, addition, comparison,
  1626.               concatenation of lists, logical operations
  1627.         Thus a-b < c-d means (a-b) < (c-d) but a<b - c<d need parentheses
  1628.         to mean (a<b) - (c<d).  Note:  a<b<c will parse, but it means
  1629.         (a<b)<c where (a<b) will be 1 or 0.  This isn't very useful.
  1630.         You should write a<b and b<c.
  1631.  
  1632.