.help VOPS Feb83 "Vector Primitives" .sh Introduction The vector primitives are abstract machine instructions which operate on vectors. The "a" prefixed operators are for one dimensional arrays, and the "m" prefixed operators are for two dimensional arrays (matrices). Each generic instruction is implemented as a set of operators, one for each data type. There are no vector primitives for the type BOOL. If a "b" suffix is given, the vector primitive is understood to operate on unsigned machine bytes. The "u" suffix is used for the special type unsigned short integer. The binary operators ("c = a op b") come in two forms. If the regular three character instruction mnemonic is used, the B operand must be vector. If the letter "k" is added to the mnemonic, the B operand must be a constant. These dual mode operators are flagged (with "(k)") in the table below. .nf Instruction Operation Data Types cht__ b = a (change datatype) UBcsilrdx clr_ fill a with zeros csilrdx mov_ (k) b = a (copy vector) csilrdx abs_ b = abs(a) silrdx log_ b = log10(a) silrdx lln_ b = natural_log(a) silrdx sqr_ b = sqrt(a) silrdx srt_ b = sort(a) csilrdx neg_ b = -a silrdx map_ b = (a + k1) * k2 silrdx map_B b = (a + k1) * k2 silrdx lut_ b = lut[a] (lookup table) csil lui_ b = interp (a, x) silrd rep_ a = newval if (low<=a<=high) csilrdx add_ (k) c = a + b silrdx sub_ (k) c = a - b silrdx mul_ (k) c = a * b silrdx div_ (k) c = a / b silrdx min_ (k) c = min(a,b) silrd max_ (k) c = max(a,b) silrd mod_ (k) c = mod(a,b) silrd pow_ (k) c = a ** int_pwr silrdx exp_ (k) c = a ** real_pwr silrdx not_ b = !a sil and_ (k) c = and(a,b) sil bor_ (k) c = or(a,b) sil xor_ (k) c = xor(a,b) sil .tp 4 other vector primitives: lim_ ngpix = lim_ (a, npix; minval, maxval) silrdx win_ nrej = win_ (a, npix, lcut, hcut) silrdx avg_ ngpix = avg_ (a, npix; mean, sigma) silrdx rav_ ngpix = rav_ (a, npix; mean, sigma; ksig) silrdx ? med_ ngpix = med_ (a, ia, npix; median) silrd .fi For example, "aaddr(a,b,c,npix)" would add the two REAL vectors A and B, of length NPIX, placing the sum in the vector C. To add a constant K to the vector A, "aaddkr(a,k,c,npix)" would be used. The sequence "aclrb(a,nbytes)" would zero NBYTES machine bytes, starting at location A. .sh Preprocessing Generic Operators A preprocessor is provided to convert a generic operator into a set of type specific operators. By coding only generic operators, the programmer only has to maintain a single piece of code, reducing the possibility of an error, and greatly reducing the amount of work. The GENERIC preprocessor takes as input files written in either the IRAF preprocessor language or C (or any other language which provides macro definitions), with embedded preprocessor directives and keywords. .sh Usage The calling sequence for the preprocessor (on the UNIX system) is as follows: generic [-t types] [-p prefix] [-o outfile] file [file...] Any number of files may be processed. .sh Flags The following (optional) flags are provided to control the types and names of the generated files: .ls 8 .ls 8 -t Used to specify the datatypes of the files to be produced. The default value is "silrdx", meaning types SHORT through COMPLEX. Other possible types are "BU", i.e., unsigned byte and unsigned short. The generic preprocessor does not support type boolean. .le .ls -p An optional prefix string to be added to each file name generated. Provided to make it convenient to place all generated files in a subdirectory. If the name of the file(s) being preprocessed is "aadd.x", and the prefix is "d/", the names of the generated files will be "d/aadds.x", "d/aaddi.x", "d/aaddl.x", and so on. .le .ls -o If an output filename is specified with the -o flag, only a single input file may be processed. Any "$t" sequences embedded in the output file name will be replaced by the type "suffix" character to generate the filenames of the type specific files in the generic family. If no $t sequence is given, the type suffix is appended to the filename. If no -o output filename is given, the names of the output files are formed by concatenating the type suffix to the root of the input filename. .le .le .sh Directives The action of the preprocessor is directed by placing "$xxx" directives in the text to be processed. The identifiers INDEF and PIXEL are also known to the preprocessor, and will be replaced by their type specific equivalents (INDEF --> INDEFS, INDEFI, etc., PIXEL --> short, int, real, etc.) in the generated text. Comments (#... and /* ... */), quoted strings (".."), and escaped lines (^%) are passed on unchanged. .ls 4 .ls 20 $/text/ The text enclosed by the matching slashes is passed through unchanged. .le .ls $t The lowercase value of the current type suffix character (one of [bucsilrdx]). .le .ls $T The uppercase value of the current type suffix character (one of [BUCSILRDX]). .le .ls digits$f Replaced by "digits.0" if the current type is REAL, by "digits.0D0" if the current type is DOUBLE, by "(digits,digits)" if the type is complex, or by "digits" for all other datatypes. .le .ls $if Conditional compilation. Two forms of the $if statment are implemented: .nf $if (datatype == ) $if (datatype != ) or $if (sizeof() sizeof()) .fi where , , and are type suffix characters ("silrd", etc.), and where is one of the relational operators == != <= < >= > Nesting is permitted. Conditional statements need not be left justified, i.e., whitespace may be placed between BOL and a $xx preprocessor directive. .le .ls $$if Replaced by "$if". Not evaluated until the second time the file is processed. .le .ls $else, $$else Begins a section of code which gets processed if the $if condition was false. .le .ls $endif, $$endif Terminates a $if or $else construct. .le .ls TY_PIXEL Replaced by TY_INT, TY_REAL, and so on. .le .ls SZ_PIXEL Replaced by SZ_INT, SZ_REAL, and so on. .le .ls PIXEL Replaced by the datatype keyword of the file currently being generated (int, real, etc.). .le .ls XPIXEL Replaced by the defined type (XCHAR, XINT, ect.). Used in generic C programs which will be called from the subset preprocessor, and which must manipulate the subset pp datatypes. .le .ls $PIXEL Replaced by the string "PIXEL" (used to postpone substitution until the next pass). .le .ls INDEF Replaced by the INDEF parameter for the current datatype (INDEFS, INDEFI, INDEFL, INDEF, or INDEFX). .le .ls $INDEF Replaced by the string "INDEF". .le .le .sh Example The following generic operator computes the square root of a vector. The members of the generic family would be called "asqrs", "asqri", and so on. .ks .nf # ASQR -- Compute the square root of a vector (generic) procedure asqr$t (a, b, npix) PIXEL a[npix], b[npix] int npix, i begin do i = 1, npix { if (a[i] < 0$f || a[i] == INDEF) b[i] = INDEF else { $if (datatype != rdx) b[i] = sqrt(double(a[i])) $else b[i] = sqrt(a[i]) $endif } } end .fi .ke .sh Doubly Generic Operators The preprocessor can also be used to generate doubly generic operators (operators which have two type suffixes). A good example is the type conversion operator ACHTxy, which converts a vector of type X to a vector of type Y. If there are seven datatypes (csilrdx), this generic family will consist of 49 members. Doubly generic programs are preprocessed once to expand the first suffix, then each file generated by the first pass is processed to expand the second suffix. On the UNIX sytstem, this might be done by a command such as .nf generic acht.x; generic -p dir/ acht[silrd].x rm acht[silrd].x .fi This would expand "acht" in the current directory (generating 5 files), then expand each of the "acht$t" files in the subdirectory "dir/", creating a total of 25 files in the subdirectory. The final command removes the 5 intermediate files.