%%HP: T(3)A(R)F(.); @ CMAT: HP48 program to apply expressions to columns of a matrix. @ 03/22/91 Version 1.0 @ Wes Hubert @ @ CMAT provides operations on matrix columns. To use it, place a matrix on @ level 2 of the stack, and an algebraic equation object or command list @ on level 1 of the stack. (See external documentation for information @ about command lists.) The equation should be of the form: @ 'Ci=expression', where "Ci" specifies the column where the @ result should be placed, and "expression" uses "C1, C2, ... Cn" to @ specify columns 1, 2, ... n of the matrix. For example: @ [[1 2] [3 4] [5 6]] @ 'C1=C2^2+C1' @ would return: @ [[5 2] [19 4] [41 6]] @ @ If the output column is not in the original matrix, the matrix will be @ expanded to include enough new columns to store it, filling any new @ unreferenced columns with zero. For example, if the equation for @ the input matrix above were 'C4=C2^2+C1', the result would be: @ [[1 2 0 5] [3 4 0 19] [5 6 0 41]] @ @ CMAT creates a working directory, stores variables into it, and @ purges the directory when it finishes. It includes rudimentary error @ trapping to purge the working directory even if it does not run to @ completion. @ DIR CMAT @ Protect environment from data errors \<< 'WRKTAB' CRDIR WRKTAB IFERR CMAIN THEN UPDIR 'WRKTAB' PGDIR ERRM DOERR ELSE UPDIR 'WRKTAB' PGDIR END \>> CMAIN @ Main program for column processing \<< { } 'NAMES' STO IF DUP TYPE 5 \=/ THEN 1 \->LIST END 'FLIST' STO 1 FLIST SIZE FOR elt FLIST elt GET IF CPARSE THEN CCOND CRESULT CADJUST 1 NR FOR ir ir 'CASEID' STO 1 NC FOR ic ir ic 2 \->LIST GETI SWAP DROP NAMES ic GET STO NEXT IF CTST THEN FORM EVAL \->NUM ir RESULT 2 \->LIST SWAP PUT END NEXT END NEXT \>> CPARSE @ Scan item from command list. \<< IF DUP TYPE 5 \=/ @ If not a list, THEN 1 @ treat as algebraic equation ELSE DUP 1 GET 1 1 SUB @ Check first char of keyword CASE DUP "N" == @ "NAMELIST" THEN DROP 2 99 SUB CNL 0 @ Process in CNL, return 0 END DUP "I" == @ "IF" THEN DROP DUP 3 GET SWAP 2 GET 1 @ Return equation & condition END "C" == @ "COMPUTE" THEN 2 GET 1 @ Return equation only END END END \>> CNL @ Process namelist {{position name}...} \<< IF DUP TYPE 5 == THEN 1 OVER SIZE FOR i DUP i GET 1 GETI IF DUP NAMES SIZE > THEN NAMES SIZE 1 + OVER FOR i NAMES "C" i + @ Default name C+column# # 5B15h SYSEVAL + 'NAMES' STO @ String to variable name NEXT END ROT ROT GET NAMES ROT ROT PUT 'NAMES' STO NEXT END DROP \>> CCOND @ Process conditional part, if present \<< IF DUP \->STR DUP "=" POS SWAP "==" POS NOT AND THEN 1 @ Default is TRUE (1) END 'CTST' STO \>> CRESULT @ Save result column # in RESULT \<< OBJ\-> DROP2 'FORM' STO IF NAMES OVER POS DUP THEN SWAP DROP ELSE DROP \->STR 3 OVER SIZE 1 - SUB OBJ\-> END 'RESULT' STO \>> CADJUST @ Add columns to matrix and names \<< DUP SIZE DUP 1 GET 'NR' STO 2 GET 'NC' STO IF NC RESULT < THEN TRN RESULT NR 2 \->LIST RDM TRN END NAMES DUP SIZE 1 + NC FOR i "C" i + # 5B15h SYSEVAL + NEXT 'NAMES' STO \>> END