rs@uunet.UU.NET (Rich Salz) (07/07/87)
Mod.sources: Volume 10, Number 34 Submitted by: robison@b.cs.uiuc.edu (Arch Robison) Archive-name: ifp/Part01 IFP[1] is a variant of Backus' FP [2]. The IFP interpreter is written in C and is an order of magnitude faster than the BSD 4.2 FP [3]. The interpreter should run on any UNIX box. Arch D. Robison University of Illinois at Urbana-Champaign CSNET: robison@UIUC.CSNET UUCP: {ihnp4,pur-ee,convex}!uiucdcs!robison ARPA: robison@B.CS.UIUC.EDU (robison@UIUC.ARPA) General References ------------------ [1] Arch D. Robison, "Illinois Functional Programming: A Tutorial," BYTE Vol. 12,2 pp. 115-125 McGraw-Hill Inc., (February 1987). [2] John Backus, "Can Programming Be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs," CACM Vol. 21,8 pp. 613-641 ACM, (August 1978). [3] Scott Baden, "Berkeley FP User's Manual, Rev. 4.1," UNIX Programmers Manual, (July 27,1983). #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh. # The following files will be created: # README # ifp.1 # RunIFP # fproot export PATH; PATH=/bin:$PATH if test -f 'README' then echo shar: over-writing existing file "'README'" fi cat << \SHAR_EOF > 'README' This directory contains the following subdirectories and files: README - this file RunIFP - shell script which runs IFP interpreter fproot - IFP demonstration root directory fproot/demo - demonstration functions interp - source code and Makefile for IFP interpreter manual - troff files and Makefile for IFP manual SHAR_EOF chmod +x 'README' if test -f 'ifp.1' then echo shar: over-writing existing file "'ifp.1'" fi cat << \SHAR_EOF > 'ifp.1' .TH IFP 1 "Jan 28, 1987" .UC 4 .SH NAME ifp \- Illinois FP interpreter .SH SYNOPSIS .B ifp [ option ] .SH DESCRIPTION .I Ifp starts the Illinois FP interpreter. .PP .I Ifp understands several options. Normally, no options are required. Most of the options are for experimental work. Not all (or even any) of the options may exist for a particular version of the interpreter. .TP .B \-l Print all functions with full pathname. Useful for debugging scope problems. .TP .B \-e[012] Turn on expression cache. The cache may be turned on for any subset of: .nf 0 Primitive functions 1 User-defined functions 2 PFOs .fi To see the cache statistics, give the command "cache" to the interpreter. .TP .B \-pn (Multimax only) This option specifies that the interpreter should be run as n parallel processes. .TP .B \-f (Multimax only) Print expression queue statistics. .TP .B \-sn (Multimax only) Use stack of max. depth n for expression scheduling. .TP .B \-qn (Multimax only) Use queue of max. length n for expression scheduling. .TP .B \-d[pafricxhusle] Turn on spy points corresponding to selected letters. .nf p parser a memory allocation f file io r reference counts i initialization c expression cache x extended definitions h hypercube u Multimax s Semaphores l Free list e Expression sckeduling .fi For example, -dar turns on spy points for memory allocation and reference counts. .SH FILES .ta \w'/usr/local/lib/lib*.a\ \ 'u ifp interpreter .br .SH "SEE ALSO" Illinois FP User's Manual .sp 2 A Functional Programming Interpreter (THESIS, Univerisity of Illinois) .sp 2 .ul Illinois Functional Programming: A Tutorial (BYTE, Feb. 1987) .br fp(1) .SH BUGS Programming in IFP still requires thinking. Some the options are incompatible. .SH AUTHOR Arch D. Robison SHAR_EOF if test -f 'RunIFP' then echo shar: over-writing existing file "'RunIFP'" fi cat << \SHAR_EOF > 'RunIFP' # Shell script for invoking IFP interpreter. # This script is for demonstration and documentation purposes only. # Running the script will set the appropriate environment variables # and start up the IFP interpreter in the demonstration directory. # All its actions should be put in the user's .login, and .cshrc files. # The IFP interpreter must be compiled before running this script. # See the Makefile in subdirectory "interp" for instructions on how # to compile the interpreter. #----------------------------------------------------------------------- # These two lines should go in each user's .login file and be customized # for the user's particular IFP root directory and editor. setenv IFProot $cwd/fproot setenv EDITOR "/usr/ucb/vi" # This alias is for convenience. Presumably the interpreter will normally # reside on the user's search path. alias ifp $cwd/interp/ifp # Normally the user would type in the following two lines: cd fproot/demo ifp # The interpreter will respond with the prompt "ifp>" when ready for # user input. SHAR_EOF chmod +x 'RunIFP' if test ! -d 'fproot' then mkdir 'fproot' fi cd 'fproot' if test ! -d 'demo' then mkdir 'demo' fi cd 'demo' if test -f '%IMPORT' then echo shar: over-writing existing file "'%IMPORT'" fi cat << \SHAR_EOF > '%IMPORT' FROM /sys IMPORT apndl,apndr,apply,assoc,cat,distl,distr,dropl,dropr,explode,id,implode, iota,length,patom,pick,repeat,reverse,takel,taker,tl,tlr,trans; FROM /math/arith IMPORT +,-,*,%,add1,arccos,arcsin,arctan,cos,div,exp,ln, max,min,mod,minus,power,prod,sin,sqrt,sub1,sum,tan; FROM /math/logic IMPORT <,<=,=,~=,>=,>,~,and,all,any,atom,boolean,false,longer,member,null, numeric,odd,or,pair,shorter,xor; SHAR_EOF if test -f 'A' then echo shar: over-writing existing file "'A'" fi cat << \SHAR_EOF > 'A' DEF A AS #<<1 2 3> <4 5 6> <7 8 9>>; SHAR_EOF if test -f 'Abs' then echo shar: over-writing existing file "'Abs'" fi cat << \SHAR_EOF > 'Abs' (* Absolute value function *) DEF Abs AS IF [id,#0] | < THEN minus ELSE id END; SHAR_EOF if test -f 'B' then echo shar: over-writing existing file "'B'" fi cat << \SHAR_EOF > 'B' (* * A data matrix. *) DEF B AS #<5 3 88 6 21 0 0 -7 5 2 1 4 8 10 1 4 2 4 3 7 9 5 2 5 1 3 3 5 7 2 3 6 4 7 5 3 1 8 4 7 8 9 7 1 6 12 5 8 10 5 2 8 12 1 6 9 1 2 3 4 5 6 1 2 4 5 6 7 8 9 2 1>; SHAR_EOF if test -f 'Cart' then echo shar: over-writing existing file "'Cart'" fi cat << \SHAR_EOF > 'Cart' (* * Cartesian product of two sequences *) DEF Cart AS distr | EACH distl END; SHAR_EOF if test -f 'CosSin' then echo shar: over-writing existing file "'CosSin'" fi cat << \SHAR_EOF > 'CosSin' (* * CosSin * * Compute the sine and cosine of an angle via half-angle formulae. * The function is accurate to 12 decimals. *) DEF CosSin AS IF [id|Abs,#1e-6]|< THEN [[#1,[Square,#2]|%]|-,id] ELSE [id,#2]|% | CosSin | [[+,-]|*, [*,*]|+] END; SHAR_EOF if test -f 'Data' then echo shar: over-writing existing file "'Data'" fi cat << \SHAR_EOF > 'Data' (* * Currently I/O is almost non-existent in IFP. One way to skirt this problem * when you have a large amount of data to input is to define a constant * function with the appropriate values. * * The function Data returns a sequence of data values. We could, for * instance, sort them by composing Data with QuickSort * * Examples: * 0 : Data -> <5 3 88 6 21 0 -7> * 0 : Data | QuickSort -> <-7 0 3 5 6 21 88> *) DEF Data AS #<5 3 88 6 21 0 -7>; SHAR_EOF if test -f 'Debug' then echo shar: over-writing existing file "'Debug'" fi cat << \SHAR_EOF > 'Debug' (* * Version of Fib with debugging output * * n : Debug -> sequence of first n Fibonacci numbers * * The two functions created with the "@" form print their inputs * so we can see what is going on inside the Debug function. *) DEF Debug AS IF [id,#2] | <= THEN @"trivial case" | [#<1 1>,id] | takel ELSE @"recurse" | sub1 | Debug | [id, [1r,2r]|+] | apndr END; SHAR_EOF if test -f 'Double' then echo shar: over-writing existing file "'Double'" fi cat << \SHAR_EOF > 'Double' (* Double a number - e.g. 3:Double -> 6 *) DEF Double AS [id,id]|+; SHAR_EOF if test -f 'Fib' then echo shar: over-writing existing file "'Fib'" fi cat << \SHAR_EOF > 'Fib' (* * Compute nth fibonacci number * * Examples: * * 6 : Fib -> 8 * 7 : Fib -> 13 * 8 : Fib -> 21 *) DEF Fib AS IF [id,#2] | < THEN id ELSE sub1 | [Fib,sub1|Fib] | + END; SHAR_EOF if test -f 'FibSeq' then echo shar: over-writing existing file "'FibSeq'" fi cat << \SHAR_EOF > 'FibSeq' (* * Fibonacci numbers * * n : FibSeq -> sequence of first n Fibonacci numbers * * Example * 6 : FibSeq -> <1 1 2 3 5 8> *) DEF FibSeq AS IF [id,#2] | <= THEN [#<1 1>,id] | takel (* trivial case *) ELSE sub1 | FibSeq | (* generate n-1 Fibonacci numbers *) [id, [1r,2r]|+] | apndr (* append sum of last two to end of list *) END; SHAR_EOF if test -f 'Format' then echo shar: over-writing existing file "'Format'" fi cat << \SHAR_EOF > 'Format' DEF Format AS [id,#" "] | distr | cat | implode; SHAR_EOF if test -f 'Hanoi' then echo shar: over-writing existing file "'Hanoi'" fi cat << \SHAR_EOF > 'Hanoi' (* * Hanio - towers of Hanoi solver * * <N Names> : Hanoi -> <<src dst> ...<src dst>> * * where N is number of rings and names is a triple of post names * <source temporary dest>. * * Example: * <2 <a b c>> : Hanoi -> <<a,b>,<a,c>,<b,c>> *) DEF Hanoi AS {[n,[a,b,c]] := id} IF [n,#0]|= THEN [] ELSE [ [n|sub1, [a,c,b]] | Hanoi, [[a,c]], [n|sub1, [b,a,c]] | Hanoi ] | cat END; SHAR_EOF if test -f 'Inner' then echo shar: over-writing existing file "'Inner'" fi cat << \SHAR_EOF > 'Inner' (* * Compute the inner product of two vectors. *) DEF Inner AS trans | EACH * END | INSERT + END; SHAR_EOF if test -f 'InsertSort' then echo shar: over-writing existing file "'InsertSort'" fi cat << \SHAR_EOF > 'InsertSort' (* * InsertSort * * This function sorts a sequence of numbers or strings into ascending order * using insertion sort. * * Examples: * * <3 1 4 1 5 9 2> : InsertSort == <1 1 2 3 4 5 9> * * <all work and no play> : InsertSort == <all and no play work> * * The sequence may not mix strings and numbers. *) DEF InsertSort AS IF null THEN id (* Check for trivial case *) ELSE [tl,[1]] | apndr | INSERT {[Element,Seq] := id} {[Left,Right] := [Seq, distl | FILTER > END | length] | [takel,dropl]} [Left,[Element],Right] | cat END END; SHAR_EOF if test -f 'Inter' then echo shar: over-writing existing file "'Inter'" fi cat << \SHAR_EOF > 'Inter' (* * Set intersection: [A,B] : Inter -> elements of B which are in A * * Example: * <<2 3 4> <5 3 2 1>> : Inter -> <3 2> *) DEF Inter AS distl | FILTER member END | EACH 2 END; SHAR_EOF if test -f 'MatMul' then echo shar: over-writing existing file "'MatMul'" fi cat << \SHAR_EOF > 'MatMul' (* * MatMul * * [matrixA,matrixB] -> matrixAB *) DEF MatMul AS {[A,B] := id} [A,B|trans] | distr | EACH distl | EACH Inner END END; SHAR_EOF if test -f 'Member' then echo shar: over-writing existing file "'Member'" fi cat << \SHAR_EOF > 'Member' (* * <S e> : Member -> #t if e is in sequence S, #f otherwise * * Examples: * <<a b c d> c> -> t * <<2 4 6 8> 3> -> f *) DEF Member AS distr | EACH = END | any; SHAR_EOF if test -f 'Merge' then echo shar: over-writing existing file "'Merge'" fi cat << \SHAR_EOF > 'Merge' (* * Merge * * Merge two ascending sequences. * * The sequences should not mix strings and numbers. * * Example: * * <<a b x z> <c d z>> : Merge -> <a b c d x y z> *) DEF Merge AS IF EACH null END | or THEN cat ELSE IF EACH 1 END | > THEN reverse ELSE id END | [1|1,[1|tl,2]|Merge] | apndl END; SHAR_EOF if test -f 'MergeSort' then echo shar: over-writing existing file "'MergeSort'" fi cat << \SHAR_EOF > 'MergeSort' (* * MergeSort * * This function sorts a sequence of numbers or strings into ascending order * using merge sort. * * Examples: * * <3 1 4 1 5 9 2> : MergeSort == <1 1 2 3 4 5 9> * * <all work and no play> : MergeSort == <all and no play work> * * The sequence may not mix strings and numbers. *) DEF MergeSort AS IF [length,#2] | < THEN id ELSE [id, [length,#2] | div] | [takel,dropl] | EACH MergeSort END | Merge END; SHAR_EOF if test -f 'Outer' then echo shar: over-writing existing file "'Outer'" fi cat << \SHAR_EOF > 'Outer' (* * Outer product of two vectors *) DEF Outer AS Cart | EACH EACH * END END; SHAR_EOF if test -f 'PasTri' then echo shar: over-writing existing file "'PasTri'" fi cat << \SHAR_EOF > 'PasTri' (* * Pascal's triangle generator * * n : PasTri -> first n rows of Pascal's triangle * * Example * 5 : PasTri -> < * <1> * <1 1> * <1 2 1> * <1 3 3 1> * <1 4 6 4 1> * > *) DEF PasTri AS IF [id,#0] | <= THEN #<<1>> ELSE sub1 | PasTri | (* Create triangle with n-1 rows *) [ id, 1r | (* Take last row of smaller triangle *) [ [#0,id] | apndl, (* Append 0 to left edge of row *) [id,#0] | apndr (* Append 0 to right edge of row *) ] | trans | EACH + END (* Add corresponding elements *) ] | apndr (* Append new row to smaller triangle *) END; SHAR_EOF if test -f 'Permute' then echo shar: over-writing existing file "'Permute'" fi cat << \SHAR_EOF > 'Permute' DEF Permute AS IF null THEN #<<>> ELSE [id,length|iota] | distl | EACH [pick,[takel|tlr,dropl]|cat|Permute] | distl | EACH apndl END END | cat END; SHAR_EOF if test -f 'PigLatin' then echo shar: over-writing existing file "'PigLatin'" fi cat << \SHAR_EOF > 'PigLatin' (* * Convert sequence of words to pig-latin * * E.g. * <Have a nice day> : PigLatin -> <aveHay a icenay ayday> * * The text processing is done via explode and implode. * `explode' converts a string into a sequence of characters (1 letter strings), * `implode' catenates a sequence of strings into a single string. * * Coded by Kevin Kenny and Arch Robison *) DEF PigLatin AS EACH explode | IF EACH Vowel END | any | ~ THEN id (* Not a word, don't mangle it *) ELSE IF 1|Vowel|~ THEN (* Word begins with a consonant - rotate first vowel to front. *) WHILE 1|Vowel|~ DO [tl,1]|apndr END ELSIF [1r|Vowel, [#<y Y>,1r]|member] | or THEN (* Word ends in vowel or 'y' - append a 'w' *) [id,#w] | apndr ELSE id END | [id,#<a y>] | cat END | implode END; SHAR_EOF if test -f 'PowerSet' then echo shar: over-writing existing file "'PowerSet'" fi cat << \SHAR_EOF > 'PowerSet' (* * PowerSet * * This function generates all subsets of a given set. Sets are * represented as sequences of distinct elements. * * Examples: * * <> : PowerSet -> <<>> * * <a b c> : PowerSet -> <<a,b,c>,<a,b>,<a,c>,<a>,<b,c>,<b>,<c>,<>> *) DEF PowerSet AS IF null THEN [id] ELSE [1, tl | PowerSet] | [ distl | EACH apndl END, 2 ] | cat END; SHAR_EOF if test -f 'QuickSort' then echo shar: over-writing existing file "'QuickSort'" fi cat << \SHAR_EOF > 'QuickSort' (* * QuickSort * * This function sorts a sequence of numbers or strings into ascending order * using the Quicksort algorithm. * * Examples: * * <3 1 4 1 5 9 2> : QuickSort == <1 1 2 3 4 5 9> * * <all work and no play> : QuickSort == <all and no play work> * * The sequence may not mix strings and numbers. *) DEF QuickSort AS IF [length,#2] | < THEN id ELSE [id,1] | distr | [ FILTER < END | EACH 1 END | QuickSort, FILTER = END | EACH 1 END, FILTER > END | EACH 1 END | QuickSort ] | cat END; SHAR_EOF if test -f 'SelSort' then echo shar: over-writing existing file "'SelSort'" fi cat << \SHAR_EOF > 'SelSort' (* * Selection sort * * Example: * * <3 1 4 1 5 9 2> : SelSort == <1 1 2 3 4 5 9> * * The sequence must be numeric. *) DEF SelSort AS IF [length,#2] | < THEN id ELSE [INSERT min END,id] | distl | [ FILTER = END | EACH 2 END, FILTER ~= END | EACH 2 END | SelSort ] | cat END; SHAR_EOF if test -f 'SlowSort' then echo shar: over-writing existing file "'SlowSort'" fi cat << \SHAR_EOF > 'SlowSort' (* * SlowSort * * Sort a sequence the hard way, i.e. take all permutations * and pick one for which all elements are in order. *) DEF SlowSort AS Permute | FILTER [tl,tlr]|trans | EACH >= END | all END | 1; SHAR_EOF if test -f 'Square' then echo shar: over-writing existing file "'Square'" fi cat << \SHAR_EOF > 'Square' (* Square a number - e.g. 3:Square -> 9 *) DEF Square AS [id,id]|*; SHAR_EOF if test -f 'Tangent' then echo shar: over-writing existing file "'Tangent'" fi cat << \SHAR_EOF > 'Tangent' (* Trigonometric tangent function *) DEF Tangent AS [sin,cos]|%; SHAR_EOF if test -f 'Text' then echo shar: over-writing existing file "'Text'" fi cat << \SHAR_EOF > 'Text' (* * Text * * Example piece of text for use with PigLatin function. * * Example: * * 0 : Text | PigLatin -> ... *) DEF Text AS #<All work and no play makes Jack a dull boy>; SHAR_EOF if test -f 'Vowel' then echo shar: over-writing existing file "'Vowel'" fi cat << \SHAR_EOF > 'Vowel' (* * Determine if a letter is a vowel. * * E.g. * A : Vowel -> t * u : Vowel -> t * R : Vowel -> f * * This function is used by function PigLatin. *) DEF Vowel AS [#<a e i o u A E I O U>, id] | member; SHAR_EOF if test -f 'cotan' then echo shar: over-writing existing file "'cotan'" fi cat << \SHAR_EOF > 'cotan' (* * Trigonmetric cotangent function *) DEF cotan AS [cos,sin] | %; SHAR_EOF if test -f 'Euler' then echo shar: over-writing existing file "'Euler'" fi cat << \SHAR_EOF > 'Euler' (* * Compute Euler's phi-function, i.e. number of number rel. prime to n. * * E.g. 8:Euler -> 4 since 1,3,5,7 are relatively prime to 8 *) DEF Euler AS [id,iota] | distl | EACH WHILE [2,#0]|> DO [2,mod] END | IF [1, #1]|= THEN #1 ELSE #0 END END | sum; SHAR_EOF if test -f '%DOC' then echo shar: over-writing existing file "'%DOC'" fi cat << \SHAR_EOF > '%DOC' This directory contains demonstration functions. To use one, enter the IFP command show input : function ; where input is an appropriate object and function is one of the functions below: Abs - absolute value of a number cotan - find trigonometric cotangent of angle expressed in radians Debug - version of Fib with debugging messages Double - double a number Euler - Euler totient (phi) function Fib - find first n fibonacci numbers Inner - find inner product of two vectors Inter - set intersection Member - set membership PigLatin - converts sequence of words to Pig Latin PasTri - find first n rows of Pascal's triangle QuickSort - sort a sequence of numbers or sequence of strings Square - square a number Vowel - determine if a string is a vowel All IFP primitives are imported into this directory also, so you can experiment with them. Look in %IMPORT for their names. The functions are detailed in the file \IFP.TXT SHAR_EOF cd .. if test ! -d 'math' then mkdir 'math' fi cd 'math' if test ! -d 'arith' then mkdir 'arith' fi cd 'arith' if test -f 'prod' then echo shar: over-writing existing file "'prod'" fi cat << \SHAR_EOF > 'prod' (* * prod * * Compute product of sequence. * * E.g. <10 2 3 4> : prod -> 240 *) DEF prod AS IF ../logic/null THEN #1 ELSE INSERT * END END; SHAR_EOF cd .. if test ! -d 'linear' then mkdir 'linear' fi cd 'linear' if test -f '%IMPORT' then echo shar: over-writing existing file "'%IMPORT'" fi cat << \SHAR_EOF > '%IMPORT' FROM /sys IMPORT apndl,apndr,cat,distr,distl,id,iota,length,tl,trans; FROM /math/arith IMPORT +,-,*,%,exp,ln,sum; FROM /math/logic IMPORT =,null; SHAR_EOF if test -f 'A' then echo shar: over-writing existing file "'A'" fi cat << \SHAR_EOF > 'A' (* Test case generator for L and U - check by trying A | [L,U] | MatMul *) DEF A AS #< < 2.3 4.7 -2.7 5.7 7.4 2.1 12.7 1.1 32.1 4.5 1.1 8.3> < 1.7 -1.7 5.2 3.2 1.2 3.5 2.4 2.9 1.9 1.7 -4.5 -9.9> < 6.1 3.4 1.2 10.6 2.9 1.7 1.1 -0.3 1.2 3.2 1.6 1.3> <23.3 -9.7 2.4 5.2 7.6 1.1 86.2 1.7 3.2 9.7 1.2 87.1> < 1.2 3.4 4.5 6.7 9.8 0.1 2.1 5.7 -9.1 -5.2 0.2 1.7> <12.3 1.2 8.7 12.3 -4.7 -.1 3.2 2.1 4.3 1.8 1.9 2.3> < 5.7 4.7 -2.8 5.7 7.4 2.1 12.7 1.1 32.1 4.5 1.1 8.3> < 1.7 -6.7 5.6 7.4 1.2 3.5 2.7 2.8 1.9 1.7 -4.5 -9.9> < 3.1 -3.4 -9.2 10.6 8.9 1.7 -1.1 -0.3 3.2 3.2 1.6 1.3> <13.3 -9.7 5.2 7.6 1.1 86.2 1.3 3.2 9.7 1.2 87.1 -9.2> < 1.2 3.4 -4.5 -6.7 9.8 0.1 -2.1 5.8 -9.1 -5.2 0.2 1.7> <12.3 1.2 -8.7 12.3 -4.7 -.1 -3.2 1.8 1.9 2.3 3.1 4.3> >; SHAR_EOF if test -f 'Aik' then echo shar: over-writing existing file "'Aik'" fi cat << \SHAR_EOF > 'Aik' (* Tail of matrix after gaussian elimination on (1|1) *) DEF Aik AS [ MatTail, [Li1|tl,U1k|tl] | Outer ] | MatSub; SHAR_EOF if test -f 'ApndlCol' then echo shar: over-writing existing file "'ApndlCol'" fi cat << \SHAR_EOF > 'ApndlCol' (* Append column (1) to left side of matrix (2) *) DEF ApndlCol AS [1,2|trans] | apndl | trans; SHAR_EOF if test -f 'ApndrCol' then echo shar: over-writing existing file "'ApndrCol'" fi cat << \SHAR_EOF > 'ApndrCol' (* Append column (2) to right side of matrix (1) *) DEF ApndrCol [1|trans,2] | apndr | trans; SHAR_EOF if test -f 'MatTail' then echo shar: over-writing existing file "'MatTail'" fi cat << \SHAR_EOF > 'MatTail' (* Deletes first row and column of matrix *) DEF MatTail AS tl | EACH tl END; SHAR_EOF if test -f 'Outer' then echo shar: over-writing existing file "'Outer'" fi cat << \SHAR_EOF > 'Outer' (* Outer product of two vectors *) DEF Outer AS Cart | EACH EACH * END END; SHAR_EOF if test -f '%DOC' then echo shar: over-writing existing file "'%DOC'" fi cat << \SHAR_EOF > '%DOC' This directory contains functions for linear matrix manipulation. In particular, it contains L and U, which take the lower and upper parts of the LU decomposition of a matrix. SHAR_EOF if test -f 'Singleton' then echo shar: over-writing existing file "'Singleton'" fi cat << \SHAR_EOF > 'Singleton' (* Check if matrix is a singleton *) DEF Singleton AS [length,#1]|=; SHAR_EOF if test -f 'U' then echo shar: over-writing existing file "'U'" fi cat << \SHAR_EOF > 'U' (* U part of LU decomposition of matrix *) DEF U AS IF Singleton THEN id ELSE [ U1k, Aik | [EACH #0 END,U] | ApndlCol ] | apndl END; SHAR_EOF if test -f 'U1k' then echo shar: over-writing existing file "'U1k'" fi cat << \SHAR_EOF > 'U1k' (* First row of U part *) DEF U1k AS 1; SHAR_EOF if test -f 'Cart' then echo shar: over-writing existing file "'Cart'" fi cat << \SHAR_EOF > 'Cart' (* Cartesian product of two vectors *) DEF Cart AS distr | EACH distl END; SHAR_EOF if test -f 'Inner' then echo shar: over-writing existing file "'Inner'" fi cat << \SHAR_EOF > 'Inner' (* Inner product *) DEF Inner AS trans | EACH * END | IF null THEN #0 ELSE INSERT + END END; SHAR_EOF if test -f 'L' then echo shar: over-writing existing file "'L'" fi cat << \SHAR_EOF > 'L' (* L part of LU decomposition of matrix *) DEF L AS IF Singleton THEN #<<1.0>> ELSE [ Li1, Aik | [EACH #0 END,L] | apndl ] | ApndlCol END; SHAR_EOF if test -f 'LU' then echo shar: over-writing existing file "'LU'" fi cat << \SHAR_EOF > 'LU' (* * LU * * [L,U] decomposition of matrix written as single function. * This function is functionally identical to [L,U] *) DEF LU AS IF Singleton THEN [#<<1.0>>,id] (* definition of L *) ELSE [ Li1, Aik | [EACH #0 END,LU], U1k ] | [ [ 1, 2 | [1,2|1] | apndl ] | ApndlCol, [ 3, 2 | [1,2|2] | ApndlCol ] | apndl ] END; SHAR_EOF if test -f 'Li1' then echo shar: over-writing existing file "'Li1'" fi cat << \SHAR_EOF > 'Li1' (* First column of L part *) DEF Li1 AS [EACH 1 END,1|1] | distr | EACH % END; SHAR_EOF if test -f 'MatAdd' then echo shar: over-writing existing file "'MatAdd'" fi cat << \SHAR_EOF > 'MatAdd' (* Matrix addition *) DEF MatAdd AS MatCat | EACH EACH + END END; SHAR_EOF if test -f 'MatCat' then echo shar: over-writing existing file "'MatCat'" fi cat << \SHAR_EOF > 'MatCat' (* Converts pair of matrices to matrix of pairs *) DEF MatCat AS trans | EACH trans END; SHAR_EOF if test -f 'MatMul' then echo shar: over-writing existing file "'MatMul'" fi cat << \SHAR_EOF > 'MatMul' DEF MatMul AS [1,2|trans] | distr | EACH distl | EACH Inner END END; SHAR_EOF if test -f 'MatSub' then echo shar: over-writing existing file "'MatSub'" fi cat << \SHAR_EOF > 'MatSub' (* Matrix subtraction *) DEF MatSub AS MatCat | EACH EACH - END END; SHAR_EOF if test -f 'VecAdd' then echo shar: over-writing existing file "'VecAdd'" fi cat << \SHAR_EOF > 'VecAdd' (* Vector addition *) DEF VecAdd AS trans | EACH + END; SHAR_EOF if test -f 'VecSub' then echo shar: over-writing existing file "'VecSub'" fi cat << \SHAR_EOF > 'VecSub' (* Vector subtraction *) DEF VecSub AS trans | EACH - END; SHAR_EOF cd .. cd .. cd .. # End of shell archive exit 0 -- Rich $alz "Anger is an energy" Cronus Project, BBN Labs rsalz@pineapple.bbn.com Moderator, comp.sources.unix sources@uunet.uu.net