d by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: define,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/define,v $ ## ## ## Under source code control: 1991/07/21 04:37:18 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * environment ************* Environment variables CALCPATH A :-separated list of directories used to search for resource filenames (*.cal files) that do not begin with: / ./ ../ ~ If this variable does not exist, a compiled value is used. Typically compiled in value is: .:./cal:~/cal:${CALC_SHAREDIR}:${CUSTOMCALDIR} which is usually: .:./cal:~/cal:/usr/share/calc:/usr/share/calc/custom This value is used by the READ command. It is an error if no such readable file is found. The CALCBINDINGS file searches the CALCPATH as well. CALCRC On startup (unless -h or -q was given on the command line), calc searches for files along the :-separated $CALCRC environment variable. If this variable does not exist, a compiled value is used. Typically compiled in value is: ${CALC_SHAREDIR}/startup:~/.calcrc:./.calcinit which is usually: /usr/share/calc/startup:~/.calcrc:./.calcinit Missing files along the $CALCRC path are silently ignored. CALCBINDINGS On startup (unless -h or -q was given on the command line), calc reads key bindings from the filename specified in the $CALCRC environment variable. These key bindings are used for command line editing and the command history. If this variable does not exist, a compiled value is used. Typically compiled in value is: bindings The bindings file is searched along the CALCPATH. Unlike the READ command, a .cal extension is not added. If the file could not be opened, or if standard input is not a terminal, then calc will still run, but fancy command line editing is disabled. NOTE: If calc was compiled with GNU-readline support, the CALCBINDINGS facility is ignored and the standard readline mechanisms (see readline(3)) are used. HOME This value is taken to be the home directory of the current user. It is used when files begin with '~/'. If this variable does not exist, the home directory password entry of the current user is used. If that information is not available, '.' is used. PAGER When invoking help, this environment variable is used to display a help file. If this variable does not exist, a compiled value is used. Typically compiled in value is something such as 'more', 'less', 'pg' or 'cat'. SHELL When a !-command is used, the program indicated by this environment variable is used. If this variable does not exist, a compiled value is used. Typically compiled in value is something such as 'sh' is used. ## Copyright (C) 1999 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: environment,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/environment,v $ ## ## Under source code control: 1991/07/23 05:47:25 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * expression ************* Expression sequences This is a sequence of statements, of which expression statements are the commonest case. Statements are separated with semicolons, and the newline character generally ends the sequence. If any statement is an expression by itself, or is associated with an 'if' statement which is true, then two special things can happen. If the sequence is executed at the top level of the calculator, then the value of '.' is set to the value of the last expression. Also, if an expression is a non-assignment, then the value of the expression is automatically printed if its value is not NULL. Some operations such as pre-increment and plus-equals are also treated as assignments. Examples of this are the following: expression sets '.' to prints ---------- ----------- ------ 3+4 7 7 2*4; 8+1; fact(3) 6 8, 9, and 6 x=3^2 9 - if (3 < 2) 5; else 6 6 6 x++ old x - print fact(4) - 24 null() null() - Variables can be defined at the beginning of an expression sequence. This is most useful for local variables, as in the following example, which sums the square roots of the first few numbers: local s, i; s = 0; for (i = 0; i < 10; i++) s += sqrt(i); s If a return statement is executed in an expression sequence, then the result of the expression sequence is the returned value. In this case, '.' is set to the value, but nothing is printed. ## Copyright (C) 1999 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: expression,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/expression,v $ ## ## Under source code control: 1991/07/21 04:37:18 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * errorcodes ************* Calc generated error codes (see the error help file): ## Copyright (C) 1999 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: errorcodes.hdr,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/errorcodes.hdr,v $ ## ## Under source code control: 1995/12/18 03:19:11 ## File existed as early as: 1995 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ 10001 Division by zero 10002 Indeterminate (0/0) 10003 Bad arguments for + 10004 Bad arguments for binary - 10005 Bad arguments for * 10006 Bad arguments for / 10007 Bad argument for unary - 10008 Bad argument for squaring 10009 Bad argument for inverse 10010 Bad argument for ++ 10011 Bad argument for -- 10012 Bad argument for int 10013 Bad argument for frac 10014 Bad argument for conj 10015 Bad first argument for appr 10016 Bad second argument for appr 10017 Bad third argument for appr 10018 Bad first argument for round 10019 Bad second argument for round 10020 Bad third argument for round 10021 Bad first argument for bround 10022 Bad second argument for bround 10023 Bad third argument for bround 10024 Bad first argument for sqrt 10025 Bad second argument for sqrt 10026 Bad third argument for sqrt 10027 Bad first argument for root 10028 Bad second argument for root 10029 Bad third argument for root 10030 Bad argument for norm 10031 Bad first argument for << or >> 10032 Bad second argument for << or >> 10033 Bad first argument for scale 10034 Bad second argument for scale 10035 Bad first argument for ^ 10036 Bad second argument for ^ 10037 Bad first argument for power 10038 Bad second argument for power 10039 Bad third argument for power 10040 Bad first argument for quo or // 10041 Bad second argument for quo or // 10042 Bad third argument for quo 10043 Bad first argument for mod or % 10044 Bad second argument for mod or % 10045 Bad third argument for mod 10046 Bad argument for sgn 10047 Bad first argument for abs 10048 Bad second argument for abs 10049 Scan error in argument for eval 10050 Non-simple type for str 10051 Non-real epsilon for exp 10052 Bad first argument for exp 10053 Non-file first argument for fputc 10054 Bad second argument for fputc 10055 File not open for writing for fputc 10056 Non-file first argument for fgetc 10057 File not open for reading for fgetc 10058 Non-string arguments for fopen 10059 Unrecognized mode for fopen 10060 Non-file first argument for freopen 10061 Non-string or unrecognized mode for freopen 10062 Non-string third argument for freopen 10063 Non-file argument for fclose 10064 Non-file argument for fflush 10065 Non-file first argument for fputs 10066 Non-string argument after first for fputs 10067 File not open for writing for fputs 10068 Non-file argument for fgets 10069 File not open for reading for fgets 10070 Non-file first argument for fputstr 10071 Non-string argument after first for fputstr 10072 File not open for writing for fputstr 10073 Non-file first argument for fgetstr 10074 File not open for reading for fgetstr 10075 Non-file argument for fgetline 10076 File not open for reading for fgetline 10077 Non-file argument for fgetfield 10078 File not open for reading for fgetfield 10079 Non-file argument for rewind 10080 Non-integer argument for files 10081 Non-string fmt argument for fprint 10082 Stdout not open for writing to ??? 10083 Non-file first argument for fprintf 10084 Non-string second (fmt) argument for fprintf 10085 File not open for writing for fprintf 10086 Non-string first (fmt) argument for strprintf 10087 Error in attempting strprintf ??? 10088 Non-file first argument for fscan 10089 File not open for reading for fscan 10090 Non-string first argument for strscan 10091 Non-file first argument for fscanf 10092 Non-string second (fmt) argument for fscanf 10093 Non-lvalue argument after second for fscanf 10094 File not open for reading or other error for fscanf 10095 Non-string first argument for strscanf 10096 Non-string second (fmt) argument for strscanf 10097 Non-lvalue argument after second for strscanf 10098 Some error in attempting strscanf ??? 10099 Non-string first (fmt) argument for scanf 10100 Non-lvalue argument after first for scanf 10101 Some error in attempting scanf ??? 10102 Non-file argument for ftell 10103 File not open or other error for ftell 10104 Non-file first argument for fseek 10105 Non-integer or negative second argument for fseek 10106 File not open or other error for fseek 10107 Non-file argument for fsize 10108 File not open or other error for fsize 10109 Non-file argument for feof 10110 File not open or other error for feof 10111 Non-file argument for ferror 10112 File not open or other error for ferror 10113 Non-file argument for ungetc 10114 File not open for reading for ungetc 10115 Bad second argument or other error for ungetc 10116 Exponent too big in scanning 10117 E_ISATTY1 is no longer used 10118 E_ISATTY2 is no longer used 10119 Non-string first argument for access 10120 Bad second argument for access 10121 Bad first argument for search 10122 Bad second argument for search 10123 Bad third argument for search 10124 Bad fourth argument for search 10125 Cannot find fsize or fpos for search 10126 File not readable for search 10127 Bad first argument for rsearch 10128 Bad second argument for rsearch 10129 Bad third argument for rsearch 10130 Bad fourth argument for rsearch 10131 Cannot find fsize or fpos for rsearch 10132 File not readable for rsearch 10133 Too many open files 10134 Attempt to rewind a file that is not open 10135 Bad argument type for strerror 10136 Index out of range for strerror 10137 Bad epsilon for cos 10138 Bad first argument for cos 10139 Bad epsilon for sin 10140 Bad first argument for sin 10141 Non-string argument for eval 10142 Bad epsilon for arg 10143 Bad first argument for arg 10144 Non-real argument for polar 10145 Bad epsilon for polar 10146 Non-integral argument for fcnt 10147 Non-variable first argument for matfill 10148 Non-matrix first argument-value for matfill 10149 Non-matrix argument for matdim 10150 Non-matrix argument for matsum 10151 E_ISIDENT is no longer used 10152 Non-matrix argument for mattrans 10153 Non-two-dimensional matrix for mattrans 10154 Non-matrix argument for det 10155 Matrix for det not of dimension 2 10156 Non-square matrix for det 10157 Non-matrix first argument for matmin 10158 Non-positive-integer second argument for matmin 10159 Second argument for matmin exceeds dimension 10160 Non-matrix first argument for matmin 10161 Second argument for matmax not positive integer 10162 Second argument for matmax exceeds dimension 10163 Non-matrix argument for cp 10164 Non-one-dimensional matrix for cp 10165 Matrix size not 3 for cp 10166 Non-matrix argument for dp 10167 Non-one-dimensional matrix for dp 10168 Different-size matrices for dp 10169 Non-string argument for strlen 10170 Non-string argument for strcat 10171 Non-string first argument for strcat 10172 Non-non-negative integer second argument for strcat 10173 Bad argument for char 10174 Non-string argument for ord 10175 Non-list-variable first argument for insert 10176 Non-integral second argument for insert 10177 Non-list-variable first argument for push 10178 Non-list-variable first argument for append 10179 Non-list-variable first argument for delete 10180 Non-integral second argument for delete 10181 Non-list-variable argument for pop 10182 Non-list-variable argument for remove 10183 Bad epsilon argument for ln 10184 Non-numeric first argument for ln 10185 Non-integer argument for error 10186 Argument outside range for error 10187 Attempt to eval at maximum input depth 10188 Unable to open string for reading 10189 First argument for rm is not a non-empty string 10190 Unable to remove a file 10191 Operation allowed because calc mode disallows read operations 10192 Operation allowed because calc mode disallows write operations 10193 Operation allowed because calc mode disallows exec operations 10194 Unordered arguments for min 10195 Unordered arguments for max 10196 Unordered items for minimum of list 10197 Unordered items for maximum of list 10198 Size undefined for argument type 10199 Calc must be run with a -C argument to use custom function 10200 Calc was built with custom functions disabled 10201 Custom function unknown, try: show custom 10202 Non-integral length for block 10203 Negative or too-large length for block 10204 Non-integral chunksize for block 10205 Negative or too-large chunksize for block 10206 Named block does not exist for blkfree 10207 Non-integral id specification for blkfree 10208 Block with specified id does not exist 10209 Block already freed 10210 No-realloc protection prevents blkfree 10211 Non-integer argument for blocks 10212 Non-allocated index number for blocks 10213 Non-integer or negative source index for copy 10214 Source index too large for copy 10215 E_COPY3 is no longer used 10216 Non-integer or negative number for copy 10217 Number too large for copy 10218 Non-integer or negative destination index for copy 10219 Destination index too large for copy 10220 Freed block source for copy 10221 Unsuitable source type for copy 10222 Freed block destinction for copy 10223 Unsuitable destination type for copy 10224 Incompatible source and destination for copy 10225 No-copy-from source variable 10226 No-copy-to destination variable 10227 No-copy-from source named block 10228 No-copy-to destination named block 10229 No-relocate destination for copy 10230 File not open for copy 10231 fseek or fsize failure for copy 10232 fwrite error for copy 10233 fread error for copy 10234 Non-variable first argument for protect 10235 Bad second argument for protect 10236 Bad third argument for protect 10237 No-copy-to destination for matfill 10238 No-assign-from source for matfill 10239 Non-matrix argument for mattrace 10240 Non-two-dimensional argument for mattrace 10241 Non-square argument for mattrace 10242 Bad epsilon for tan 10243 Bad argument for tan 10244 Bad epsilon for cot 10245 Bad argument for cot 10246 Bad epsilon for sec 10247 Bad argument for sec 10248 Bad epsilon for csc 10249 Bad argument for csc 10250 Bad epsilon for sinh 10251 Bad argument for sinh 10252 Bad epsilon for cosh 10253 Bad argument for cosh 10254 Bad epsilon for tanh 10255 Bad argument for tanh 10256 Bad epsilon for coth 10257 Bad argument for coth 10258 Bad epsilon for sech 10259 Bad argument for sech 10260 Bad epsilon for csch 10261 Bad argument for csch 10262 Bad epsilon for asin 10263 Bad argument for asin 10264 Bad epsilon for acos 10265 Bad argument for acos 10266 Bad epsilon for atan 10267 Bad argument for atan 10268 Bad epsilon for acot 10269 Bad argument for acot 10270 Bad epsilon for asec 10271 Bad argument for asec 10272 Bad epsilon for acsc 10273 Bad argument for acsc 10274 Bad epsilon for asin 10275 Bad argument for asinh 10276 Bad epsilon for acosh 10277 Bad argument for acosh 10278 Bad epsilon for atanh 10279 Bad argument for atanh 10280 Bad epsilon for acoth 10281 Bad argument for acoth 10282 Bad epsilon for asech 10283 Bad argument for asech 10284 Bad epsilon for acsch 10285 Bad argument for acsch 10286 Bad epsilon for gd 10287 Bad argument for gd 10288 Bad epsilon for agd 10289 Bad argument for agd 10290 Log of zero or infinity 10291 String addition failure 10292 String multiplication failure 10293 String reversal failure 10294 String subtraction failure 10295 Bad argument type for bit 10296 Index too large for bit 10297 Non-integer second argument for setbit 10298 Out-of-range index for setbit 10299 Non-string first argument for setbit 10300 Bad argument for or 10301 Bad argument for and 10302 Allocation failure for string or 10303 Allocation failure for string and 10304 Bad argument for xorvalue 10305 Bad argument for comp 10306 Allocation failure for string diff 10307 Allocation failure for string comp 10308 Bad first argument for segment 10309 Bad second argument for segment 10310 Bad third argument for segment 10311 Failure for string segment 10312 Bad argument type for highbit 10313 Non-integer argument for highbit 10314 Bad argument type for lowbit 10315 Non-integer argument for lowbit 10316 Bad argument type for unary hash op 10317 Bad argument type for binary hash op 10318 Bad first argument for head 10319 Bad second argument for head 10320 Failure for strhead 10321 Bad first argument for tail 10322 Bad second argument for tail 10323 Failure for strtail 10324 Failure for strshift 10325 Non-string argument for strcmp 10326 Bad argument type for strncmp 10327 Varying types of argument for xor 10328 Bad argument type for xor 10329 Bad argument type for strcpy 10330 Bad argument type for strncpy 10331 Bad argument type for unary backslash 10332 Bad argument type for setminus 10333 Bad first argument type for indices 10334 Bad second argument for indices 10335 Too-large re(argument) for exp 10336 Too-large re(argument) for sinh 10337 Too-large re(argument) for cosh 10338 Too-large im(argument) for sin 10339 Too-large im(argument) for cos 10340 Infinite or too-large result for gd 10341 Infinite or too-large result for agd 10342 Too-large value for power 10343 Too-large value for root 10344 Non-real first arg for digit 10345 Non-integral second arg for digit 10346 Bad third arg for digit 10347 Bad first argument for places 10348 Bad second argument for places 10349 Bad first argument for digits 10350 Bad second argument for digits 10351 Bad first argument for ilog 10352 Bad second argument for ilog 10353 Bad argument for ilog10 10354 Bad argument for ilog2 10355 Non-integer second arg for comb 10356 Too-large second arg for comb 10357 Bad argument for catalan 10358 Bad argument for bern 10359 Bad argument for euler 10360 Bad argument for sleep 10361 calc_tty failure 10362 No-copy-to destination for octet assign 10363 No-copy-from source for octet assign 10364 No-change destination for octet assign 10365 Non-variable destination for assign 10366 No-assign-to destination for assign 10367 No-assign-from source for assign 10368 No-change destination for assign 10369 No-type-change destination for assign 10370 No-error-value destination for assign 10371 No-copy argument for octet swap 10372 No-assign-to-or-from argument for swap 10373 Non-lvalue argument for swap 10374 Non-lvalue argument 3 or 4 for quomod 10375 Non-real-number arg 1 or 2 or bad arg 5 for quomod 10376 No-assign-to argument 3 or 4 for quomod 10377 No-copy-to or no-change argument for octet preinc 10378 Non-variable argument for preinc 10379 No-assign-to or no-change argument for preinc 10380 No-copy-to or no-change argument for octet predec 10381 Non-variable argument for predec 10382 No-assign-to or no-change argument for predec 10383 No-copy-to or no-change argument for octet postinc 10384 Non-variable argument for postinc 10385 No-assign-to or no-change argument for postinc 10386 No-copy-to or no-change argument for octet postdec 10387 Non-variable argument for postdec 10388 No-assign-to or no-change argument for postdec 10389 Error-type structure for initialization 10390 No-copy-to structure for initialization 10391 Too many initializer values 10392 Attempt to initialize freed named block 10393 Bad structure type for initialization 10394 No-assign-to element for initialization 10395 No-change element for initialization 10396 No-type-change element for initialization 10397 No-error-value element for initialization 10398 No-assign-or-copy-from source for initialization 10399 No-relocate for list insert 10400 No-relocate for list delete 10401 No-relocate for list push 10402 No-relocate for list append 10403 No-relocate for list pop 10404 No-relocate for list remove 10405 Non-variable first argument for modify 10406 Non-string second argument for modify 10407 No-change first argument for modify 10408 Undefined function for modify 10409 Unacceptable type first argument for modify 10410 Non-string arguments for fpathopen 10411 Unrecognized mode for fpathopen 10412 Bad epsilon argument for log 10413 Non-numeric first argument for log 10414 Non-file argument for fgetfile 10415 File argument for fgetfile not open for reading 10416 Unable to set file position in fgetfile 10417 Non-representable type for estr 20000 base of user defined errors ************* * file ************* Using files The calculator provides some functions which allow the program to read or write text files. These functions use stdio internally, and the functions appear similar to some of the stdio functions. Some differences do occur, as will be explained here. Names of files are subject to ~ expansion just like the C or Korn shell. For example, the file name: ~/.rc.cal refers to the file '.rc.cal' under your home directory. The file name: ~chongo/.rc.cal refers to the a file 'rc.cal' under the home directory of 'chongo'. A file can be opened for either reading, writing, or appending. To do this, the 'fopen' function is used, which accepts a filename and an open mode, both as strings. You use 'r' for reading, 'w' for writing, and 'a' for appending. For example, to open the file 'foo' for reading, the following could be used: fd = fopen('foo', 'r'); If the open is unsuccessful, the numeric value of errno is returned. If the open is successful, a value of type 'file' will be returned. You can use the 'isfile' function to test the return value to see if the open succeeded. You should assign the return value of fopen to a variable for later use. File values can be copied to more than one variable, and using any of the variables with the same file value will produce the same results. If you overwrite a variable containing a file value or don't save the result of an 'fopen', the opened file still remains open. Such 'lost' files can be recovered by using the 'files' function. This function either takes no arguments or else takes one integer argument. If no arguments are given, then 'files' returns the maximum number of opened files. If an argument is given, then the 'files' function uses it as an index into an internal table of open files, and returns a value referring to one the open files. If that entry in the table is not in use, then the null value is returned instead. Index 0 always refers to standard input, index 1 always refers to standard output, and index 2 always refers to standard error. These three files are already open by the calculator and cannot be closed. As an example of using 'files', if you wanted to assign a file value which is equivalent to stdout, you could use: stdout = files(1); The 'fclose' function is used to close a file which had been opened. When this is done, the file value associated with the file remains a file value, but appears 'closed', and cannot be used in further file-related calls (except fclose) without causing errors. This same action occurs to all copies of the file value. You do not need to explicitly close all the copies of a file value. The 'fclose' function returns the numeric value of errno if there had been an error using the file, or the null value if there was no error. The builtin 'strerror' can be use to convert an errno number into a slightly more meaningful error message: badfile = fopen("not_a_file", "r"); if (!isfile(badfile)) { print "error #" : badfile : ":", strerror(badfile); } File values can be printed. When this is done, the filename of the opened file is printed inside of quote marks. If the file value had been closed, then the null string is printed. If a file value is the result of a top-level expression, then in addition to the filename, the open mode, file position, and possible EOF, error, and closed status is also displayed. File values can be used inside of 'if' tests. When this is done, an opened file is TRUE, and a closed file is FALSE. As an example of this, the following loop will print the names of all the currently opened non-standard files with their indexes, and then close them: for (i = 3; i < files(); i++) { if (files(i)) { print i, files(i); fclose(files(i)); } } The functions to read from files are 'fgetline' and 'fgetc'. The 'fgetline' function accepts a file value, and returns the next input line from a file. The line is returned as a string value, and does not contain the end of line character. Empty lines return the null string. When the end of file is reached, fgetline returns the null value. (Note the distinction between a null string and a null value.) If the line contained a numeric value, then the 'eval' function can then be used to convert the string to a numeric value. Care should be used when doing this, however, since eval will generate an error if the string doesn't represent a valid expression. The 'fgetc' function returns the next character from a file as a single character string. It returns the null value when end of file is reached. The 'printf' and 'fprintf' functions are used to print results to a file (which could be stdout or stderr). The 'fprintf' function accepts a file variable, whereas the 'printf' function assumes the use of 'files(1)' (stdout). They both require a format string, which is used in almost the same way as in normal C. The differences come in the interpretation of values to be printed for various formats. Unlike in C, where an unmatched format type and value will cause problems, in the calculator nothing bad will happen. This is because the calculator knows the types of all values, and will handle them all reasonably. What this means is that you can (for example), always use %s or %d in your format strings, even if you are printing a non- string or non-numeric value. For example, the following is valid: printf("Two values are %d and %s\n", "fred", 4567); and will print "Two values are fred and 4567". Using particular format characters, however, is still useful if you wish to use width or precision arguments in the format, or if you wish to print numbers in a particular format. The following is a list of the possible numeric formats: %d print in currently defined numeric format %f print as floating point %e print as exponential %r print as decimal fractions %x print as hex fractions %o print as octal fractions %b print as binary fractions Note then, that using %d in the format makes the output configurable by using the 'config' function to change the output mode, whereas the other formats override the mode and force the output to be in the specified format. Using the precision argument will override the 'config' function to set the number of decimal places printed. For example: printf("The number is %.100f\n", 1/3); will print 100 decimal places no matter what the display configuration value is set to. The %s and %c formats are identical, and will print out the string representation of the value. In these cases, the precision argument will truncate the output the same way as in standard C. If a matrix or list is printed, then the output mode and precision affects the printing of each individual element. However, field widths are ignored since these values print using multiple lines. Field widths are also ignored if an object value prints on multiple lines. The functions 'fputc' and 'fputs' write a character and string to a file respectively. The final file-related functions are 'fflush', 'ferror', and 'feof'. The 'fflush' function forces buffered output to a file. The 'ferror' function returns nonzero if an error had occurred to a file. The 'feof' function returns nonzero if end of file has been reached while reading a file. The 'strprintf' function formats output similarly to 'printf', but the output is returned as a string value instead of being printed. ## Copyright (C) 1999-2006 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: file,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/file,v $ ## ## Under source code control: 1991/07/21 04:37:19 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * history ************* Command history There is a command line editor and history mechanism built into calc, which is active when stdin is a terminal. When stdin is not a terminal, then the command line editor is disabled. Lines of input to calc are always terminated by the return (or enter) key. When the return key is typed, then the current line is executed and is also saved into a command history list for future recall. Before the return key is typed, the current line can be edited using emacs-like editing commands. As examples, ^A moves to the beginning of the line, ^F moves forwards through the line, backspace removes characters from the line, and ^K kills the rest of the line. Previously entered commands can be recalled by using the history list. The history list functions in a LRU manner, with no duplicated lines. This means that the most recently entered lines are always at the end of the history list where they are easiest to recall. Typing h lists all of the commands in the command history and numbers the lines. The most recently executed line is always number 1, the next most recent number 2, and so on. The numbering for a particular command therefore changes as lines are entered. Typing a number at the beginning of a line followed by g will recall that numbered line. So that for example, 2g will recall the second most recent line that was entered. The ^P and ^N keys move up and down the lines in the history list. If they attempt to go off the top or bottom of the list, then a blank line is shown to indicate this, and then they wrap around to the other end of the list. Typing a string followed by a ^R will search backwards through the history and recall the most recent command which begins with that string. Typing ^O inserts the current line at the end of the history list without executing it, and starts a new line. This is useful to rearrange old history lines to become recent, or to save a partially completed command so that another command can be typed ahead of it. If your terminal has arrow keys which generate escape sequences of a particular kind ([A and so on), then you can use those arrow keys in place of the ^B, ^F, ^P, and ^N keys. The actual keys used for editing are defined in a bindings file, usually called /usr/local/lib/calc/bindings. Changing the entries in this file will change the key bindings used for editing. If the file is not readable, then a message will be output and command line editing is disabled. In this case you can only edit each line as provided by the terminal driver in the operating system. A shell command can be executed by typing '!cmd', where cmd is the command to execute. If cmd is not given, then a shell command level is started. ## Copyright (C) 1999 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: history,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/history,v $ ## ## Under source code control: 1991/07/21 04:37:20 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * interrupt ************* Interrupts While a calculation is in progress, you can generate the SIGINT signal, and the calculator will catch it. At appropriate points within a calculation, the calculator will check that the signal has been given, and will abort the calculation cleanly. If the calculator is in the middle of a large calculation, it might be a while before the interrupt has an effect. You can generate the SIGINT signal multiple times if necessary, and each time the calculator will abort the calculation at a more risky place within the calculation. Each new interrupt prints a message of the form: [Abort level n] where n ranges from 1 to 3. For n equal to 1, the calculator will abort calculations at the next statement boundary specified by an ABORT opcode as described below. For n equal to 2, the calculator will abort calculations at the next opcode boundary. For n equal to 3, the calculator will abort calculations at the next attempt to allocate memory for the result of an integer arithmetic operation; this level may be appropriate for stopping a builtin operation like inversion of a large matrix. If a final interrupt is given when n is 3, the calculator will immediately abort the current calculation and longjmp back to the top level command level. Doing this may result in corrupted data structures and unpredictable future behavior, and so should only be done as a last resort. You are advised to quit the calculator after this has been done. ABORT opcodes If config("trace") & 2 is zero, ABORT opcodes are introduced at various places in the opcodes for evaluation of command lines and functions defined by "define ... { ... }" commands. In the following, config("trace") has been set equal to 8 so that opcodes are displayed when a function is defined. The function f(x) evaluates x + (x - 1) + (x - 2) + ... until a zero term is encountered. If f() is called with a negative or fractional x, the calculation is never completed and to stop it, an interruption (on many systems, by ctrl-C) will be necessary. ; config("trace", 8), ; define f(x) {local s; while (x) {s += x--} return s} 0: DEBUG line 2 2: PARAMADDR x 4: JUMPZ 19 6: DEBUG line 2 8: LOCALADDR s 10: DUPLICATE 11: PARAMADDR x 13: POSTDEC 14: POP 15: ADD 16: ASSIGNPOP 17: JUMP 2 19: DEBUG line 2 21: LOCALADDR s 23: RETURN f(x) defined (The line number following DEBUG refers to the line in the file from which the definition is read.) If an attempt is made to evaluate f(-1), the effect of the DEBUG at opcode 6 ensures that a single SIGINT will stop the calculation at a start of {s += x--} loop. In interactive mode, with ^C indicating input of ctrl-C, the displayed output is as in: ; f(-1) ^C [Abort level 1] "f": line 2: Calculation aborted at statement boundary The DEBUG opcodes are disabled by nonzero config("trace") & 2. Changing config("trace") to achieve this, and defining g(x) with the same definition as for f(x) gives: ; define g(x) {local s; while (x) {s += x--} return s} 0: PARAMADDR x 2: JUMPZ 15 4: LOCALADDR s 6: DUPLICATE 7: PARAMADDR x 9: POSTDEC 10: POP 11: ADD 12: ASSIGNPOP 13: JUMP 0 15: LOCALADDR s 17: RETURN g(x) defined If g(-1) is called, two interrupts are necessary, as in: ; g(-1) ^C [Abort level 1] ^C [Abort level 2] "g": Calculation aborted in opcode ## Copyright (C) 1999-2006 David I. Bell, Landon Curt Noll and Ernest Bowen ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: interrupt,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/interrupt,v $ ## ## Under source code control: 1991/07/21 04:37:21 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * list ************* NAME list - create list of specified values SYNOPSIS list([x, [x, ... ]]) TYPES x any, &any return list DESCRIPTION This function returns a list that is composed of the arguments x. If no args are given, an empty list is returned. Lists are a sequence of values which are doubly linked so that elements can be removed or inserted anywhere within the list. The function 'list' creates a list with possible initial elements. For example, x = list(4, 6, 7); creates a list in the variable x of three elements, in the order 4, 6, and 7. The 'push' and 'pop' functions insert or remove an element from the beginning of the list. The 'append' and 'remove' functions insert or remove an element from the end of the list. The 'insert' and 'delete' functions insert or delete an element from the middle (or ends) of a list. The functions which insert elements return the null value, but the functions which remove an element return the element as their value. The 'size' function returns the number of elements in the list. Note that these functions manipulate the actual list argument, instead of returning a new list. Thus in the example: push(x, 9); x becomes a list of four elements, in the order 9, 4, 6, and 7. Lists can be copied by assigning them to another variable. An arbitrary element of a linked list can be accessed by using the double-bracket operator. The beginning of the list has index 0. Thus in the new list x above, the expression x[[0]] returns the value of the first element of the list, which is 9. Note that this indexing does not remove elements from the list. Since lists are doubly linked in memory, random access to arbitrary elements can be slow if the list is large. However, for each list a pointer is kept to the latest indexed element, thus relatively sequential accesses to the elements in a list will not be slow. Lists can be searched for particular values by using the 'search' and 'rsearch' functions. They return the element number of the found value (zero based), or null if the value does not exist in the list. EXAMPLE ; list(2,"three",4i) list (3 elements, 3 nonzero): [[0]] = 2 [[1]] = "three" [[2]] = 4i ; list() list (0 elements, 0 nonzero) LIMITS none LINK LIBRARY none SEE ALSO append, delete, insert, islist, pop, push, remove, rsearch, search, size ## Copyright (C) 1999 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: list,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/list,v $ ## ## Under source code control: 1994/03/19 03:13:19 ## File existed as early as: 1994 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * mat ************* NAME mat - keyword to create a matrix value SYNOPSIS mat [index-range-list] [ = {value_0. ...} ] mat [] [= {value_0, ...}] mat variable_1 ... [index-range-list] [ = {value_0, ...} ] mat variable_1 ... [] [ = {value_0, ...} ] mat [index-range-list_1[index-ranges-list_2] ... [ = { { ...} ...} ] decl id_1 id_2 ... [index-range-list] ... TYPES index-range-list range_1 [, range_2, ...] up to 4 ranges range_1, ... integer, or integer_1 : integer_2 value, value_1, ... any variable_1 ... lvalue decl declarator = global, static or local id_1, ... identifier DESCRIPTION The expression mat [index-range-list] returns a matrix value. This may be assigned to one or more lvalues A, B, ... by either mat A B ... [index-range-list] or A = B = ... = mat[index-range-list] If a variable is specified by an expression that is not a symbol with possibly object element specifiers, the expression should be enclosed in parentheses. For example, parentheses are required in mat (A[2]) [3] and mat (*p) [3] but mat P.x [3] is acceptable. When an index-range is specified as integer_1 : integer_2, where integer_1 and integer_2 are expressions which evaluate to integers, the index-range consists of all integers from the minimum of the two integers to the maximum of the two integers. For example, mat[2:5, 0:4] and mat[5:2, 4:0] return the same matrix value. If an index-range is an expression which evaluates to an integer, the range is as if specified by 0 : integer - 1. For example, mat[4] and mat[0:3] return the same 4-element matrix; mat[-2] and mat[-3:0] return the same 4-element matrix. If the variable A has a matrix value, then for integer indices i_1, i_2, ..., equal in number to the number of ranges specified at its creation, and such that each index is in the corresponding range, the matrix element associated with those index list is given as an lvalue by the expressions A[i_1, i_2, ...]. The elements of the matrix are stored internally as a linear array in which locations are arranged in order of increasing indices. For example, in order of location, the six element of A = mat [2,3] are A[0,0], A[0,1], A[0,2], A[1,0], A[1,,1], A[1,2]. These elements may also be specified using the double-bracket operator with a single integer index as in A[[0]], A[[1]], ..., A[[5]]. If p is assigned the value &A[0.0], the address of A[[i]] for 0 <= i < 6 is p + i as long as A exists and a new value is not assigned to A. When a matrix is created, each element is initially assigned the value zero. Other values may be assigned then or later using the "= {...}" assignment operation. Thus A = {value_0, value_1, ...} assigns the values value_0, value_1, ... to the elements A[[0]], A[[1]], ... Any blank "value" is passed over. For example, A = {1, , 2} will assign the value 1 to A[[0]], 2 to A[[2]] and leave all other elements unchanged. Values may also be assigned to elements by simple assignments, as in A[0,0] = 1, A[0,2] = 2; If the index-range is left blank but an initializer list is specified as in: ; mat A[] = {1, 2 } ; B = mat[] = {1, , 3, } the matrix created is one-dimensional. If the list contains a positive number n of values or blanks, the result is as if the range were specified by [n], i.e. the range of indices is from 0 to n - 1. In the above examples, A is of size 2 with A[0] = 1 and A[1] = 2; B is of size 4 with B[0] = 1, B[1] = B[3] = 0, B[2] = 3. The specification mat[] = { } creates the same as mat[1]. If the index-range is left blank and no initializer list is specified, as in mat C[] or C = mat[], the matrix assigned to C has zero dimension; this has one element C[]. To assign a value using "= { ...}" at the same time as creating C, parentheses are required as in (mat[]) = {value} or (mat C[]) = {value}. Later a value may be assigned to C[] by C[] = value or C = {value}. The value assigned at any time to any element of a matrix can be of any type - number, string, list, matrix, object of previously specified type, etc. For some matrix operations there are of course conditions that elements may have to satisfy: for example, addition of matrices requires that addition of corresponding elements be possible. If an element of a matrix is a structure for which indices or an object element specifier is required, an element of that structure is referred to by appropriate uses of [ ] or ., and so on if an element of that element is required. For example, one may have an expressions like: ; A[1,2][3].alpha[2]; if A[1,2][3].alpha is a list with at least three elements, A[1,2][3] is an object of a type like obj {alpha, beta}, A[1,2] is a matrix of type mat[4] and A is a mat[2,3] matrix. When an element of a matrix is a matrix and the total number of indices does not exceed 4, the indices can be combined into one list, e.g. the A[1,2][3] in the above example can be shortened to A[1,2,3]. (Unlike C, A[1,2] cannot be expressed as A[1][2].) The function ismat(V) returns 1 if V is a matrix, 0 otherwise. isident(V) returns 1 if V is a square matrix with diagonal elements 1, off-diagonal elements zero, or a zero- or one-dimensional matrix with every element 1; otherwise zero is returned. Thus isident(V) = 1 indicates that for V * A and A * V where A is any matrix of for which either product is defined and the elements of A are real or complex numbers, that product will equal A. If V is matrix-valued, test(V) returns 0 if every element of V tests as zero; otherwise 1 is returned. The dimension of a matrix A, i.e. the number of index-ranges in the initial creation of the matrix, is returned by the function matdim(A). For 1 <= i <= matdim(A), the minimum and maximum values for the i-th index range are returned by matmin(A, i) and matmax(A,i), respectively. The total number of elements in the matrix is returned by size(A). The sum of the elements in the matrix is returned by matsum(A). The default method of printing matrices is to give a line of information about the matrix, and to list on separate lines up to 15 elements, the indices and either the value (for numbers, strings, objects) or some descriptive information for lists or matrices, etc. Numbers are displayed in the current number-printing mode. The maximum number of elements to be printed can be assigned any nonnegative integer value m by config("maxprint", m). Users may define another method of printing matrices by defining a function mat_print(M); for example, for a not too big 2-dimensional matrix A it is a common practice to use a loop like: define mat_print(A) { local i,j; for (i = matmin(A,1); i <= matmax(A,1); i++) { if (i != matmin(A,1)) printf("\t"); for (j = matmin(A,2); j <= matmax(A,2); j++) printf(" [%d,%d]: %e", i, j, A[i,j]); if (i != matmax(A,1)) printf("\n"); } } So that when one defines a 2D matrix such as: ; mat X[2,3] = {1,2,3,4,5,6} then printing X results in: [0,0]: 1 [0,1]: 2 [0,2]: 3 [1,0]: 4 [1,1]: 5 [1,2]: 6 The default printing may be restored by ; undefine mat_print; The keyword "mat" followed by two or more index-range-lists returns a matrix with indices specified by the first list, whose elements are matrices as determined by the later index-range-lists. For example mat[2][3] is a 2-element matrix, each of whose elements has as its value a 3-element matrix. Values may be assigned to the elements of the innermost matrices by nested = {...} operations as in ; mat [2][3] = {{1,2,3},{4,5,6}} An example of the use of mat with a declarator is ; global mat A B [2,3], C [4] This creates, if they do not already exist, three global variables with names A, B, C, and assigns to A and B the value mat[2,3] and to C mat[4]. Some operations are defined for matrices. A == B Returns 1 if A and B are of the same "shape" and "corresponding" elements are equal; otherwise 0 is returned. Being of the same shape means they have the same dimension d, and for each i <= d, matmax(A,i) - matmin(A,i) == matmax(B,i) - matmin(B,i), One consequence of being the same shape is that the matrices will have the same size. Elements "correspond" if they have the same double-bracket indices; thus A == B implies that A[[i]] == B[[i]] for 0 <= i < size(A) == size(B). A + B A - B These are defined A and B have the same shape, the element with double-bracket index j being evaluated by A[[j]] + B[[j]] and A[[j]] - B[[j]], respectively. The index-ranges for the results are those for the matrix A. A[i,j] If A is two-dimensional, it is customary to speak of the indices i, j in A[i,j] as referring to rows and columns; the number of rows is matmax(A,1) - matmin(A,1) + 1; the number of columns if matmax(A,2) - matmin(A,2) + 1. A matrix is said to be square if it is two-dimensional and the number of rows is equal to the number of columns. A * B Multiplication is defined provided certain conditions by the dimensions and shapes of A and B are satisfied. If both have dimension 2 and the column-index-list for A is the same as the row-index-list for B, C = A * B is defined in the usual way so that for i in the row-index-list of A and j in the column-index-list for B, C[i,j] = Sum A[i,k] * B[k,j] the sum being over k in the column-index-list of A. The same formula is used so long as the number of columns in A is the same as the number of rows in B and k is taken to refer to the offset from matmin(A,2) and matmin(B,1), respectively, for A and B. If the multiplications and additions required cannot be performed, an execution error may occur or the result for C may contain one or more error-values as elements. If A or B has dimension zero, the result for A * B is simply that of multiplying the elements of the other matrix on the left by A[] or on the right by B[]. If both A and B have dimension 1, A * B is defined if A and B have the same size; the result has the same index-list as A and each element is the product of corresponding elements of A and B. If A and B have the same index-list, this multiplication is consistent with multiplication of 2D matrices if A and B are taken to represent 2D matrices for which the off-diagonal elements are zero and the diagonal elements are those of A and B. the real and complex numbers. If A is of dimension 1 and B is of dimension 2, A * B is defined if the number of rows in B is the same as the size of A. The result has the same index-lists as B; each row of B is multiplied on the left by the corresponding element of A. If A is of dimension 2 and B is of dimension 1, A * B is defined if number of columns in A is the same as the size of A. The result has the same index-lists as A; each column of A is multiplied on the right by the corresponding element of B. The algebra of additions and multiplications involving both one- and two-dimensional matrices is particularly simple when all the elements are real or complex numbers and all the index-lists are the same, as occurs, for example, if for some positive integer n, all the matrices start as mat [n] or mat [n,n]. det(A) If A is a square, det(A) is evaluated by an algorithm that returns the determinant of A if the elements of A are real or complex numbers, and if such an A is non-singular, inverse(A) returns the inverse of A indexed in the same way as A. For matrix A of dimension 0 or 1, det(A) is defined as the product of the elements of A in the order in which they occur in A, inverse(A) returns a matrix indexed in the same way as A with each element inverted. The following functions are defined to return matrices with the same index-ranges as A and the specified operations performed on all elements of A. Here num is an arbitrary complex number (nonzero when it is a divisor), int an integer, rnd a rounding-type specifier integer, real a real number. num * A A * num A / num - A conj(A) A << int, A >> int scale(A, int) round(A, int, rnd) bround(A, int, rnd) appr(A, real, rnd) int(A) frac(A) A // real A % real A ^ int If A and B are one-dimensional of the same size dp(A, B) returns their dot-product, i.e. the sum of the products of corresponding elements. If A and B are one-dimension and of size 3, cp(A, B) returns their cross-product. randperm(A) returns a matrix indexed the same as A in which the elements of A have been randomly permuted. sort(A) returns a matrix indexed the same as A in which the elements of A have been sorted. If A is an lvalue whose current value is a matrix, matfill(A, v) assigns the value v to every element of A, and if also, A is square, matfill(A, v1, v2) assigns v1 to the off-diagonal elements, v2 to the diagonal elements. To create and assign to A the unit n * n matrix, one may use matfill(mat A[n,n], 0, 1). For a square matrix A, mattrace(A) returns the trace of A, i.e. the sum of the diagonal elements. For zero- or one-dimensional A, mattrace(A) returns the sum of the elements of A. For a two-dimensional matrix A, mattrans(A) returns the transpose of A, i.e. if A is mat[m,n], it returns a mat[n,m] matrix with [i,j] element equal to A[j,i]. For zero- or one-dimensional A, mattrace(A) returns a matrix with the same value as A. The functions search(A, value, start, end]) and rsearch(A, value, start, end]) return the first or last index i for which A[[i]] == value and start <= i < end, or if there is no such index, the null value. For further information on default values and the use of an "accept" function, see the help files for search and rsearch. reverse(A) returns a matrix with the same index-lists as A but the elements in reversed order. The copy and blkcpy functions may be used to copy data to a matrix from a matrix or list, or from a matrix to a list. In copying from a matrix to a matrix the matrices need not have the same dimension; in effect they are treated as linear arrays. EXAMPLE ; obj point {x,y} ; mat A[5] = {1, 2+3i, "ab", mat[2] = {4,5}, obj point = {6,7}} ; A mat [5] (5 elements, 5 nonzero): [0] = 1 [1] = 2+3i [2] = "ab" [3] = mat [2] (2 elements, 2 nonzero) [4] = obj point {6, 7} ; print A[0], A[1], A[2], A[3][0], A[4].x 1 2+3i ab 4 6 ; define point_add(a,b) = obj point = {a.x + b.x, a.y + b.y} point_add(a,b) defined ; mat [B] = {8, , "cd", mat[2] = {9,10}, obj point = {11,12}} ; A + B mat [5] (5 elements, 5 nonzero): [0] = 9 [1] = 2+3i [2] = "abcd" [3] = mat [2] (2 elements, 2 nonzero) [4] = obj point {17, 19} ; mat C[2,2] = {1,2,3,4} ; C^10 mat [2,2] (4 elements, 4 nonzero): [0,0] = 4783807 [0,1] = 6972050 [1,0] = 10458075 [1,1] = 15241882 ; C^-10 mat [2,2] (4 elements, 4 nonzero): [0,0] = 14884.650390625 [0,1] = -6808.642578125 [1,0] = -10212.9638671875 [1,1] = 4671.6865234375 ; mat A[4] = {1,2,3,4}, A * reverse(A); mat [4] (4 elements, 4 nonzero): [0] = 4 [1] = 6 [2] = 6 [3] = 4 LIMITS The theoretical upper bound for the absolute values of indices is 2^31 - 1, but the size of matrices that can be handled in practice will be limited by the availability of memory and what is an acceptable runtime. For example, although it may take only a fraction of a second to invert a 10 * 10 matrix, it will probably take about 1000 times as long to invert a 100 * 100 matrix. LINK LIBRARY n/a SEE ALSO ismat, matdim, matmax, matmin, mattrans, mattrace, matsum, matfill, det, inverse, isident, test, config, search, rsearch, reverse, copy, blkcpy, dp, cp, randperm, sort ## Copyright (C) 1999-2006 Landon Curt Noll ## ## Calc is open software; you can redistribute it and/or modify it under ## the terms of the version 2.1 of the GNU Lesser General Public License ## as published by the Free Software Foundation. ## ## Calc is distributed in the hope that it will be useful, but WITHOUT ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General ## Public License for more details. ## ## A copy of version 2.1 of the GNU Lesser General Public License is ## distributed with calc under the filename COPYING-LGPL. You should have ## received a copy with calc; if not, write to Free Software Foundation, Inc. ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ## ## @(#) $Revision: 30.1 $ ## @(#) $Id: mat,v 30.1 2007/03/16 11:10:42 chongo Exp $ ## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/mat,v $ ## ## Under source code control: 1991/07/21 04:37:22 ## File existed as early as: 1991 ## ## chongo /\oo/\ http://www.isthe.com/chongo/ ## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ ************* * obj ************* Using objects Objects are user-defined types which are associated with user- defined functions to manipulate them. Object types are defined similarly to structures in C, and consist