home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_progs
/
educ
/
schoonsc.lzh
/
Schoonschip
/
SDocsAMI.LZH
/
SDocsAMI
/
Schipman.e
< prev
next >
Wrap
Text File
|
1991-06-14
|
213KB
|
5,522 lines
SCHOONSCHIP (*)
A Program For Symbol Handling.
M. Veltman
0. DIFFERENCES WITH OLDER VERSIONS
1. INTRODUCTION
2. BASICS
3. INPUT FACILITIES
4. TYPE DEFINITION
5. X, D AND T EXPRESSIONS
6. FILES
7. PRINT OPTIONS
8. END LINE OPTIONS
9. SUBSTITUTIONS
10. PATTERNS
11. CONDITIONAL SUBSTITUTIONS
12. COMMANDS
13. PARTICLE PHYSICS
14. INTERNAL PROCEDURES
15. CHARACTER SUMMATION
16. GAMMA ALGEBRA
17. R-INPUT
18. STATEMENTS. CONDITIONAL INPUT READING.
19. LARGE PROBLEM HANDLING
20. FILE HANDLING COMMANDS
21. SUMMARY
APPENDIX A. COMMAND LINE OPTIONS
APPENDIX B. COMPATIBILITY
First version: January 1964.
Current version: June 1991.
*) Copyright (C) 1991 by Martinus J. G. Veltman. This version of the
Schoonschip manual may be freely copied on a not-for-profit basis. All rights
to other versions of the Schoonschip manual are reserved.
A more extensive, printed manual and updated information are available from:
David N. Williams
1238 Westport
Ann Arbor, MI 48103
Email: 75706.3124@CompuServe.com
0. DIFFERENCES WITH OLDER VERSIONS.
This version of Schoonschip (Jan 1, 1989) differs considerably from the
previous versions. Every effort has been made to avoid changing code
that has been shown to work correctly, and also upward compatibility
was considered very important. To be able to run known problems and to
compare the results is an invaluable and very unique part of Schoonschip.
In this way 25 years of experience are still very much part of this
version.
Modern users tackle ever larger problems, and improvement of Schoonschip
with respect to handling large problems was a high priority. There are
several aspects to this situation. First, new methods to present and
formulate a problem had to be considered. This has led to the introduction
of a new concept, namely character summation. This allows very efficient
generation of diagrams. As yet the main application seems to be high energy
physics, but the concept appears to be of larger generality. More specific
to high energy physics is gamma matrix algebra. Efficient methods to deal
with gamma matrices in other then four dimensions have been incorporated.
This allows application of dimensional regularization to problems with
fermions.
Another important tool in handling large problems is the Freeze command.
It existed in CDC versions of Schoonschip, and has now been implemented
also in this version.
Last but not least the output sorting methods of Schoonschip have been
vastly improved. The previous versions tended to generate very large
disk files and consequently were quite time consuming. This seriously
limited the magnitude of the problems that could be treated, especially
on relatively small systems (PC's). It must be well understood: in
principle there is no reason why Schoonschip should not run equally well
on PC's as compared to mainframes. Of course, there is a difference
due to the different CPU speeds, but that is often more then compensated
by the fact that mainframes usually must deal with a multitude of users. And
disk file handling is not necessarily slower on a PC. The main difference
is that mainframes have essentially infinite disk space, but that advantage
is rapidly disappearing as larger and larger disk systems become available
to PC users. Right now the standard is about 20 Mb, but there are already
very good and inexpensive systems with capacities in the 100 Mb range.
The new sorting methods give an improvement of one or two orders of
magnitude in time and disk space for large problems (producing more then
1 Mb of disk files). Of course, 'reasonable' default parameters are
build in, but for truly large problems things must be tailored to the
specifics of the problem. It is suggested that the section on large
files is read at least once, such as to give an idea of the situation;
if the need arises one can go back and get the details.
Several new statements and commands have been implemented. Some of them
replace older, more cumbersome forms. New statements:
Anti
Beep
Directory
Digits
Dostop
Dryrun
External
Fortran
Freeze
Large
Maximum
Overflow
Precision
Progress
Rationalize
Round
Silence
Showl
Synonym
Nshow
Traditional
Conditional input reading statements:
Goto
Gotoif
Gotoifn
New commands:
Absol
Anti
All
Beep
Dostop
Expand
Extern
Gammas (=old Trick,Trace)
Iall
Ndotpr
Order
Print
Stats
Slight modification:
Integ on CDC versions of Schoonschip truncated the numbers. Later versions
rounded to nearest integer. The truncation has been re-instated, but
the statement 'Round on' may be used to obtain rounding to nearest integer.
B list may now have vector names. All dot-products or vector components
relating to that vector are factored out.
In addition the Exclusive option is now available. If the first
argument in the B-list is the keyword Excl then the subsequent
names will be the only quantities that will be factored out. In this
case function names may appear in this B-list. A function not
mentioned in the list will not be factored out. Thus then functions
may appear inside the brackets in the output.
This Excl option has been provided in connection with the Freeze
command. Here a word of caution: avoid situations where a twice
occurring index becomes 'split', i.e. one appears outside and one
appears inside the brackets. In that case be sure that such an index
is not a created index.
A word of caution: using the Excl option functions may become reordered.
A D function with or without dummy arguments may now appear in the left hand
side of a substitution, although not combined with other factors.
The Count command has been slightly enhanced, allowing multiple counts with
one command.
The Symme and Asymm commands have been slightly enhanced, allowing handling
of groups of arguments.
The Spin command allows now vectors as arguments to identify spinors.
The substitution types
Id,Funct,a=...
Id,Funct,p(mu~)=...
may now have function names inbetween the keyword and the last argument.
Then only those functions are considered. Example:
Id,Funct,Epf,p(mu~) = k(mu) + q(mu)
All statements are summarized in the section on Statements. Commands are
discussed in the section on Commands.
New notation:
Long names containing special symbols such as +, - etc may now be used for
algebraic symbols. They must be enclosed in square brackets. Example:
[a+2/3*b] is seen as a symbol with that name.
Entirely rewritten: section on Conditional substitutions.
new sections are:
Character summation
Gamma algebra
R-input
Statements. Conditional input reading.
Large problem handling
File handling commands
It is suggested that one reads (or tries to read) them at least once, to
have some idea as to what is available.
Schoonschip has not been known to be so-called "user friendly", whatever
that may mean. This concerns error reporting as well as syntax. Some, but not
much has been done on error reporting. While important, and this is well
recognized, it is not considered the highest priority. Concerning the syntax,
a number of improvements has been made.
There are a few minor incompatibilities with older versions. Square brackets
[] now have a new function, and cannot be used any more as regular brackets.
The statements DELETE (for deleting blocks) and Printer (to request for
line printer type output, i.e. longer line length) have been replaced by
Bdelete and Lprinter. This because now no difference is made been between
lower and upper case symbols for commands etc. Also, it has been attempted
to make the commands recognizable by the first few (four at most) characters.
The condition code system has been thoroughly reviewed. Although quite
powerful it was too cumbersome to handle. Instead there is now a system
employing familiar concepts: IF, AND, OR, NOT, ELSE and ENDIF.
The handling of exponents has been modified. Before the addition was circular
through 128 to -128. Now this is no more true. The result will be an overflow
error message that can however be switched off (Overflow off statement).
Further there is a new, alternative, notation for gamma matrices.
Acknowlegements. Thanks are due to Drs. E. Remiddi and J. Vermaseren for
inspiring several of the improvements incorporated in this (and older !)
Schoonschip versions.
1. INTRODUCTION.
Schoonschip is a program written in assembler language intended to help
handling large algebraic expressions. Very little is build-in in the sense of
function properties, or integral tables etc, but it offers many facilities to
operate on expressions. Thus if the user knows the type of integrands that can
occur it is easy to let the program do the actual integrations. Schoonschip
never tries to think for the user, it just makes it possible to use the
computer as a tool when doing algebra.
There are provisions for building up a library of Schoonschip statements.
Blocks of statements, performing well defined operations (such as for example
differentiation or integration) may be defined, stored, and when needed
recalled with a single line. In this way a user can build up to his own needs.
In principle the system works as follows. An expression is given to Schoonschip
and subsequently one gives instructions as to what to do. In first instance
Schoonschip works out the given expression term by term, and next each term
passes a series of levels. At each level the user has an opportunity to work on
that term. The result is collected in an output storage area and identical
terms are added. The result can be handled in a variety of ways: it can be
returned to the input for a new round, or it can be written to disk for later
use, etc. Of course, the result is normally printed as well.
This manual explains the available features by way of examples. Some knowledge
of the way that Schoonschip works is of advantage, and at various points some
details will be given. The manual is meant to be read having at the same type
the file with examples at hand. This file is supposedly named Examples.e. To
see then how example 5 works one types
Schip +5 Examples.e
If the output is larger than one screenful one may also specify an output file,
either by the >fnam option or also by simply giving the name as second
argument:
Schip +5 Examples.e outp
The file outp can then afterwards be inspected.
Below the input text of these examples is reproduced also.
2. BASICS.
The first example shows what is meant by working out the initial expression.
The expression must be given on a line wich has a Z in the first column. The
general convention is that a line with a blank or tab in column one is a
continuation of the previous line.
Now the first example:
Example 1.
Z XX = (a + b)^2
The notation ^ implies exponentiation. Also ** (as in Fortran) may be used. XX
is an invented name that identifies the expression if it is to be re-used, or
written to disk etc. It may be part of another expression in later problems.
All that Schoonschip does now is to work this out to a series of terms: a^2,
a*b, b*a and b^2. Thus if nothing else is done this is what will go to the
output. For algebraic variables (as a and b are taken to be by default)
commutation is assumed, thus a*b is recognized to be the same as b*a. The way
Schoonschip handles this is by rearranging every term, setting symbols in an
internally well defined order. For quantities of the same kind this is
generally the same order as that in which they appear in the input.
At this point no further instructions are given, and the program may proceed to
do this work. To signal that all has been said a line with an * in column one
must be given. The further content of the line instructs Schoonschip what to do
next after this task has been performed. Right now the idea is to go on to
another example, and the word 'begin' leads to this action. After this a, b and
XX are lost.
*begin
For massive expressions it is often desirable to group terms in the output. For
instance, they may be grouped with respect to the variable a and the exponent
whith which it may occur. The way to do this is to give a list of quantities to
be factored out on a line with as first character a B. At most 130 quantities
allowed.
B a
Z XX= (a + b)^2
*end
This is about all control that the user has on the output format. Some
additional facilities concern the way numbers are printed. By default
Schoonschip tries to write every number as a rational fraction, but this is not
always possible. Internally all numbers are represented as floating point
numbers, with a 14 bit exponent and a 96 bit fraction. When printing
Schoonschip tries to convert to a rational, using 70 bits as input. Then the
rational is reconverted to a floating point number, and agreement to 84 bits is
required. If that works the number is printed as a rational, otherwise as an
integer or floating point number depending on the number. If printing as a
floating point number the user has control over the number of decimal digits to
be printed. Also the rationalization procedure can be influenced. This is done
by means one or more of three statements:
Precision #
Rationalization #
Digits #
As often in the Schoonschip syntax only the first three (if no confusion
possible two) characters of these statements are significant, and they may be
in upper or lower case. Thus
PRE #
is acceptable instead of Precision.
The # represent numbers specifying decimal digits. If none is given the default
is used. The number following Digits specifies the number of digits to be
printed for floating point numbers. Default is 5. The number following
Rationalization specifies how many decimal digits should be used (sum of
numerator plus denominator digits) when attempting rationalization. Default is
22. If 0 is specified no rationalization attempt is made. For other then the
default value no check on the remaining digits is done. This may be used to
find a rational approximation for some number.
Numbers are always a problem in symbol handling programs, and the approach
chosen in Schoonschip has come out of many years of trying various
possibilities. As already noted above, every number is put in a floating point
format with a fraction of about 29 decimal digits (96 bits) and 14 bit
exponent. In the course of the calculation one will loose precision and stray
bits will accumulate in the least significant part of the number. Consequently
cancellations will in general not be exact. Schoonschip assumes that two
quantities cancel if 25 decimal digits (80 bits) of the coefficients cancel.
This number can be changed by means of the Precision statement where # is the
desired number of decimal digits. To be precise: 1.E15 + 1 - 1.E15 is 0 if 15
is specified, and is 1 if 16 is given.
The above makes clear to what extend numbers are handled precisely. In general
rationals will be converted properly if the sum of the decimal digits in
numerator and denominator is less than 21.
A number may be given in various ways:
- without exponent or fraction: 1230, 17893
- with fraction: 1.978, 33.127
- with (signed) exponent: 12E13, 178E-17
- with (signed) exponent and fraction: 23.47E15, 18.49E-200
- in hexadecimal notation: 0x10ABC, 0xA4FFF
The latter two are the same as 68284 and 675839. The hexadecimal notation
is actually needed in certain statements (the Directory statement).
Schoonschip will work out multiplications and divisions of numbers directly,
thus 2/3 is immediately converted to 0.6666666...
The effect of the above statements as well as some other features are shown in
the following example. An expression is given, printed, and re-directed to the
input, and new instructions are given. Normally, when re-routing an expression
to the input no output is printed, and one must explicitly asked for that by
means of a line having a P in column one. Schoonschip reproduces such a line
with an additional > sign. The re-direction is by means of the word 'yep' on
the * line. Also the way comments may be given is illustrated. A ! implies
simply end of line, and has no further effect. Also it should be noted that
blanks and tabs are generally ignored (except for their function as first
column character to indicate continuation).
Example 2.
P output !Only the first two characters of 'output' are significant.
Digits 3
Rationalization 3 ! 0 leads to no rationalization attempt.
Z XX=3.14 + 1/3*a1 + 7.1357689E20*a2 !E20 or E+20 implies 10^20.
*yep
Digits !This restores to the default option, 5 digits.
Rationalization !Default: 22 digits, with check.
*end
The *end line implies termination after the problem has been worked out. As
with most Schoonschip input, the * lines are format free, except that the *
must be in column 1. But one may write for example * en d .
3. INPUT FACILITIES.
While little can be done to the output, there is great flexibility concerning
input. Two basic features are available: BLOCK's and DO loops. A block is a set
of lines that may recur with minor variations and that can be called with a
single line. The structure is very much as macro's in assemblers. The DO-loops
are similar to Fortran do-loops.
A block is delimited by two lines. The first line contains the word BLOCK in
columns 1-5 followed by a name followed by arguments separa- ted by comma's and
enclosed in curly brackets. The last line must contain the word ENDBLOCK in
columns 1-8. When calling the block arguments are substituted, provided they
were enclosed in quotation marks in the block definition. A block name may have
1-6 characters.
Example 3.
BLOCK text{xx,yy}
C This argument is substituted in a call: 'xx'.
This not: xx.
Arguments can be glued together: 'xx''yy'.
ENDBLOCK
To call a block simply give the name with the arguments to be
substituted. Be sure to start in column one, and to enclose arguments
in curly brackets. An example of a call:
text{yes,sir}
A block remains known over *begin lines. It can be deleted by means of a line
having the word BDELETE (four, if no confusion possible three characters
significant, lower case accepted also) starting in column 1 followed by the
name of the block to be deleted.
BDELETE text
Blocks are stored on disk in a file called tape9, and recalled as needed.
Schoonschip keeps a list of names in memory. There is a simple way to delete
entire lines when calling a block. A line with the character ~ in column one is
totally ignored by Schoonschip, not even printed. Suppose we want in one case
lines 1 and 2 of a block, and line 3 in another case. Example:
BLOCK lines{A,B}
'A'C line 1
'A' line 2
'B' line 3
ENDBLOCK
Now call the blocks and use ~ to delete lines:
lines{,~}
lines{~,}
Note that an empty argument leads to an empty substitution. Actually if the
final argument(s) are empty it is not even necessary to type comma's. Thus
lines{~} gives the same as the last example.
It may happen that one wants to call a block with some of the arguments
containing a comma. In that case enclose that argument in curly brackets {}.
When substituting Schoonschip peels away the outer layer of curly brackets. For
example, text{{a, b}, and c} leads to:
C This argument is substituted in a call: a, b.
This not: xx.
Arguments can be glued together: a, b and c.
DO-loops are also delimited by two lines. The first line must have DO in
columns 1-2 followed by name=#,#,# . The word 'name' may have (as is generally
the case with names in Schoonschip) up to 6 characters. The three numbers
represent a range of numbers to be substituted for 'name' in the rest of the DO
loop. The first two specify the range, the last the increment. The DO loop is
terminated by a line containing the word ENDDO in columns 1-5. As in the case
of blocks substitution is done if 'name' occurs enclosed in quotation marks:
DO var=1,7,2
P input !Normally only the first DO round is printed.
C value of var: 'var'
ENDDO
The numbers may also take negative values. Schoonschip handles this by
attaching the prefix % to the number, which is interpreted as an intrinsic
minus sign when encountered in front of a number. If it occurs elsewhere this %
sign is part of whatever it occurs with.
DO var=-1,1 !The third number is 1 by default.
P input
C value of var: 'var'.
C This may be part of a name, for example XX'var', or an index,
for example YY(3+'var'). In the last case Schoonschip will interpret
the % sign as minus and correctly work out the number.
ENDDO
The exit of a DO-loop may be forced prematurely at execution time, by means
of the command Dostop (see substitutions and commands). This is a somewhat
tricky affair, due to the fact that DO-loop expansion is strictly on the
input level, while the Dostop command functions during execution, i.e. after
input has been read up to a line with an * in column 1. Thus a Dostop command
will have effect only after such a line. Therefore, normally, a forced exit
should be effected only for DO-loops that have a line with an * as the last
statement.
There exists also a Dostop statement which is effective just before execution.
It serves to preset the Dostop flag, and at execution time the thus forced
DO-exit may be nullified or set. Again, a *-line should be the last before the
ENDDO. The syntax of this statement is:
Dostop on
or
Dostop off
This sets or clears the forced DO-loop exit flag. Both Dostop statement and
command should normally occur within the same DO-loop. The statement should
preferably occur just before the first substitution or command of the set in
which the Dostop command occurs.
Blocks and DO loops may be nested, up to 10 levels deep. As is evident from the
above, all this is strictly on the input level, and just pure character
substitution (apart from the % sign). It is up to the user to make sure that
sensible Schoonschip input results. Use the statements P input and P ninput
to see or to suppress the actually generated text.
Since the same blocks may occur in many different problems it is useful to have
the blocks stored in some file, and to let Schoonschip read them in before
starting on some problem. This is possible, and is in fact not restricted to
blocks. A line with the word Read in columns 1-4 followed by a file name
causes Schoonschip to open that file and read it as normal input. As soon as a
line with the word End in columns 1-3 is encountered Schoonschip switches back
to the normal input file, specified in the call statement. Other files may be
read subsequently, Schoonschip reads all blocks and whatever else, simply
switching input. All blocks read are stored in tape9 and may be used in all
subsequent problems. Restriction: a Read within a Read file is not allowed.
4. TYPE DEFINITION.
In algebraic expressions different types of symbols may occur. The user must
specify beforehand these symbols. The following types may occur: Algebraic
symbols, Indices, Vectors, Functions and Expressions. These are defined on
lines having A I V F or X in column one. Actually there are additional types of
expressions, characterized by D or T in column 1, but we will discuss them
later. Names may have up to six characters, both upper and lower case and
numers allowed, although a name should be distinguishable from a number.
Also the character _ (underscore) may be used in names. If it is not the
first it is not included in the count. The underscore has a function in
certain contexts, to be explained later.
A limited facility is present to handle large names. Sometimes large names
containing other then the characters mentioned may be very useful by way of
mnemonics. Such names can be used, but they must be enclosed in square
brackets. They may contain just about any character except control characters
(such as tab or linefeed) or square brackets themselves. Futhermore they can
only be used for algebraic symbols.
Examples:
Abcd abc_def 12A3 12_ab f1 f2 [a + b/3]
Illegal names:
Abcdefg 12E3
The last name would actually be understood as a number: 12 * 10^3.
Generally, symbols are simple commuting variables that may have an exponent.
Such exponents must be short integers, that is integers in the range -128 to
+127 inclusive. The extreme values are taken in case of overflow, if error
trapping on that has been suppressed with the Overflow statement.
Indices may occur as algebraic variables, but are really meant to be vector
indices, or function arguments.
Functions are non-commuting quantities, with or without arguments. Of course,
if they are commuting that can be handled too. But if they represent matrices
(with or without indices as arguments) then they must be considered as
non-commuting. In short, functions may be used to represent anything that is
not any of the other types of symbols. Whatever calculational rules they obey
must be given by the user.
Vectors are handled according to the standard rules of vector algebra. To
achieve this dot-products may be formed, denoted by a capital D inbetween two
vector names. Thus, if p and q are vectors then pDq denotes the dot-product
between p and q. ASchoonschip follows the usual summation convention that twice
occuring indices imply summation: p(i1)*p(i1) is interpreted by Schoonschip as
pDq. Also the Kronecker delta is available: it is the special function D which
is build-in. Here an example showing various rules:
Example 4.
A a1,a2,a3 !Algebraic symbol list.
F f1,f2,f3 !Functions.
I mu,nu !Indices.
V p,q,k !Vectors.
Z XX = p(mu)*{ a3^-20*a1*q(mu) + a2*a1^7*D(mu,nu)*k(nu)
+ a3*f2(mu,k,q)*f1} !Note the use of {}.
+ q(mu)*{a3*a2*a1 + f3*f2*f1}
*end
Note that functions are always treated as if they are on the B list. Also
vectors not part of a dotproduct are factorized. Note also the re-arrangement
of the symbols a1, a2 and a3, which is not done for functions such as f1, f2
and f3. Note also that Schoonschip pays no attention to the fact that f2
occurred both with and without arguments. As shown curly brackets may be used
instead of the usual brackets, but they must be paired. Also the user must make
sure that they cannot be confused with BLOCK definitions and calls. If some
special character such as * + , etc occurs in front of the { no problem arises.
Functions and vectors may not have exponents. For functions this a mild
restriction, because one can always add on an argument, and consider that to
be the exponent.
Vectors may have a numerical arguments, for example p(3). This is taken to mean
the third component of p, but only in some really formal sense, and Schoonschip
has no objections against for example p(-3). The only restriction is that the
number must be a short-short number, i.e. less then 32. These numbers are
treated modulo 32, ranging from 0 to 31. Thus p(-3) becomes p(29). In the
following something like p(3) will be called a vector component. If an index
occurs all by itself, not as argument of a vector or function, it is treated as
an algebraic symbol. Thus one could have mu^3. Also vector components and
dot-products may have an exponent.
Like Fortran, Schoonschip has default assignments for names not mentioned in
any list. Things are pretty obvious in a case such as ff(a1,a2); but it is
ambigous for a case like p(k). Is p a function or a vector? Again, like in
Fortran, the default assignment for xx in a case like f(a1,xx) is an index if
the first character of xx is in the range I-N or i-n, and else an algebraic
symbol. It is always possible to see what Schoonschip guessed using the P list
command. This causes a print-out of all the lists of all quantities in a given
problem, but more about these commands later.
The rules for algebraic symbols are the usual ones. They are supposed to
commute with themselves and everything else, including functions. They may
appear with or without an exponent (must be short number), and may be preceeded
by a /. This simply implies a reversal of sign of the exponent. Thus a/b^3 =
a*b^-3. The exponent may also be an expression in brackets, provided this
expression, when encountered while working out the problem evaluates to a
number. This number is then truncated and rounded to the nearest short integer.
Thus b^(2-2/3) becomes b^1 = b.
Overflow occurs ff the exponent of an algebraic expression exceeds 127 or is
less than -128. In that case Schoonschip generates en error message. This may
be suppressed with the Overflow statement:
Overflow off
In that case Schoonschip creates in the case of overflow (or underflow) the
exponent 127 (or -128) representing infinity. The error trapping can be turned
on again with the statement:
Overflow on
The Overflow statement may be given in the *fix section and the option given
is then the default.
The rules for dot-products, vector components and indices not vector or
function argument are precisely those of algebraic symbols.
The lists are also used to assign some further properties to the various
objects. If complex conjugation occurs in a problem then the reality properties
must be known. An algebraic symbol may be real (default), imaginary or complex.
If it is complex then its complex conjugate must be designated. All this is
done in the A-list. If a symbol in the A-list is followed by =i it is taken to
be imaginary and the conjugate of the symbol is minus that symbol. A symbol may
also be explicitly designated to be real by the assignment =r. If the symbol is
followed by =c it is assumed that this is a complex symbol, and Schoonschip
creates a new name, by appending C (capital C), and places this directly after
this symbol:
A a1,a2=i,a3=c
implies a1 is real, a2 is imaginary (Conjg(a2)=-a2), a3 is complex, i.e.
Conjg(a3)=a3C and Conjg(a3C)=a3. The symbol a3C is created by Schoonschip.
If so desired it may be renamed by means of the statement
Oldnew a2C=xxx
where xxx stands for the new name. The Oldnew statement may actually be used to
change any existing name, including the build-in names.
Indices, vector components and dot-products are taken to be real. Functions may
also be real, imaginary or complex, and in addition "undefined", which will be
explained below.
Except for =c the definitions can be overwritten, the last definition holds.
This is useful with respect to build-in quantities of which one wishes to
change the reality properties. Overriding with =c leads to the fact that the
following symbol in the list is considered as the conjugate, which is fine if
it was not defined something else before. On the other hand, redefining an =c
assignment leaves its conjugate symbol as real, so that must then be redefined
explicitly also if not real.
In addition one may assign a number to an algebraic symbol. This number must be
between -32 and +32, and its function is to facilitate working with power
series. If one assigns for example the number 4 to a symbol then it is assumed
that powers of this symbol of 4 or higher can be ignored, and if a term
containing the symbol to such a power is seen it is immediately set to zero.
This is extremely useful if not indispensable when substituting series into
series. Somewhat similar one may assign z to a vector; if then that vector
occurs in a dot-product, with an index, or as vector-component it is also
immediately set to zero. Such facilities are very important when dealing with
large expressions. Function arguments are not considered with respect to zero
setting. This is somewhat ambiguous for a case such as p(mu)*f1(...,mu,..) =
f1(...,p,..); this ambiguity is to be resolved by the user, and seems not to
offer any difficulties.
Warning. Assigning a number to a symbol in order to speed up things is not to
be used if both negative and positive powers appear. Something like a^3 may
be deleted before being multiplied with, say, a^-2 in case the number 2 was
assigned to a.
Example 5.
A a1,a2=i,a3=c,a4=c,a5=i=3
V p,q=z,k
Z XX = Conjg(a1 + a2 + a3 + a4 + a5)
Z YY = Conjg(a3C + a4C)
Z ZZ = (a1 + a5)^5
Z AA = p(mu)*{p(mu) + q(mu)} + D(mu,3)*{p(mu) + q(mu)} + pDk
Oldnew a4C=b4,k=K
*end
Note how a5^3 and higher has been eliminated. Note also that the vector k
is replaced by K. The notation D(mu,3) is explained below.
The vector algebra rules are:
p(mu)*q(mu) = pDq
p(mu)*D(mu,nu)=p(nu)
D(mu,nu)*D(nu,la) = D(mu,la)
D(mu,mu) = n
In the above mu, nu and la are supposedly indices defined in an I-list. The
quantity n is the range of the indices, and may be a number, but also can
be symbolic. Thus when working in 3-dimensional space n would be 3, in four
dimensions n = 4. The default value is 4, since 1905. The way to specify
this value is in the I-list. One writes the number behind the index:
I mu=3,nu=3,la=3
Obviously one is supposed not to mix indices of different range in a
D-function. Schoonschip makes no check for that. If Schoonschip encounters
D(mu,mu) the number found in the I-list is substituted. Also a symbol may be
used, but it is restricted by the requirement that it may be only one character
in length. When encounterd in an I list Schoonschip will immediately enter that
symbol in the algebraic symbol list, and in addition the character followed by
an underscore is entered.
I mu=N,nu=N,la=N
If Schoonschip now encounters for example D(mu,mu)*D(la,la) the result
is N^2. The names N and N_ are entered in the symbol table. The name N_ is
used extensively in Gamma algebra involving indices of range N.
As an extension of these well-known rules there is the additional convention
that numbers and vectors may occur whenever indices may occur. Thus,
p(q) D(p,q) D(p,3) D(3,4)
are perfectly legal and they are worked out as one might guess:
p(q) = pDq, D(p,q) = pDq, D(p,3) = p(3),
and finally, if n1 and n2 are numbers then D(n1,n2) = 1 if n1 = n2, and = 0
if n1 not equal to n2.
These conventions imply a rule for D, namely that D(-x,y)=-D(x,y).
If an index occurs as argument of a function the treatment is conventional:
D(mu,nu)*f(...,nu,..) = f(...,mu,..)
where now mu may be index, vector or number, and the logical extension:
p(mu)*f(...,nu,..) = f(...,p,..),
etc.
Despite this simplicity there is a complication that is really quite a
a problem. Consider the following expression:
D(mu,nu)*f1(...,mu,..)*f2(...,nu,..)
There are two possible answers, namely
f1(...,mu,..)*f2(...,mu,..)
and
f1(...,nu,..)*f2(...,nu,..)
The answer is clearly not well defined. They should in fact be identified.
If two such terms arrive in the output Schoonschip should add them up, to
obtain 2*f1(...)*f2(...).
The solution to this problem is a renaming of indices. Indices that are
summation indices appearing twice, and whose name is not really relevant
may be declared in a Sum list:
Sum mu,nu
Now Schoonschip will in both cases rename the indices in the same way, and
the result is identical. The Sum list must occur after the I-list. It is
best placed near the line with an * in the first column. The indices
appearing in a Sum list must be defined before, but not in the *fix section
(explained later). The following example illustrates the Sum command:
Example 6.
I mu,nu,la,ka
Z XX = D(mu,nu)*f1(a1,a2,mu)*f2(a3,a4,nu)
+ f1(a1,a2,mu)*f2(a3,a4,nu)*D(mu,nu)
Z YY = D(la,ka)*f1(a1,a2,la)*f2(a3,a4,ka)
+ f1(a1,a2,la)*f2(a3,a4,ka)*D(la,ka)
Sum,la,ka
*end
Note how the indices la and ka are replaced by the invented name Naa.
Now functions. Functions may have arguments, which must be single quantities
separated by comma's. There is an extension involving tables, explained later.
An expression in brackets is also allowed as argument. As a special facility
functions may have characters as argument. Only single characters are legal,
and they are recognized by preceeding them with a ". Thus f1("A,"s) is legal.
See for example section 3.4, Compo for applications. Finally one may have
essentially numerical expressions. An essentially numerical expression is an
expression that works out to a number at execution time. It may include
most anything that works out to a number; it may even contain previously
evaluated expressions, but such expressions must be 'Keep' files, enclosed in
brackets, and be just one number. The number obtained will be truncated
and rounded to the nearest short number. A function containing an expression in
brackets as argument must somehow be replaced before it reaches the output
store, because that is how long Schoonschip retaines the definition of
expressions in brackets. This means that there must be an equation (rather, a
substitution as they will be called) leading to a replacement of such a
function before the line with a * in column one. Example of a function with
legal arguments:
f1(a1,p,q(3),"X,pDq,17-22,(23*a5-b5),f2)
This function must be replaced before the * line because of last but one
argument. This is no such problem in the following case:
f2(a3,7-2,pDq,"A)
It is not legal to start with numbers exceeding 127 in absolute value
occurring all by themselves:
f1(1E25)
is illegal and produces an error. But f1(2.34) is accepted and changed into
f1(2). And
f1(1-7E25)
is accepted but gives an overflow message at execution time. This is pretty
academic, and it is mentioned only for completeness. For a full understanding
it is necessary to know what is really going on inside Schoonschip. Numbers in
a function argument must be short integers (in the range -128, 127). Thus if
numerical expressions occur as function arguments they must be "integerized".
There is an operational symbol for that, namely Integ. At input time
Schoonschip analyzes this situation only very superficially, and when in doubt
adds the Integ operator to the argument. This happens as soon as a / or * etc
is seen. Thus f1(1E25-1) is translated to f1(Integ(1E25-1)). When this
expression is seen at execution time the argument is normally rounded and
truncated. Overflow occurs if the number is outside the range mentioned.
Integ will by default truncate the number towards 0, i.e. 1.9 becomes 1
and -1.9 becomes -1. Optionally this may be changed with the Round
statement:
Round on
In that case the number is rounded to the nearest integer (i.e. 1.9 becomes
2, -1.9 beomes -2). The statement Round off resets to the default option,
truncate. In all cases the floating point number is first rounded in the very
last 10 bits, to allow for stray bits.
The consequence of this is that composite non-numerical arguments are
to be avoided, for example f1(3-a) gives an error report, not at input
time, but when executing. As it may well happen that the symbol a is a
dummy to be replaced by a number to be specified during the calculation
it must be treated this way, and can not be flagged at input time. This will
become clear later.
With respect to complex conjugation the following rules are build in. When
conjugating a product of functions Schoonschip
reverses the order of all functions;
conjugates those quantities whose reality properties are known,
including the function arguments;
postpones complex conjugation of functions that have been classified
as u (for undefined) in the F-list.
In this context an expression in brackets is considered a u-function.
Example 7.
A a1,a2=i,a3=c
F f1,f2=i,f3=c,f4=u
Z xx=Conjg{ f1(a1,a2,a3)*f2(a1,a2,a3,f3)*f4(a1,a2,a3) }
*end
A particular problem arises if an expression in brackets occurs as argument of
a non-u-function. In such cases the expressions in brackets are conjugated,
that is the operator Conjg is attached to such expressions. Unfortunately that
is not possible for other types of symbols, thus if a u-function occurs as
argument of a non-u-function subject to complex conjugation then Schoonschip
stops. In such cases the function of which the u-function is an argument must
be made u-type too, which is after all quite logical. A u-function will
generally be replaced by something else later on, and then the complex
conjugation can be worked out.
A number of functions is build-in, including their reality properties, and here
a particular problem arises. The Epf function (the totally anti-symmetric Weyl
tensor) is real in 3 dimensions, where it represents the cross-product of
vectors, but it must be considered as imaginary in 4-dimensional Minkowski
space (because one of the components must be 4). Generally, the default
situation in Schoonschip is 4 dimensions, and thus Epf is considered as
imaginary. This may be changed by mentioning Epf in the F-list with the
option =r.
X-expressions are always considered as undefined with respect to complex
conjugation. They are discussed later.
The build-in quantities are:
Algebraic symbols: i=i.
This is the usual i, and the relation i^2=-1 is build in, although it is
not always applied instanteneously.
Functions: D,Epf=i,G=i,Gi,G5=i,G6=c,G7,Ug=c,Ubg,
DD,DB,DT,DS,DX,DK,DP,DF=u and DC.
Special rules are build-in for these functions. Some of these functions
must not be used, because they serve special purposes. The function DD is used
internally for all kinds of things.
The function D is the Kronecker delta function and has been explained
before. The Epf is the Weyl tensor, and it may have any number of arguments.
If it has 6 arguments it is assumed to be this tensor in 6-dimensional
space. A special command that reduces products of Epf to at most one Epf
is build in. Furthermore it is assumed that Epf is totally anti-symmetric
in all its arguments, and also it is supposed to commute with all other
functions. Both the D and Epf function are taken to be linear in their
arguments, that is D(-x,y)=D(x,-y)=-D(x,y) and similarly for Epf.
The functions G, Gi, G5, G6, G7, Ug and Ubg refer to gamma matrices and
Dirac-spinors as occurring in relativistic quantum-mechanics. They will
be discussed in a special section. Users not interested in that subject
may forget about them. Inside Schoonschip they account for about 8% of
the code, not worth removing.
The functions DB, DT, DP, DK and DC are numerical functions that are very
useful in many situations. DB with one argument is the factorial, and
DB with two arguments is the binomial function. The definition is:
DB(n) = n!
DB(n,m) = n! /{m!(n-m)!}
Internally the calculation of the binomial function is word (=16 bits) bound,
and fails for DB(19,m), m=8,9,... and higher up.
The function DT is the theta-function, and is very useful to switch terms on
and off. It may have any number of numerical arguments and is 1 if all
arguments are positive including zero, and else is zero:
DT(n1,n2,...) = 0 if one or more n1 negative, else DT =1.
The function DP is the permutation symbol. The arguments are permuted till they
are in ascending order, and the value of DP is zero if two arguments are equal,
and else +1 or -1 depending on the sign of the permutation:
DP(n1,n2,n3,...) = +1, -1 or 0. Zero if two numbers equal;
1 if permutation to smallest first
is even;
-1 if that permutation is odd.
For example, DP(2,1) = -1.
The function DK is something like a numerical Kronecker delta. It is 1 if
the arguments are equal, else it is zero:
DK(n1,n2) = 1 if n1=n2, else =0.
The fact that it is explicitly a numerical function makes it different from
the D function. For instance, DK may be part of a function argument
expression as in f1(...,4-2*DK(n1,n2),..)
The function DC is 1 if the sum of the arguments (it may have any number
of arguments) is zero, and else DC is zero. It is primarily intended for
situations where one has some conservation rule. It is also used in
connection with character handling, and then there are various rules.
The function DS is the summation function. Its application for character
summation will be explained in another section. Other than that it must
appear in the form:
DS(J,J1,J2,( F(J) ),( H(J) ) )
or
DS(J,J1,J2,( F(j) ) )
In here F and H are expressions that may depend on J. The quantities J1
and J2 must be numerical, and H must be a numerical expression. H is not
limited to short numbers. When working out this function Schoonschip makes
J run from J1 to J2 inclusive, and creates a sum of terms. Each term is of
the form
F(J)*G(J)
where G(J) is defined by the first G to be one (thus G(J1)=1), and
subsequent G are equal to the product of the previous G and the numerical
expression H for that value of J. This sounds complicated, but is not. The
expression H simply defines a recurrence relation between the coefficients
of the sum. For example, 21 terms of series for e^x are given by:
DS(J,0,20,(x^J),(1/J))
The recurrence relation G(J)=G(J-1)*H(J) for the coefficients gives 1/J!
as coefficient G(J) of the J'th term. This is a better way of handling
the factorial, both from an economical and numerical point of view, than
writing 1/J!, that is 1/(DB(J)).
There is an important restriction. If more than one DS function occurs
in an expression one must use different names for the summation variable
(J in the above example). Thus use J1, J2, etc.
Example 8.
Digits 20
Ratio 0
Z xx = DS(J,0,20,(1.),(1/J))
*begin
Digits
Ratio
Z yy = DS(J,0,4,(X^J),(1/J))
*end
5. X, D AND T EXPRESSIONS.
So far only Z-expressions occurred in the examples. These expressions are to be
evaluated by Schoonschip. Other expressions may be defined and may be called
when they are needed. Such expressions are X and D expressions. One may have
up to 500 X expressions. As a simple example take the series for cos(x). The
equation for cos(x) is:
cos(x) = { exp(i*x) + exp(-i*x) }/2
This series may be obtained as follows. First define exp(y) and then
write cos(x) in terms of this exponential (arbitrarily 6 terms are kept):
Example 9.
X EXP(y) = DS(J,0,6,(y^J),(1/J))
Z COS = { EXP{ (i*x) } + EXP{ -(i*x) } }/2
*end
Important rule: any X-expression must have been defined before it can be
referred to. It is permissible to have X-expressions appearing in an X-
expression provided that they were defined before.
The rules for arguments of X-expressions are the same as for functions,
which is why the argument i*x is enclosed in brackets. Here we see how
this is replaced in the right hand side of the EXP definition, so that
indeed this expression in brackets no more appears as function argument.
This method of defining COS may seem to be a waste, but in practice this
is used to define COS once and for all. It is namely possible to specify
an argument for the Z-expression, and to tell to Schoonschip not to throw
away this expression after printing it; then later on one may refer to
COS(x) as if it were also an X-expression. That will be discussed in the
section on files.
Arguments as appearing in the X-expression definition will often be called
dummies in the rest of this manual. They are to be replaced by the arguments
found in the call (in the Z-expression) at execution time. In other situations
some of the arguments may be dummies, others not, as we will see. In those
situations a dummy is to be followed by a wiggle: ~. In X and D expressions
and also in tables (T) all arguments are dummies and the wiggle needs not to
be given.
D-expressions are arrays of X-expressions. This may for example be used
to specify matrices. Everything is the same as for X-expressions, except
for the first argument. In calling a D-expression this argument must be a
number, and this number is then used to select the expression from the
array. Since the expressions in a X or D-expression may again be X or
D-expressions the possibilities are quite extensive. For example, let there
be a 3x3 matrix with the elements (a11,a12,a13),(a21,a22,a23),(a31,a32,a33)
in rows one, two and three. The first part of the following example produces
the determinant of that matrix:
Example 10.
B a11,a21,a31
D rc(n)=a11,a12,a13,
a21,a22,a23,
a31,a32,a33
X matrix(n,m)=rc(3*n+m-3)
Z xxx = DS{J1,1,3,(DS{J2,1,3,(DS{J3,1,3,
{ DP(J1,J2,J3)*matrix(J1,1)*matrix(J2,2)*matrix(J3,3) }
} ) } ) }
*begin
As shown, an X or D-expression can have many arguments. In fact, X or
D-expressions may be arguments of X or D-expressions. Here one must follow an
important rule. To make it possible for Schoonschip to analyze the right hand
side of some expression correctly dummies must be of the same kind as later the
argument replacing the dummy is going to be. The same kind means generally
speaking one of the four cases: symbols with or without exponent, vectors
functions or Tables. Thus functions and expressions (and later files) are of
the same kind. Algebraic symbols must be used as standin for dotproducts,
vector-components and also for short numbers (less than 128 in magnitude, the
same kind that may appear as function argument). Functions may stand for X or
D-expressions, as shown also in the second part of this example. It is best to
play this for sure, and use as dummies really the same kind, i.e. X-expression
type for X-expressions or D-expressions, functions for functions etc. In the
example below the use of for instance ra instead of f1 in the definition of
the X-expression matrix is advised. Vector-components, dotproducts and
numbers are illegal as dummy. If they are to be substituted in an X-expression
use some algebraic symbol to represent them, as we did using n and m in these
examples.
In the second part of example 10 we define a general X-expression for
a determinant that may be called to compute the determinant of any matrix
occurring in a problem. Two determinants are computed.
F f1
B a11,a21,a31,b11,b21,b31
D ra(n)=a11,a12,a13,
a21,a22,a23,
a31,a32,a33
D rb(n)=b11,b12,b13,
b21,b22,b23,
b31,b32,b33
X matrix(n,m,f1)=f1(3*n+m-3)
X DET(f1) = DS{J1,1,3,(DS{J2,1,3,(DS{J3,1,3,
{ DP(J1,J2,J3)*matrix(J1,1,f1)*matrix(J2,2,f1)*matrix(J3,3,f1) }
} ) } ) }
Z detb=DET(rb)
Z deta=DET(ra)
*begin
In the third part of this example it is shown how the X-expression DET
can be made into a D-expression giving determinants for 1x1, 2x2 and 3x3
matrices.
C Example 10.
F f1
B b11,b21,b31
D ra(n)=(a1-a2),0,
0,(a1+a2)
D rb(n)=b11,b12,b13,
b21,b22,b23,
b31,b32,b33
D rc(n)=c11
X matrix(k,n,m,f1)=f1(k*n+m-k)
D DET(n,f1) =
f1(1) ,
DS{J1,1,2,(DS{J2,1,2,
{ DP(J1,J2)*matrix(n,J1,1,f1)*matrix(n,J2,2,f1) }
} ) } ,
DS{K1,1,3,(DS{K2,1,3,(DS{K3,1,3,
{ DP(K1,K2,K3)*matrix(n,K1,1,f1)*matrix(n,K2,2,f1)*matrix(n,K3,3,f1) }
} ) } ) }
Z deta=DET(2,ra)
Z detb=DET(3,rb)
Z detc=DET(1,rc)
*end
Several remarks are in order. First, note how items in a D-expression array
must be enclosed in brackets if the expression contains more than one term.
The rule is that each entry must be one term only (an expression is a sum of
terms, each term is a product of factors). An expression enclosed in brackets
counts as one factor in a term. Secondly, there is the question of DS
arguments. For the first argument, the summation index, one must use different
variables for each DS function. Thus J1, J2 and J3 must not be used more than
once. This was mentioned before, and in this example it is relevant.
T-expressions or better Tables are for use as function arguments. There are
also 'character tables' to be discussed elsewhere. Tables represent an array of
quantities that may be selected as function argument and at execution time the
appropriate argument is selected on the basis of the value of the first
argument. The following example shows a complicated way of obtaining f(a) +
f(b) + f(c) :
Example 11.
T List(n)=a,b,c
F f
Z compl = DS(J,1,3,{ f(List(J)) } )
*begin
This is really the idea: to enable summing over a series of arguments that
can then be listed using a Table. The rules for entries in a Table are
simple: they must be valid function arguments. Tables can be nested,
allowing essentially matrices of arguments. The first argument of the
Table in the call selects an item from the corresponding Table list. If
that item is again a Table, then the second Table list is looked up with
the second argument determining which argument to take. And so on.
All arguments are treated as dummies, and Table entries may depend on
them. Since an expression enclosed in brackets may appear in the Table list
that allows for complicated constructions. If such expressions are essentially
numerical, and they must ultimately be converted to a short number the
oprator Integ must be placed in front of them. Also Conjg is allowed.
A x=c
T r1(n)=a11,a12,a13
T r2(n)=a21,a22,a23
T r3(n)=a31,a32,a33
T matr(n,m)=r1,r2,r3
T weird(n,a1,a2)=Conjg(a1+a2),Integ(3*a2)
X XX(a1,a2)=a2*a1
Z sqa13 = DS(J,1,3,{f1(matr(1,J))*f1(matr(J,3)} )
Z weirdo=XX(weird(1,x,7),weird(2,x,7))
*end
There is a subtlety here. Whatever follows Conjg, enclosed in brackets,
is considered an expression. It must not survive as function argument
beyond the * line. Thus if in weirdo we would have had f1 instead of
the X-expression XX then this would be illegal here.
General rule: anything that can occur as function argument can occur as
element in a Table list. This includes for example characters (notation: "X
is the character X). Be careful with numbers: they are treated like
function arguments, and non-integers are truncated.
6. FILES.
Files very much resemble X-expressions, but there is one important difference.
A file contains the result of some Schoonschip calculation. A Z-line defines a
file, with the name as given on that line. A file may have arguments, can be
stored in a variety of ways, and can be part of a problem just as any
X-expression.
Schoonschip has been made with the assumption that files tend to be large.
Elaborate measures have been taken to handle the largest files. The number
of files that can be handled at any one time is limited to about 200.
To begin with, files are divided in local and common files. All the
Z-expressions that have been shown sofar are local. Local files are normally
lost over a * line, except over a *yep. A local file may be kept over a * line
provided that the word next is on that line, and provided that the file was
mentioned in a Keep list:
Z xxx(a,b)=(a+b)^2
Keep xxx
*next
Z yyy=xxx(c,d)
*begin
After a *begin the local files are all lost. Schoonschip treats local files
as efficiently as possible. They are kept in memory if there is room, if
they are too big they are stored on disk and recalled if needed.
Common files are kept untill explicitly deleted or till the *end line. They can
be written to disk for use in a later session. Schoonschip keeps all common
files in a sequential file on disk. Great care has been taken that such
expressions, when needed in a problem, are read with the least amount of
input/output activity. The user will normally see nothing of these read/ write
activities, but should still be aware of it when handling large problems.
Computer handled problems have the tendency to become large, that is simply in
the nature of the subject. Except for the simplest cases it is really quite
impossible for a computer to simplify an expression. While it is trivial to
simplify a^2+2*a*b+b^2 to (a+b)^2, it becomes an entirely different matter when
dealing with 1000 or more terms. Of course, with a little help from the user,
simplification can be done, on a rather primitive level. If one recognizes a
pattern such as shown above one substitutes a^2=apb^2-b^2-2*a*b, and the output
collapses to apb^2.
In addition to the classification local and common, files may be indexed
or non-indexed. This makes it possible to have arrays of files, much like
D-expressions. The way a file is defined to be indexed is as follows:
- A local file is defined to be indexed if on the defining Z-line the
first argument of that file is a number in the range 0-32767. There are
provisions for situations where this number is an expression, involving
for instance DO-loop or BLOCK variables, but at execution time such
expressions must work out to a number. Only numbers and DO-loop or
block variables may appear in these expressions, and for these latter
variables numbers must be substituted.
- A common file is defined to be indexed if it appears in the Common
list with a subscript, preferably the number 0. The implication of
that is not the existence of the file with the particular index zero,
but rather that this filename represents a class of subscripted files.
Thus:
Common abc,Xyz,fgh(0),jkl
defines abc, Xyz, fgh and jkl to be common files, and fgh is an indexed
files. When in a subsequent Z-line such a filename occurs it is recognized
and at the end of the calculation the file is written to disk.
For local files the command Keep is of interest:
Keep aaa,bbb,ccc(1),eee
This line, which should occur shortly before a *next line, leads to keeping
of the files mentioned over the *next. For an indexed file one may either
explicitly mention an index (such as for ccc here) and then only that file
is kept. If there are several ccc files to be kept it is sufficient to
mention ccc without any index and then all ccc files are kept.
There are several other commands that relate to files. First, common files
may be written to a named disk file for use in a later problem. This may
be done with the command
Write xxx
All common files that exist at that moment are written (sequentially) to
a file named xxx. Thus xxx will in general contain many files. This
statement must be all by itself, and not be embedded in some problem.
In other words, before and after this Write line there must be a * line
not containing yep or next.
When one or more of the common files contained in xxx are needed one
may enter these files:
Enter xxx
This statement should preferably be the first statement of a Schoonschip
program. It must be before a *fix line, explained below. Schoonschip opens
the file xxx and enters all names in the common file table, and the files
themselves are copied to a diskfile local to Schoonschip (tape7). One may
have several Enter and Write statements. Note: do not confuse Enter and Read.
The latter is for reading normal Schoonschip text from some external file.
Common files may be deleted:
Delete abc,Xyz,fgh(3)
Again, the mentioning of fgh without any index leads to deletion of all
fgh files.
As the reader may guess it is quite a problem to keep all namelists straight
when common files are entered. Normally Schoonschip treats this problem only
when encountering such files in a given problem. Usually that will give no
problems, but difficulties may arise in connection with summation indices (see
Sum declaration). For this reason it may be necessary to enter the names
contained in that file before actually starting on the problem. The statement
Names abc,Xyz,...
is meant for this purpose. If this directive is not given, and Schoonschip
runs into problems then an error exit is taken, asking for the Names line.
Example 12 shows some very simple case. Note that the local file xxx
is lost over the *begin line, and xxx is taken to be a function. Similarly
for common file ccc after a delete. When this problem is run the file
fileC is created. Make sure that there is not already some file by that
name.
Example 12.
P lists
Common yyy,ccc(0)
Z xxx(a,b)=(a+b)^2
Z ccc(3,a,b)=(a+b)^3
Z ccc(4,a,b)=(a+b)^4
Keep xxx
*next
F f1,f2
V p
Z yyy(p)=xxx(c,d) + p(nu)*f2(mu)
Sum mu,nu
*begin
Write fileC
*begin
V q
Z zzz=a1*yyy(q)
Z Abc=xxx(a,b)
Delete ccc,yyy !The actual delete occurs when this section is done.
*begin
Z xyz=ccc(3,e,f)
*end
The statement P lists at the beginning causes Schoonschip to print all
symbols known before execution. Also details such as reality properties or
dimensionality of indices is shown. For X, D, T expressions the type as well as
the nesting depth is shown. Also brackets count in this respect.
At this point it must once more be emphasized to be conscious of the use of
local and especially common files in a problem. If for example yyy is a rather
lengthy common file then things such as (yyy)^4 may lead to very lengthy
calculations. If yyy has 100 terms this gives rise to (100)^4 terms, i.e. 100
million terms that must be sorted. This will fill up all available disk-space,
to name something. And 100 terms is really not that much as these things go.
Just to avoid this kind of disaster Schoonschip has an output limit build in of
about 0.5 Megabyte per file used by Schoonschip. This limit may be changed by
means of the statement
Outlimit,#
where # is the new limit in bytes. What to do if really big expressions
must be evaluated will be discussed later. In this context an expression
is called big when it exceeds 50,000 terms.
7. PRINT OPTIONS.
The following directives influence output. Only the first two characters
of the word following P are releveant.
P brackets print working out of brackets
P heads print in the output only the factors outside brackets (B-line)
P input print input lines (default)
P lists print lists of all symbols (vectors, functions etc.)
P ninput do not print input lines
P nlists do not print lists (default)
P noutput print no output (default in *yep cases)
P nstats print no statistics (default)
P output print output (default, except in case of *yep)
P stats print statistics
In addition the following directives affect output format:
Screen try to keep lines less than 80 characters long (default)
Lprinter go up to 130 characters/line
Printing of the individual files may be affected as well, but only if they
are currently being processed:
Print xxx,yyy,... print files xxx,yyy,...
Nprint xxx,yyy,... do not print xxx,yyy,...
Punch xxx,yyy,... write xxx,yyy,... to a file named tape8 in fortran
compatible form.
This last directive is useful if the output is to be used for further
numerical output in a fortran program, or for curve plotting etc.
Normally print options stay in effect untill cancelled. Exception: P heads.
The P output option, often used to force output printing in a *yep situation,
survives only one *yep.
8. END LINE OPTIONS.
For the * line the following possibilities exist:
*fix Do not start execution. All names and expressions defined
before this statement remain valid till the *end line.
*yep Start execution. Write the output to disk and feed in again
as input.
*next Start execution. Keep all namelists, and those local files
mentioned in Keep lists. A Keep list extends over one
*next only.
*begin Start execution. After this start new problem. Disregard
all names except those mentioned in the *fix section.
*end Start execution. Stop after completion.
Not explained so far is the *fix option. This is used whenever names or
X, D or T expressions are to be defined that are valid for all following
problems, including those after a *begin. This *fix section must be the
very first section, and must not contain any Z expressions. If common
files are to be entered it must be in this section.
The sequence shown above reflects the general structure of any Schoonschip
program. First there is a *fix section, and then there may be several *yep,
*next and *begin lines before the final *end is encountered.
The *yep command is extremely useful, but can only be explained properly
later, after discussing substitutions. It is rather unique to Schoonschip,
and of crucial importance when dealing with large problems.
9. SUBSTITUTIONS.
Most things discussed up to now essentially help to define expressions, but do
not really work on those expressions. The main tools for work on expressions
are what will be called substitutions and commands. A substitution basically
amounts to looking at an expression term-by-term, and if certain patterns match
something may be removed from the term, and something else substituted. This
basic tool, for the first time introduced in the 1964 Schoonschip version, is
the essential ingredient of symbol manipulation.
Thus in the first place there is pattern recognition, and secondly there
is a substitution. In this version (1984+), optionally, these two aspects can
be separated. One can first look for a pattern, set some flag indicating the
result of the inspection, and then at a later stage act on that flag.
Commands define certain operations to be done on the terms, and that are of
sufficient generality to warrant building in. For instance, there is a command
that allows the user to specify which functions are commuting with each other.
Schoonschip acts on that by setting these functions in an internally well
defined order, so that terms differing only by functions being placed in
different order become equal. Such an operation can also be done with
substitutions, but is more tedious.
An important concept in substitutions is the use of dummies. These quantities
have already been introduced before in connection with X, D and T expressions,
and here they become even more useful. Let us start with a simple example.
Imagine that some polynomial in x must be integrated, and let this polynomial
be quadratic:
a*x^2 + b*x
to be integrated from x1 to x2. This integration amounts to using the rule x^n
=> x^(n+1)/(n+1), and then putting the integration limits. This may be done as
a substitution. First look for x to any power (this is the pattern). Then
remove x and substitute by the appropriate expression which is the integral of
that x. The following example shows how this can be done:
Example 13.
Z integr = a*x^2 +b*x
Id,x^n~ = x2^(n+1)/(n+1) - x1^(n+1)/(n+1)
*begin
Schoonschip looks for the pattern "x to any power", and if found removes
that x and instead substitutes the right hand side of this substitution. The
value of the power found is substituted for n in that expression. Here n
is a dummy. To let Schoonschip know that it is a dummy the wiggle ~ must
follow directly behind it.
The notation Id refers to a name used often in the past for this operation,
namely "identity".
The matter to be discussed now is what kind of patterns can be specified.
As an example of the sort of complication that can arise take this integral
again. Suppose there had been a term without any x. What should Schoonschip
do? In this case that should be treated as x^0, but in many other cases such
terms must not be worked on. In the spirit of pattern recognition a term
without x is taken not to fit the pattern specified here, and such a term is
thus not worked on.
But how now to go about that? A classic way to do that is to use an extra
symbol, that we will call dx here:
Z integr = (a*x^2 + b*x + c)*dx
Id,x^n~*dx = x2^(n+1)/(n+1) - x1^(n+1)/(n+1)
Al,dx = x2 - x1
*end
What happens is that if dx and as well x to any power excluding zero is
encountered then the first substitution is done. This leads also to the
removal of dx. If a term without any x (the c term) passes by the first
substitution is not done, and the dx survives. But then the second
substitution is performed. The notation Al is an abbreviation of "also",
but there is more to it, which will be explained below. Generally, Al can
be used with advantage for mutually exclusive patterns. One can not use
Al in case that the first substitution generates a pattern that the second
may have to act on. Since there is a limit on the number of Id statements
it is often necessary to use Al, and its use should be well understood.
There is an equivalent notation to Al, namely placing that substitution on the
same line preceeded by a semicolon (;):
Id,x^n~*dx = x2^(n+1)/(n+1) - x1^(n+1)/(n+1) ;dx = x2 - x1
There may be several such 'also' statements on one line, but lines should
not exceed 150 characters.
This example shows really most that there is to it. Of course, more complicated
patterns than just an algebraic symbol to some power can be specified, but that
is really just an extension of the same principle. There are substitutions that
are performed if certain functions with certain arguments are present, and one
may specify if the order of these functions is important or not; one may
operate on function arguments, on vectors in a dotproduct etc. Basically,
through the years, things that may be needed have been implemented. As it
happens most of these are quite natural, barely needing a manual, such as the
one above. Let us give another example, to show a number of applications. In
the above integral more complicated things could have occurred, for instance
terms such as x^3*cos(x). To evaluate these one must first do partial
integrations:
x^3*cos(x) = x^3 * d/dx{sin(x)} = d/dx{x^3*sin(x)} - 3*x^2*sin(x)
Thus, before doing the x-integration one must first do these partial integra-
tions, and that as many times as needed given the highest power of x that
occurs. Assuming that at most x^10 occurs one would write:
Id,10,x^n~*cos(x) = x2^n*sin(x2) - x1^n*sin(x1) - n*x^(n-1)*sin(x)
Al,10,x^n~*sin(x) = - x2^n*cos(x2) + x1^n*cos(x1) + n*x^(n-1)*cos(x)
There are more elegant ways to do this, using X-expressions, but that
is not the point here. That general method is shown anyway, as last part
of Example 13.
The above implies doing these substitutions on ten subsequent Levels, and
substitution will be done as long as x to some power occurs. The final
step, to be taken if no more x present would be the integration of cos(x)
or sin(x):
Id,sin(x) = cos(x2) - cos(x1) ;cos(x) = - sin(x2) + sin(x1)
If also x to negative powers would occur one would have to treat that
separately. This is where the conditional substitutions comes in handy.
One may test for the presence of negative exponents, and set a flag
depending on the outcome of such a test:
IF Multi,x^-1
This tests for exponents that are a multiple of the exponent shown, here
-1. If so a flag is set. Subsequent substitutions will be done if that
flag is set until an ELSE is encountered. The then following substitutions
will be done if the flag was not set. An ENDIF statement terminates the
conditional substitutions. The typical sequence would be here:
IF Multi,x^-1
Substitutions to treat x^-n type terms.
ELSE
Substitutions to treat x^+n type terms.
ENDIF
A NOT following the IF is recognized, and the following sequence gives
identical results:
IF NOT Multi,x^-1
Substitutions to treat x^+n type terms.
ELSE
Substitutions to treat x^-n type terms.
ENDIF
IF's may be nested, up to 8 deep.
A futher extension uses AND and OR statements, possibly combined with NOT.
For example, if there are also terms without sin or cos:
IF cos(x)
OR sin(x)
..IF Multi,x^-1
..Substitutions to treat x^-n type terms.
..ELSE
..Substitutions to treat x^+n type terms.
..ENDIF
ELSE
Substitutions to deal with x^n without sin or cos.
ENDIF
A new notation, purely for readability, has been introduced. A . in column
one causes Schoonschip to skip all following periods. In this way one may
indent the nested IF's to show IF depth. See the section on conditional
substitutions for more details.
A few patterns as can appear in the left hand side of a substitution have been
introduced above. The need for those patterns are clear, once one starts on
this kind of problem. Along these same lines a set of patterns has been defined
that appears to be adequate to deal with things as they arise in practice. It
is somewhat difficult to give a complete description, but it has to be done.
Let us do this in two rounds, namely first somewhat sloppy, and then precise.
As long as one deals with a single quantity (including exponent or index or
arguments) one has various options specified by keywords. One such keyword
appeared already above, namely Multi. For algebraic symbols the following
substitution patterns are possible:
Id,a=... Substitute n times if a^n encountered, n positive.
Id,a^n=... Substitute once if precisely a^n encountered.
Id,a^n~=... Substitute once for a, any non-zero exponent
Id,Multi,a^n=... Substitute m/n times if a^m encountered, and m has
the same sign as n; leave rest.
Id,Once,a^n=... Substitute once if a^m encountered, m/n ge 1;
leave rest.
Id,Funct,a=.... Substitute for a if appearing as function argument.
The action taken is to enclose the expression
on the right hand side in brackets and place it
instead of the argument a. Remarks concerning
expressions in brackets as function arguments
apply here. Such functions may not cross * lines
and must be subject to some substitution before that.
Id,Funct,f1,f2,...,a=...
Same, but only in the specific functions mentioned
Thus Id,Once,a^2=... when encountering a^7 leads to one substitution, and
a^5 is left.
Of course, Al (or ; and on the same line) may occur instead of Id.
In the above n is a number, except in the third case where it is a dummy.
Similar things may be written down for dotproducts or vector-components.
For single functions one may specify the function including the arguments,
but some or all may be dummies, and one may also have repetitive dummies.
For example:
Id,f1(a~,b,c,a~)=...
leads to a substitution if the function f1 is encountered with as second
and third argument b and c, while any argument on the first or fourth
place will do provided they are the same. Here a is a repetitive dummy.
One could have specified another dummy for the last place:
Id,f1(a~,b,c,d~)=...
and then the substitution is done for any argument on the first or fourth
place, including equal arguments.
The build-function D is special insofar that it is generally not allowed
as part of a substitution pattern. It may however appear all by itself
with or without dummies. Examples:
Id,D(al,be) = ....
Id,D(al~,be) = ...
For single functions one keyword may appear. If a function has nothing but
dummies as arguments, and if the keyword Always appears, then the substitution
will be done even if the argument count is not the same. Thus
Id,Always,f1(a~,b~)=...
is applied also when encountering f1(xx,yy,zz). The argument zz is then
simply dropped. Make sure that the case that there are more dummies than
arguments can not occur.
Finally one may even specify a dummy function:
Id,f1~(a,b,c~,...)=...
The substitution is done for any function whose arguments and argument count
agree.
For vectors a number of different possibilities exist:
Id,p(mu)=... Substitute for p(mu).
Id,p(mu~)=... Substitute for p with any index.
Id,Dotpr,p(mu~)=... Substitute for p if appearing in dotproduct or as
vector-component.
Id,Dotpr,f1,f2,..,p(mu~)=...
Same, but only in the specific functions mentioned.
Id,Funct,p(mu~)=... Substitute if p appears as function argument.
Id,Funct,f1,f2,..,p(mu~)=...
Same, but only in the specific functions mentioned.
In the last cases things are done as expected for vectors. In all but the first
case it is assumed that the right hand side depends on the index mu. For
example, typically, one could have Id,Dotpr,p(mu~)=k(mu)+q(mu) . Suppose now
pDq is encountered. Schoonschip reads this as p(q), and substitutes q for the
index mu, which leads to kDq+qDq, as should be. If pDp is seen then Schoonschip
invents an index, say Naa, substitutes this index for mu and writes:
{ k(Naa) + q(Naa) } * { k(Naa) + q(Naa) }
A similar thing is done if p is encountered as function argument in case of
the Funct type substitutions:
f1(...,p,...) becomes f1(...,Naa,...)*{ k(Naa) + q(Naa) }
which leads to f1(...,k,...) + f1(...,q,...). Thus linearity of f1 in p is
supposed here. This substitution should therefore not be applied if that is
not the case.
For any other pattern involving more than one quantity substitutions are
straightforward. The only extra options that one has here is that the
ordering of functions may be specified. The keyword Adiso (allow disorder)
indicates that substitution must be done no matter the ordering of the
functions. The keyword Ainbe (allow inbetween) implies that the substitution
must be done if the functions are in the same order, even if there are some
other functions inbetween. If none of these keywords is present then the
substitution is done only if exactly the same pattern is found. The pattern
may involve dummies for exponents, vectors, indices, functions and function
arguments, and one may have repetitive dummies.
As a special option one may also have factors xx^0 where xx is an algebraic
symbol, vector-component or dot-product. Schoonschip requires in that case that
specifically xx is not there.
++++++++
We stress here that for dummies one must (repeat: must) use the same kind
of symbol as that what replaces it at execution time. See the discussion
on this subject in the section on X-expressions.
++++++++
Forty substitution Levels are available. If more Levels are needed a line with
*yep must be inserted. The Level count is printed by Schoonschip next to
every substitution. More levels are needed for a given substitution as the
bracket depth is larger. It is often advantegeous not to use brackets if
not strictly necessary. For example, it is better to write
Id,x^n~ = x2^(n+1)/(n+1) - x1^(n+1)/(n+1)
which needs two levels rather then
Id,x^n~ = (x2^(n+1) - x1^(n+1)) /(n+1)
which needs three levels. Schoonschip generates a substitution for every
bracket pair. If you want to see what Schoonschip does use the option
P brackets.
10. PATTERNS.
In this section a more precise discussion of the substitution patterns is
given. For a first reading this section may be skipped, it is really there only
for reference, in case something special is going on.
The way things are organized in Schoonschip there is a classification
in about 17 classes. In practice one will rarely realize what class a
given pattern belongs to, but for completeness we will discuss possible
patterns on the basis of this classification. We will also indicate what
action is taken once the pattern is found to be present, although that
may be influenced, postponed or even inhibited by means of conditional flags.
The classification is on the basis of what occurs on the left hand side
of the = sign on an Id or Al line. Only products of factors may occur (thus
no + or - sign except in exponents or function arguments), and no brackets
other than associated with a function and its arguments or a vector and its
index. Thus something like a+b or a*(c+d) is illegal. Furthermore, a keyword
may be given, and that influences the way Schoonschip reacts to a pattern.
Finally one will encounter the word repetitive dummy. That is when the same
dummy appears two or more times in the left hand side of a substitution. In
that case Schoonschip verifies that in the pattern the same thing appears in
both places, although the thing itself may be anything.
Here are the various classes, examples will be given later. Below a,b,..
stand for algebraic symbols, n,m,.. for short numbers, p,q,.. for vectors,
f1,f2,.. for functions etc.
0. f1(a~,b~,...) Function, all arguments non-rep. dummies.
Optional Keyword: Always
Action: substitute for every such function found provided the
number of arguments agrees.
If the keyword Always is given then substitute irrespective of
the number of arguments in the function found. It is up to the
user to see to it that the number of arguments equals or exceeds
the number of arguments actually appearing in the right hand side
of the substitution.
1. a^n Symbol with exponent, no dummy.
Keyword: Multi
Action: when encountering a^m divide m by n, and if the result,
truncated to an integer, comes out to be 1 or more, substitute
that many times. The remaining exponent is put back. Thus a^2 applied
to a^7 leads to 3 substitutions and one factor a is left.
The exponent may be negative: a^-2 applied to a^-7 leads to 3
substitutions and a remainder a^-1. If n and m have opposite sign
no substitution is done.
If the exponent n is absent the keyword Multi is understood, and
an exponent 1 used.
2. pDq^n Dotproduct with exponent, no dummy.
Keyword: Multi
Action: same as in class 1.
3. a^n Symbol with exponent, no dummy.
Action: substitute once if exactly a^n found.
4. pDq^n Dotproduct with exponent, no dummy.
Action: see class 3.
5. p(mu) Vector with index, no dummy.
Action: substitute once if p(mu) found.
6. p(mu~) Vector with dummy index.
Action: substitute for every p(..) for any index. The substitution
applies not if the vector p appears as factor in a dot-product
or as function argument, and also not to vector components such
as p(3) (i.e. if the index is a number).
7. a or mu or pDq or p(n) Symbol (index, dotproduct, vector component)
Keyword: Funct
Action: replace a (or mu etc) when occurring as function argument.
Note: such functions must be substituted for before the * line,
because an expression as function argument can not survive a *.
If functions are mentioned between the keyword and the argument
then only those functions will be considered.
8. a^n or pDq^n Symbol or dotproduct with exponent.
Keyword: Once
Action: substitute once if a^m encountered if m/n positive and
equal or larger than one. Keep the remainder. Thus a^2 when
encountering a^7 leads to one substitution and a^5 remains.
9. a^n*...f1(mu,b,..) One function and anything else.
10. f1(mu,a,b~,..) One function.
11. Anything
Keyword: Adiso
Action: substitute if all factors found even if the functions
found are not in the same order as in the left hand side of the
substitution. Note: Adiso stands for Allow disorder.
Note: the expression is put at the location of the first function
removed.
12. Anything
Keyword: Ainbe
Action: substitute if all factors found, with the functions in
the same order, although there may be other functions inbetween.
Note: Ainbe stands for Allow inbetween.
Note: the expression is put at the location of the first function
removed.
13. Anything
Action: substitute if all factors found, with the functions in
the same order and no other functions inbetween.
Note: the expression is put at the location of the first function
removed.
14. Not used.
15. p(mu~) Vector with dummy index.
Keyword: Dotpr
Action: substitute for p if p part of a dotproduct appearing with
a positive exponent.
16. p(mu~) Vector with dummy index.
Keyword: Funct
Action: substitute if the vector p is found as function argument.
If one or more function names are mentioned between the keyword and
p(mu~) then the substitution will be done only in the specific
function(s) mentioned.
All of this may sound a lot more complicated than it is, all these classes
are really such that they cover most cases that one can imagine. The user
needs not to know to which class a given substitution belongs, and most
substitutions are natural in the sense that it is obvious what action is
to be taken.
We will now give examples, essentially going through all possibilities.
The same starting expression will be used in all cases, and we will use
a *fix section to specify that expression. Then many cases follow, all
separated by a *begin implying a fresh start.
Example 14.
V p,q
A a,b,c,d,e,f,g,h
I mu,nu
F f1,f2,f3
X expr=f1(a,b,p)*f2(a,c,q)*f3(d,e)*f1(g,h)*
{ a^7 + a^-7 + a^2 + pDq^2 + pDp + p(mu) + p(nu) }
*fix
C Class 0, no keyword.
Z xxx=expr
Id,f1(a1~,a2~)=a1^10*a2^20
*begin
C Class 0, keyword Always.
Z xxx=expr
Id,Always,f1(a1~,a2~)=a1^10*a2^20
*begin
C Class 1, keyword Multi.
Z xxx=expr
Id,Multi,a^3 = xyz + hij
*begin
C Class 2, exponent 1, no keyword.
Z xxx=expr
Id,pDq = XYZ + HIJ
*begin
C Class 3, no keyword.
Z xxx=expr
Id,a^2 = a1^7/15
*begin
C Class 5.
Z xxx=expr
Id,p(mu) = - q(mu)
*begin
C Class 6.
Z xxx=expr
Id,p(mu~) = - q(mu)
*begin
C Class 7, keyword Funct.
Z xxx=expr
Id,Funct,a = a27
Id,f1(a1~,a2~,a3~) = 200*a1*a2*a3
Al,f2(a1~,a2~,a3~) = a1^10*a2^11*a3^12
*begin
C Class 8, keyword Once.
Z xxx=expr
Id,Once,a^2 = XXX
*begin
C Class 9.
Z xxx=expr
Id,a^2*f2(a1~,c,p~) = F2(a1,c,p)
*begin
C Class 10.
Z xxx=expr
Id,f1~(a,b~,p~) = F(a,b,p)
*begin
C Class 11, keyword Adiso.
Z xxx = expr
Id,Adiso,f1(g,h)*f1(a~,b~,c~) = F1(a,b,c,g,h)
*begin
C Class 12, keyword Ainbe.
Z xxx=expr
Id,Ainbe,f1(g,h)*f1(a~,b~,c~) = F1(a,b,c,g,h)
Id,Ainbe,f1(a~,b~,c~)*f1(g,h) = F2(a,b,c,g,h)
*begin
C Class 13.
Z xxx=expr
Id,f1(x~,b,p)*f2(x~,c,q) = F(x,b,p,c,q)
*begin
C Class 15, keyword Dotpr.
Z xxx=expr
Id,Dotpr,p(mu~) = - q(mu)
*begin
C Class 16, keyword Funct.
Z xxx=expr
Id,Funct,p(mu~) = - F1(a,b,mu)
*end
11. CONDITIONAL SUBSTITUTIONS.
In the foregoing IF, AND, OR and ELSE have been introduced already.
The general structure is:
IF pattern
Substitutions
ELSE
Substitutions
ENDIF
There may be no ELSE. The IF statement may be followed by AND and/or OR
statements. IF, AND or OR may be followed by NOT which inverts the action.
Finally, the pattern may optionally be followed by an = symbol and an
expression. In such a case the substitution is actually done if the
pattern fits. The pattern may be any of the classes discussed in the previous
section.
Inside Schoonschip IF's etc set or clear some bit. One bit is reserved
for any given IF depth. Nesting up to eight deep is allowed, there are eight
bits provided. Here are the rules for bit setting:
A succesful IF (or unsuccesful IF NOT) leads to setting of the bit. An AND (or
AND NOT) statement will be inspected only if the bit is set. If succesful (or
not succesful if AND NOT) the bit remains, else it is cleared. An OR (or OR
NOT) statement will be inspected if the bit is not set. If succesful (or not
succesful if OR NOT) it sets the bit. The substitutions or commands following
such a sequence will be inspected if the bit is set. After an ELSE the
substitutions or commands will be inspected if the bit is cleared.
Do not put any substitutions or commands inbetween the IF, AND or OR
statements if there is an ELSE. The reason is that substitutions and commands
following an ELSE are on the same level as those following the preceeding IF,
AND, OR group. The ELSE becomes ambiguous in such a case. Also, no AND or OR
after an ELSE, which is also ambiguous.
The fact that an expression may be given on the IF, AND, OR lines allows very
compact code. For example, to integrate any polynomium in x (see Example 15):
IF NOT x^-1 = [Log(x)]
AND NOT x^n~ = x^(n+1)/(n+1)
Al,Addfa,x
ENDIF
The command Addfa attaches the factor given, here x. That command will be
executed only if none of the two previous substitutions applied. Note the
use of Al (rather than Id) for the Addfa statement. This may be done because
this statement is not using anything that might be produced by the previous
IF and AND statements.
Note the symbol (we stress, the symbol) [Log(x)].
Here some comments about level assignments. Schoonschip assigns all IF, AND and
OR statements to the same substitution level. IF is as Id, OR and AND as the Al
type assignement. A later ELSE is assigned to the same level as the associated
IF. The first substitution following an IF, AND, OR sequence may have Id or Al;
the level assigned is as usual. If none of the IF etc substitutions actually
perform substitutions then one should use Al. However, if that substitution
needs the completion of the previous IF etc substitutions then Id should be
used. The same holds after an ELSE, where Id must be used for the first
substitution following that ELSE if that substitution needs the completion of
the IF etc substitutions. Note that these latter substitutions may be way up.
If an AND or OR substitution depends on the result of previous IF etc
substitutions then it should not have an Al type assignment as Schoonschip
would use. To force level alignment for such a case simple put a line with Id
before the AND or OR statement, like
IF a1=2*(a1+a2)
Id
AND a1=(a4+a5)
Example:
L 1 IF a3=2*(a1+a2)
L 1 AND a7=5*a1*(a7+a8)
L 3 Id,a1=0
L 4 Id,Count,x,a1,1
:
L 1 ELSE
L 3 Id,a1=3
ENDIF
L 5 Id,...
The last level shown (L 5) is the maximum of (level when reaching ELSE, level
when reaching ENDIF). Compare with Al use:
L 1 IF a3=2*(a1+a2)
L 1 AND a7=5*a1*(a7+a8)
L 1 Al,a1=0
L 3 Id,Count,x,a1,1
:
L 1 ELSE
L 1 Al,a1=3
ENDIF
L 4 Id,...
12. COMMANDS.
Sometimes certain operations are difficult or impossible to do with
substitutions, and a number of facilities have been build in that deal with
specific situations. They are generally called commands, and they perform
actions at the Level that they have been placed. They generally need at
least one level, and sometimes the number of levels to be used influences
the performance. The general syntax of a command is:
Id,Keyword,parameters separated by commas
in which case Schoonschip uses a number of levels depending on the command.
Alternatively, with # some number < 40:
Id,#,Keyword,parameters separated by commas
in which case Schoonschip sets aside # levels for this command. There is
one command for which this is quite relevant, namely Gammas.
Now to more specifics. Suppose that some function is symmetric in its
arguments, say f1(a,b,c)=f1(b,a,c)=... In such a case one would like the
arguments to be arranged always in the same order. The command
Id,Symme,f1
causes Schoonschip to inspect every function f1 that passes by at this Level,
and arguments are re-arrangered in a well defined way (first defined symbols
first). This is of course much easier than the perhaps very long set of
substitutions that would do the same thing. One would have to know beforehand
what arguments could appear, and then go through all combinations.
For commands the first four, if no confusion possible the first three
characters are relevant. The may be in upper or lower case. The following
commands are available:
Absol Make the sign of the numerical coefficient plus
Addfa Add factor
Anti Inspects functions for characters with an _
Asymm Function anti-symmetric under interchange of arguments
All Rounds up all appearances of a vector, or appearances of
all vectors in a specified function.
Beep Sent Control-G to the terminal (which normally beeps at that)
Coef Inspect numerical coefficient
Commu Re-arrange commuting functions
Compo Compose names from characters
Count Count certain occurrences
Cyclic Function invariant under cyclic permutation of arguments
Dostop Clears, sets or tests the forced DO-loop exit flag.
Epfred Reduce products of Epf functions
Even Function even in sign of arguments
Expand Expand frozen files
Extern Call user defined subroutine
Gammas Throw the book at Gamma matrices
Iall Inverse of All
Numer Insert numerical values
Ndotpr Construct anomalous dot-products (for use with Gammas)
Odd Function odd in sign of arguments
Order Order functions as based on the first two arguments
Print Prints message
Ratio Rationalize
Spin Sum over spins of spinor functions Ug, Ubg
Stats Counts how often this command is called
Symme Function symmetric under interchange of arguments
We will discuss them one by one. First the general format is shown, and
then some example is given. Commands may also occur in IF etc statements,
but often it is not well defined what means succes or failure. As a rule
succes is defined as 'some action has been taken'. For example, Addfa
will always give succes.
Ordering inside Schoonschip is always done on the basis of 'smallest first',
not only for the purposes of the commands of this section, but also for output
printing of the quantitities not mentioned in the B-list. This means the
following ordering for quantities of different kind:
Index, Vector, Function, Algebraic symbol, Characters,
Number (short numbers), Vector-component, Dot-product.
For quantities of the same kind the ordering is according to the moment at
which the quantity was encountered first. For dot-products the earliest
defined vector counts first. To guarantee a certain ordering the quantities
can be given in the appropriate list in the desired order.
With respect to numbers the counting is not entirely as one might expect:
0 before positive numbers up to 127, then 128=-128, -127, -126,..., -1.
This is because of the two's complement notation for numbers.
*** Id,Absol
The coefficient of the term inspected is forced positive. This command
needs no levels.
*** Id,Addfa,expression
The expression specified is attached as a factor. This command is mainly
intended for use with conditional statements; the expression can be attached
depending on previous actions. There are no particular limitations
on the sort of expression that can occur here; anything allowed in a Z
expression or in the right hand side of a substitution is allowed here,
although here no dummies can be specified.
Example 15.
Integration of polynomium.
A a,b,c,d,e,x
Z xxx = a*x^2 + b*x + c + d/x + e/x^2
IF NOT x^-1=[Log(x)]
AND NOT x^n~=x^(n+1)/(n+1)
Id,Addfa,x
ENDIF
*end
The command All (and the associated Iall) has two different syntaxes. In the
first syntax the first argument is a vector (must have been defined before):
*** Id,All,p,N,F
Optionally this list may be followed by the character arguments "F_, "D_
or "V_ (always separated by commas), and possibly an index list, see below.
For the second syntax the first argument is a function (must have been defined
before):
*** Id,All,Fx,N,F
The parameters p,N and F must have been defined previously as vector,
algebraic symbol (it must be a one character symbol) and function.
The parameter N may be absent.
First syntax:
All occurrences of the vector p are considered. If any qualifying p
found the function F is appended. Next this function obtains arguments
reflecting the p found:
- If p(mu) with mu any index is seen this p is removed and the argument
mu is added to the argument list of F.
- If pDq with any q and a positive exponent (say pDq^n) then the argument
q is added n times.
- If pDp with a positive power (say n) is seen then a new index is created.
This index is added 2*n times.
- If p is seen as argument of any function then an index is created. This
created index replaces p as function argument, and furthermore the index
is added to the arguments of F.
In the above work, whenever an index is created, it is given the symbolic
dimension N, or the default dimension (=4) if no N specified.
The main use of this command is to facilitate integration with the vector
p as integration variable.
Optionally character arguments may be specified after the list shown above.
The allowed characters are:
"F_ "D_ "V_
If "F_ seen no function arguments will be inspected. "D_ inhibits dot-product
inspection, "V_ single vectors. Example:
Id,All,p,N,F,"F_,"V_
Only dot-products are considered.
Second syntax:
All arguments of the funtion Fx are considered. If a given argument is
a vector then that vector is replaced by a created index. The function
Fq obtains two new arguments, namely the vector and the created index.
In the final result the arguments of Fq are: first all vectors, then the
corresponding indices. For example, All,Fx,N,Fq applied to Fx(p,k,q)
gives Fx(Naa,Nab,Nac)*Fq(p,k,q,Naa,Nab,Nac).
It is clear that the All command will in general give rise to created
indices. Such indices are often renamed by Schoonschip, in order to
achive a well defined result in the output. This renaming may sometimes
be undesirable, in particular there may be undesirable consequences
when later a Freeze command is issued; the Freeze command may offer
trouble if a created index appears in a pair, one outside and one
inside the brackets. To handle such cases one may assign to the All
command a list of indices after the last function (and the possible
V_ etc). These indices must be defined in the I list, with the same
dimension as that specified in the All command, and they will be
used rather then newly created indices. Example:
I al1=N,al2=N,al3=N
:
:
Id,All,p,N,Fx,D_,al1,al2,al3
It may be that more indices are needed then provided in the list. There
are two options here. If the command is as above, and if the list is
exhausted then Schoonschip will issue an error message. If the list is
terminated with the character C:
Id,All,p,N,Fx,D_,al1,al2,al3,"C
then Schoonschip will, after using up al1-al3, create further indices
as needed.
C Example 16.
V p,q
F F
I mu=N,nu=N
Z xx= pDp^2 * pDq^3 * F1(p,p,q,p) * p(mu) * q(nu)
Id,All,p,N,F
P output
*yep
C Showing the dimensionality of the created indices:
Id,F(i1~,i2~,i3~,i4~,i5~,i6~,i7~,i8~,i9~,i10~,i11~)=
F(i1,i2,i3,i6,i7,i8,i9,i10,i11)*D(i4,i5)
*begin
C A more realistic example.
I al,be,mu,nu
A N,N_
V p,k
F F,F20,F22
Z xx = G(1,1,al,be,p,al,be,p)
Id,All,p,N,F
P output
*yep
Id,F(i1~,i2~) = D(i1,i2)*F20(k) + k(i1)*k(i2)*F22(k)
*end
*** Id,Anti,TA
All function arguments are inspected for character arguments ("X). If
a character with underscore is seen the character table TA is consulted.
If that character appears in that table the underscore is removed.
This command will be discussed further in the section on character
manipulations.
*** Id,Asymm,F1,2,3,4,F2,F3,4,5
This command specifies that f1 is anti-symmetric in arguments 2,3 and 4,
f2 in all arguments and f3 in arguments 4 and 5. If the arguments are not
in the 'first defined first' order the arguments are permuted. If the
permutation is odd a minus sign is attached. If a number in the list is larger
then the number of function arguments that number is ignored.
There is a second syntax for this command that can be used if the arguments
occur in groups:
*** Id,Asymm,F1:2,3,4:7,8,9:12,13,14:
The groups of numbers within colons denote argument groups. They need not to be
sequential. Only the first argument of a group is used in the comparison.
However, if an interchange is needed both groups are interchanged as a whole.
For example, if in the above case argument 7 is to placed before argument 2
than 2 is interchanged with 7, 3 with 8 and 4 with 9.
If the arguments are sequential an even shorter syntax is allowed:
*** Id,Asymm,F1:1-3:7-9:12-14:
The number of arguments in each group must of course be the same.
Note: for symmetric functions see command Symme.
Example 17.
V p,q,k
I mu
A a,b,c,d,e,f,g,h
F F1,F2,F3
Z xx = F1(e,d,c,b,a) + F2(e,d,c,b,a) + F3(e,d,c,b,a)
+ F2(-125,-30,-1,0,30,125)
+ F2(pDq,pDk,kDq,p(3),q(2),F2,7,mu,p,a)
+ f1(e,f,g,d,a,b,c,h,k)
Id,Asymm,F1,2,3,4,F2,F3,4,5
Al,Asymm,f1:1-3:5-7:
*end
The command
*** Id,Beep,#
sends a Control-G to the terminal. This normally results in a beep. It may be
used to signal audibly certain occurrences. Be careful though; one quickly gets
a lot of noise. The number # limits that: at most # beeps will be issued. The
number # must be positive and less than 128. Example:
IF a^10
Al,Beep,3
ENDIF
The Beep statement (not this command) may be used to generate some noise at
termination, or if an error occurs.
The command Coef essentially inspects the numerical coefficient of any term
passing by, and here specifically use with conditional substitutions is
intended. The syntax is:
*** IF Coef,option
Of course, this command can also be used with AND or OR, with ot witthout
a NOT. The possible options are:
pl plus
ng negative
eq,# equal
lt,# less than
gt,# greater than
ib,#,# inbetween
Here # represents a number (any number, not just short numbers). When a
term passes by the coefficient is inspected or compared, and the IF bit
is set or cleared depending on the result. Concerning equal, two numbers
are considered equal if they agree within the number of decimal digits
specified by the Precision statement (25 default). The naming of the
options corresponds closely to the way the IF bit is set:
y set IF bit (or clear if IF NOT)
If Coef,option
n clear IF bit (or set if IF NOT)
C Example 18.
A a1,a2,a3,a4,alt1,agt2,aeq15,ai12
Z xxx= 0.5*a1 + 1.5*a2 + 2.5*a3 + 1.E-20*a4
IF Coef,lt,1. !Add factor alt1 if coefficient < 1.
Id,Addfa,alt1
ENDIF
IF Coef,gt,2. !Add factor agt2 if coefficient > 1.
Id,Addfa,agt2
ENDIF
IF Coef,eq,1.5 !Add factor aeq15 if coefficient = 1.5
Id,Addfa,aeq15
ENDIF
IF Coef,ib,1,2 !Add factor ai12 if coefficient inbetween 1 and 2.
Id,Addfa,ai12
ENDIF
IF Coef,lt,1E-15 !Delete the term if coefficient < 1E-15.
Id,Addfa,0
ENDIF
*end
As shown, this command can be used effectively to eliminate 'dirt'.
The command Commu is used for ordering commuting functions. The ordering
is done (i) with respect to the name of the function (smallest first, see
the introduction of this section) (ii) number of arguments (iii) arguments.
*** Id,Commu,F1,F2,F3,...
If the commuting functions occur nested between other functions then they are
taken out and placed behind these other functions. Thus the Commu command
may be of consequence even if there is only one function named, and if that
function occurs at most once in a given term.
Example 19.
A a1,a2,a3,a4,a5
F F1,F2,F3
Z xx = F3(a1,a2)*F1(a1,a2,a3)*F1(a4,a5)
+ F1(a1,a2,a4)*F2(a1,a2,a3)*F1(a1,a2,a3)
+ F3(a1,a4)*F2(a1,a2,a3)*F1(a1,a2,a4)*F2(a3,a4,a5)
Id,Commu,F1,F3
*end
The IF bit is set if any of the named functions is present.
The Compo command is quite complicated, and realistic application are not
well suited for description in this manual. We will nevertheless give a
complete description of this command. It involves character manipulation
and may lead to the generation of new symbols including functions. There
is a way to correlate the created name of a function with the arguments
specified. Combined with the use of Tables (Tables can also have characters
in the list) this is a very powerful tool to generate many symbols or also
functions reflecting a topology. For a very simple application see also
the example demonstrating the command Count, Example 21.
*** Id,Compo,"X,TA,<options>,F1,F2,<options>,F3,F4,..
The character argument "X may be absent, or it may be "S or "S_.
The character table argument TA may be absent. If present it specifies
characters for which "X_="X (anti-particle = particle). If not given
the default is used, which may be none, or one defined by means of the
Anti statement.
Briefly, Compo takes the character arguments found in F1 etc, permutes them
into a well defined order (unless "S_ is specfied for "X) and at the same time
permutes argument groups in F1. The characters are then glued together and
either identified with an existing name, or if not existing the name is entered
in some name list, or the term is discarded depending on the options specified.
The functions F1,F2,... are inspected. The arguments are expected to have the
following structure:
F1(c1,c2,c3,..,cn,/,d1,d2,..,dm,*,arg1a,arg1b,.,*,arg2a,arg2b,
..,*,argka,argkb,..)
In here c1..cn and d1...dm are characters, with the notation ". Legal are:
upper and lower case characters and number characters possibly followed by an
underscore. They may also be vectors, in which case the character(s) of the
vector name are used. Either n or m may be zero, but not both. If m is zero
the / needs not to be given. The arguments arg1a,arg1b etc correspond to
character c1, arg2a,arg2b etc to character c2 and so on. The sum of n and m
must not exceed 6 (not counting the underscores), and not 2 if the name to be
constructed is to be a vector name.
The characters c1-cn are subject to the ordering process, the d1-dm not.
Concerning the argument groups (arg1a,arg1b,..),(arg2a,arg2b,...),...,
(argka,argkb,...) the following:
- an argument group may be empty. This corresponds to two successive *
separated by a comma;
- the number of argument groups may be less then the number of characters
c (i.e. k less than n). In that case argument groups k+1, k+2,.. are
considered empty;
- the number of argument groups may be larger then the number of characters
c (i.e. k larger than n). Access groups are not considered in the actions
described below and are simply reproduced.
When encountering such a function Schoonschip inspects the characters and
permutes them according to the standard character ordering (A-Z, a-z, 0-9;
characters followed by an underscore are ordered just before the corresponding
character without underscore: A,B,C_,C etc). The sets of arguments
arg1a,arg1b,.., arg2a,arg2b,.. are permuted in tune with this. Thus if for
example only c1 and c2 are exchanged then the argument list reads afterwards:
*,arg2a,arg2b,..,*,arg1a,arg1b,..,*,arg3a,...
No permutation is done with respect to the characters d1,d2,...
No permutation is done if the character variable "S_ (no symmetrization)
was given in the argument list of Compo.
Next all characters are glued together, thus forming a name. This name is
searched for in the lists mentioned in 'options'; if found that name is
identified with that variable. If not found the action taken depends again on
the option specification. If a list is mentioned twice then the new name is
added to that list and new occurrences will be identified with that name. If no
list is specified twice in options then the whole term is discarded.
In the option list, enclosed between < >, the characters X A F V I may
appear once, the characters A F V and I also twice. Thus no new entries
can be made to X-expressions, but the X table (which includes also D
and T expressions and files) can be searched. At most one character can
occur twice. There is a default option: <AXIVFA> meaning search all lists,
and if not found insert in algebraic symbol list.
After identification of the name the corresponding symbol is made to be the
first argument of the function, replacing all c and d characters and the
optional /. Then all * are removed. The result is a function with as first
argument the constructed symbol, and the following arguments is what results
after the permutations among the argument groups. In subsequent substitutions
one may work this function out to whatever is required.
C Example 20.
F F1,F2
A a,b,c,d
Z xx = F1("c,"b,"a,/,"e,*,a1,a2)
+ F1("c,"b,"a,/,"e,*,a1,a2,*,xy)
+ F1("c,"b,"a,/,"e,*,a1,a2,*,xy,*,a2)
+ F1("c,"b,"a,/,"e,*,a1,a2,*,xy,*,b2,*,xz)
+ F2("a,"b,/,"F,*,x,*,y,*,z1)
+ F2("b,"a,/,"F,*,x,*,y,*,z1)
+ F2("F,"c,"b,"a,*,*,z,*,y,*,x)
+ F2("F,"c,"b,"a,*,*,z,*,yp,*,x)
Id,Compo,<AVIFXA>,F1,<FF>,F2
Id,Always,F2(F1~,a~,b~,c~,d~,e~) = F1(a,b,c)
Id,F1~(a~,b~,z1) = F1(a,b)
*begin
Notes: concerning the first group, F1, various possibilities concerning
number of argument groups are demonstrated. The option specified for this
in the Compo command is actually the default option and could have been
omitted. In the second group it is shown how various functions with arguments
can be created, even with different number of arguments. To this purpose
the fake argument z1 was introduced in the first two cases. The function
substitution for F2 works no matter how many arguments, but one must take
care that in the right hand side no undefined quantities appear. This means
that the function F2 should not occur with less than 3 arguments.
Unfortunately it is not possible to handle empty arguments here. The fake
argument z1 is removed in the last substitution.
Note also dummy use in the substitutions. For function dummies we used
a function symbol defined in the F-list (F1 in this case). Disaster may
result if this is not done. It is extremely difficult to analyze for all
possible cases that may occur if that type of error is made, and many
cases will lead to cryptic error messages seemingly unrelated to this.
A second example shows the use of Compo together with Tables. It is a
rather artificial example, but it shows the main ideas. Suppose an electric
circuit must be build up from 4 three-pole elements connected by diodes,
in the configuration shown:
j1
i1 ---0-------0--- i3
j4 | |j2
| |
i2 ---0-------0--- i4
j3
The currents i1 and i2 are flowing inwards, i3 and i4 outwards. j1-j4 are taken
to flow clockwise. The 3-pole elements have three external connections called
A, B and C. The connecting elements are diodes, the connections are called B
and C. B of a diode may be connected to a B from a 3-pole, C to the C of a
3-pole. One might think here of emitter and collector of a transistor. The
main object is now to generate all possible configurations, which is very
simple in this case, one may either have all the diodes oriented clock-wise, or
all oriented counter-clock-wise. Also one wants to exhibit the currents flowing
through the various objects. Once the expression involving all elements with
the currents is obtained explicitly one can go on and work out whatever is
wanted. If the connecting elements are for instance a diode, resistor and
battery in series one can compute all currents as function of the input/output
currents i1-i4, but we will leave this to the imagination of the reader.
In the example below the function v3 represents the 3-pole. The only
combination to be recognized is the combination ABC. Thus only the function
ABC is defined, and in the options of Compo the F-list is mentioned only
once. Things like AAB or ACC will then be thrown away. Below we simply
sum over all possibilities for the connecting lines (i.e. AA, BC and CB)
leaving it to Compo to keep only those combinations that contain exclusively
the functions ABC and BC.
A new feature in this example is the occurrence of characters in the
lists for the Tables Ch and Cg. While not exhibited here there is another
facility build in. Normally one refers to a table-element by means of the
table name followed by a number. One may also refer to table elements by
means of the table name followed by a character. Then the number associated
with that character (given above) is used to pick out the correct element.
This is useful if certain properties have to be associated with a character.
T Ch(n)="A,"B,"C
T Cg(n)="A,"C,"B
F BC,ABC
A i1,i2,i3,i4,j1,j2,j3,j4
Z solu = square("A,"A,"A,"A)
Id,square(c1~,c2~,c3~,c4~) = DS{L1,1,3,(DS{L2,1,3,
(DS{L3,1,3,(DS{L4,1,3,(
v3(c1,Ch(L1),Cg(L4),*,i1,*,-j1,*,j4)*
con(Ch(L1),Cg(L1),*,j1,*,-j1)*
v3(c3,Cg(L1),Ch(L2),*,-i3,*,j1,*,-j2)*
con(Ch(L2),Cg(L2),*,j2,*,-j2)*
v3(c4,Cg(L2),Ch(L3),*,-i4,*,j2,*,-j3)*
con(Ch(L3),Cg(L3),*,j3,*,-j3)*
v3(c2,Cg(L3),Ch(L4),*,i2,*,j3,*,-j4)*
con(Ch(L4),Cg(L4),*,j4,*,-j4)
) } ) } ) } ) }
Id,Compo,<F>,v3,con
Id,v3(f1~,a1~,a2~,a3~) = f1(a1,a2,a3)
Al,con(f1~,a1~,a2~) = f1(a1)
*end
The command Count has grown out of the need to have a facility that selects
terms on the basis of certain asymptotic properties. One may know of various
functions and other quantities how they behave as function of some variable for
certain limiting values of that variable (like for example behaviour as
function of x for very large x). With Count one can for instance select terms
that behave for large x as x^n with n larger then some given number. This is
the most typical application. But the command allows many other things, here is
the description.
*** Id,Count,xxx,arg1,#,arg2,#,....
In case that xxx is a function or X-expression the format is:
*** Id,Count,Fx,arg1,#,arg2,#,...,# : arg3,#,...,# : arg4,#,...
The colon's separate groups of arguments.
Optionally, function names preceeded by "F may be specified directly after
the first argument of Count or after the semicolons, if any:
*** Id,Count,Fx,"F,Fy,"F,Fz,arg1,#,arg2,#,...,# :"F,Fc,arg3,#,...,#
In here arg1, arg2 etc may be indices, vectors, algebraic symbols or functions.
As a first step, investigating a term, a number is constructed. This number is
the sum of numbers obtained for individual factors. The number for an
individual factor is the exponent of that factor (if applicable) multiplied by
the number following the corresponding argument in the Count list. Thus if in
the Count list x,7 occurs than a x^3 in a term leads to a contribution of 21 to
the number being constructed. If no exponent (as would be the case for a
function or vector) the number from the list is added once. The contribution of
vector-components or dot-products is computed on the basis of the value
assigned to the corresponding vectors in the list. Thus p,2,q,5 leads to 21 for
pDq^3 and 10 for q(3)^2. In constructing the number function arguments or
vector indices are not investigated. However, function argumnts of functions
specified with the "F option are counted as single occurences. Thus, the
statement
Id,Count,xxx,"F,Fa,a,35,b,1
leads to the count 38 for the term b^2*Fa(a,b,c).
The action taken next depends on what occurs as first argument in the
Count list (i.e. xxx above):
- If xxx is a number then the constructed number is compared with xxx.
If the constructed number is equal or larger than xxx the term is kept
Else the term is deleted.
- If xxx is an algebraic symbol, vector component or dot-product the
constructed number is made to be the exponent of that symbol and the
combination is attached to the term.
- If xxx is a function or X-expression then the number is made to be the
argument of that function or X-expression and the combination is attached
to the term.
A multiple count can be made. The occurrence of a colon (:) in the count
list signals that subsequent counts must be put in subsequent function
arguments. Thus if two colons occur a three argument function is created.
The list up to the first colon is used to compute the value of the first
argument, the argument list between first and second colon determines the
value of the second argument, etc. Example: consider the term
a^3*b^2*pDk
with p and k vectors. The command
Id,Count,Fc,a,1,b,2 : p,2,k,3
(Fc defined before to be a function) generates a two argument function Fc:
Fc(7,5)*a^3*b^2*pDk
The fact that Fc may also be an X or D-expression allows for very compact
but quite complicated counting. If Fc is a non-numeric X or D expression
then possibly several substitution levels are needed to work out the
result, and in this case Schoonschip does not automatically count that.
For purely numeric X and D expressions only one level is needed. To insure
proper level spacing in case of non-numeric Fc write a dummy substitution
involving Fc directly before the Count command and use Al for the Count
command:
Id,XxxX=Fc
Al,Count,Fc,a,1,b,2 : p,2,k,3
where XxxX is not occurring anywhere else.
In the following example we do not only demonstrate Count, but show also
some other application of Compo. The coefficients a1-a5 are constructed and
entered in the A-list (remember default options Compo is <AFVIXA>). Also
the use of Keep and *next is shown.
Example 21.
A x,y
T tt(n) = "1,"2,"3,"4,"5
C Here a complicated way to make
C pow(x) = a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5.
Z pow(x) = DS(J,1,5,{f1(/,"a,tt(J))*x^J})
Id,Compo,f1
Id,f1(y~) = y
Keep pow
*next
Z xx = pow(x)
Id,Count,3,x,1
Keep pow
*next
Z xx = pow(y)
Id,Count,f1,y,2,a3,10
Keep pow
*next
V p,q
A AA
Z xx = pow(y)*f1(a2,a3)*pDq^2
Id,Count,AA,y,2,f1,-4,p,1,q,3
*end
The commands Cyclic and Symme are analogous to Asymm, except that invariance
under cyclic permutation or simply exchange of arguments is implied.
*** Id,Cyclic,F1,2,3,4,F2,F3,4,5
*** Id,Symme,F1,2,3,4,F2,F3,4,5
For the command Symme the alternative syntaxes used to denote groups of
arguments can be used:
*** Id,Symme,F1:2,3,4:7,8,9:12,13,14:
*** Id,Symme,F1:1-3:7-9:12-14:
As to Cyclic, the arguments are permuted following the pattern specified in
the Cyclic list, which may make things pretty obscure as the following
example shows. The arguments specified are permuted till 'smallest first'.
Example 22.
A a,b,c,d,e
Z xxx = f1(e,d,c,b,a) + f2(e,d,c,b,a) + f3(e,d,c,b,a)
Id,Cyclic,f1,2,5,4
Id,Symme,f2,f3,2,3,4
*end
*** Id,Dostop,on
*** Id,Dostop,off
*** Id,Dostop
The command Dostop may be used to set, clear or test the forced DO-loop exit
flag. If this flag is set then the next ENDDO encountered is taken to be
satisfied. This command may be used to execute a set of substitutions
and commands followed by a *yep repeatedly till some condition is satified.
Here a typical example:
Z xx = a^10
DO J=1,100
Dostop off
Id,a1^n~=a1^(n-1)*b
IF NOT a1
..Id,Dostop,on
ENDIF
*yep
ENDDO
*end
The DO-loop sequence will be re-executed 100 times or till no more a1 present.
In the case shown the cycle is run 10 times and the result is b^10. Note
that:
- The Dostop statement and command are within the same program segment (i.e.
there is no line with an * inbetween);
- The last line of the DO-sequence contains an * in column 1.
Refer to the remarks on the Dostop statement for more details.
The Dostop command may have other or no parameters:
Id,Dostop,off
Id,Dostop
In the last case the Dostop flag is tested, but not modified. The command
may be used in conjunction with an IF:
IF Dostop
...
ENDIF
A set flag implies 'yes'.
The command Epfred leads to reduction of products of Epf with equal number of
arguments to one Epf.
*** Id,Epfred
The simplest case is for two arguments:
Epf(i1,i2)*Epf(i3,i4) = D(i1,i3)*D(i2,i4) - D(i1,i4)*D(i2,i3)
In three dimensions this is the equation that rewrites the product of two
cross products in terms of dot-products. If p, q and k are vectors, than the
pseudo-scalar (k.pxq) is given by Epf(k,p,q). If pp, qp and kp are also
vectors then the product (k.pxq)*(kp.ppxqp) can be rewritten in terms of dot-
products. Similar relations hold in higher dimensions. Note: the product of
two Epf of different dimension is not reduced.
Example 23.
V p,q,k,pp,qp,kp
Z xxx = Epf(k,p,q)*Epf(kp,pp,qp) + Epf(i1,i2,i3,i4)*Epf(i1,i2,j3,j4)
Id,Epfred
*end
The commands Even and Odd specify that some function is even or odd with
respect to change of sign of certain arguments. Minus signs of such arguments
are removed.
*** Id,Even,f1,2,3,4,f2,f3,4,5
*** Id,Odd,f1,2,3,4,f2,f3,4,5
Example 24.
F f1,f2,f3,f4
Z xxx = f1(-a1,-a2,a3,-a4) + f2(-a1,-a2,a3,-a4) + f3(-a1,-a2,a3,-a4)
+ f4(-a1,-a2,a3,-a4)
Id,Even,f1,2,3,f2
Id,Odd,f3,2,3,f4
*end
The command Expand occurs in combination with frozen files. See the section
on freezing a file. Syntax:
*** Id,Expand,fname
In here fname is the name of a frozen file. All frozen subfiles referred
to through the function DF or expanded.
*** Id,Extern,arg1,arg2,...
The command Extern allows entering an of external routine as integral
part of Schoonschip. First one needs the statement External:
External filename
The statement External, specifying an external file, leads to loading of that
file in working space. The command Extern leads, at execution time, to a jump
to the first location of that file. If that file contains position independent
executable code then manipulations on expressions can be performed. This
requires an understanding of the formats used inside Schoonschip, and supposes
the ability to generate such a file.
The interface provides acces to all arrays, and also utilities such as
print routines etc inside Schoonschip can be used. The information will
not be given here, but is available. Roughly speaking, a whole series
of addresses is passed on as a structure on the stack. The arguments are
passed on in the form of an array.
In principle this facility allows the creation of special packages
designated for specific problems.
*** Id,Iall,p,F
*** Id,Iall,F
Inverse of All for the two possible syntaxes. Do not use Iall if the indices
that occur as argument may have dimensional restrictions (Dim_N or Dim_4)
as created when doing gamma algebra, command Gammas. The command Ndotpr is
to be used in such cases.
*** Id,Gammas, loop indices + options, Trace, loop indices + options
This command will be discussed in a separate section: Gamma algebra.
The command Numer can be used if numerical values must be inserted for
certain quantities. The format is:
*** Id,Numer,arg1,#,arg2,#,...
The numbers need not to be short numbers, they can be anything. Function
arguments are not considered. The arguments may be algebraic symbols,
vector components or dot-products.
Example 25.
V p,q
Z xxx = a1^2*pDq^3/p(4)
Id,Numer,a1,2,pDq,1.E10,p(4),1.E5
*end
The command
*** Id,Ndotpr,F1
is closely related to the Gammas command and will be discussed in the section
on Gamma algebra.
*** Id,Order,F1,F2,...
This command searches for the functions F1, F2.... and builds a chain on
the basis of the first two arguments. First the function F1 is searched.
The second argument is taken, and looked for in other functions. If found,
the new function is chained to the previous. Etc.
One index is kept in the collected Faa, namely the first seen.
There are two additional options for this command. Specifying the character "C
(for collect) as first arguments leads to collection of all arguments except
the first two into one function. Specifying a number as first argument gives
that number as first argument to the collected functions of the first chain
collected, that number+1 to the second, etc. The option "C may be combined with
this. If the number given is zero no first argument is kept. Examples
(the output is reproduced here):
Z x1 = Faa(4,5,ddd)*Faa(2,3,bbb)*Faa(1,2,aaa)*Faa(3,4,ccc)
Id,Order,Faa
x1 = + Faa(1,aaa)*Faa(1,bbb)*Faa(1,ccc)*Faa(1,ddd) + 0.
Z x1 = Faa(4,5,ddd)*Faa(2,3,bbb)*Faa(1,2,aaa)*Faa(3,4,ccc)
Id,Order,"C,Faa
x1 = + Faa(1,aaa,bbb,ccc,ddd) + 0.
Z x1 = Faa(4,5,ddd)*Faa(2,3,bbb)*Faa(1,2,aaa)*Faa(3,4,ccc)
Id,Order,90,Faa
x1 = + Faa(90,aaa)*Faa(90,bbb)*Faa(90,ccc)*Faa(90,ddd) + 0.
Z x1 = Faa(4,5,ddd)*Faa(2,3,bbb)*Faa(1,2,aaa)*Faa(3,4,ccc)
Id,Order,90,"C,Faa
x1 = + Faa(90,aaa,bbb,ccc,ddd) + 0.
Z x1 = Faa(4,5,ddd)*Faa(2,3,bbb)*Faa(1,2,aaa)*Faa(3,4,ccc)
Id,Order,0,Faa
x1 = + Faa(aaa)*Faa(bbb)*Faa(ccc)*Faa(ddd) + 0.
Z x1 = Faa(4,5,ddd)*Faa(2,3,bbb)*Faa(1,2,aaa)*Faa(3,4,ccc)
Id,Order,0,"C,Faa
x1 = + Faa(aaa,bbb,ccc,ddd) + 0.
*** Id,Print,#,Message
This command can be used to print a message at execution time. The number
# limits the number of times the message is printed. Everything after the
third comma, including blanks, up till the end of the line is printed when
this command is encountered at execution time. Example:
Id,2,Print, Hello world.
The message " Hello world." is printed at most twice.
The command Ratio is specifically there to facilitate integrations. It
is used to rationalize a product of factors that are linear in the integration
variable. The simplest case is:
1/(x+a) * 1/(x+b) = {1/(x+a) - 1/(x+b)}/(b-a)
Since in Schoonschip expressions cannot have a negative exponent (except when
they are purely numerical) one cannot directly write such things. The way to
do that is to introduce a symbol to represent an expression appearing with
negative exponent, for example xpa = x+a. Then the equation becomes:
xpa^-1*xpb^-1 = {xpa^-1 - xpb^-1}*bma^-1
Here the [] notation for symbols comes in very conveniently. One may write:
[x+a]^-1 * [x+b]^-1 = {[x+a]^-1 - [x+b]^-1}/[b-a]
If the exponents are large this becomes quite complicated, and that is where
Ratio comes in. In the command one must specify the two factors and their
difference, in the case mentioned one would write:
*** Id,Ratio,[x+a],[x+b],[b-a]
Ratio works for all cases of exponents that may occur, positive or negative.
C Example 26.
A a1,a2,a2ma1
F f1
B b2,b3,b4,b5
Z xx=f1(8,4)
Id,f1(n~,m~)=
{ b2*a1^n*a2^m
+ b3*a1^-n*a2^m
+ b4*a1^n*a2^-m
+ b5*a1^-n*a2^-m
}
Id,Ratio,a1,a2,a2ma1
*begin
C Here the use of Ratio with [] names.
B [b-a]
Z xxx = 1/[x+a]^3 * 1/[x+b]^2
Id,Ratio,[x+a],[x+b],[b-a]
P output
*yep
C Just checking...
Id,[x+a]^n~ = (x+a)^(3+n)*(x+b)^2/[x+a]^3/[x+b]^2
Al,[x+b]^n~ = (x+a)^3*(x+b)^(2+n)/[x+a]^3/[x+b]^2
Id,b = [b-a] + a
*end
*** Id,Spin,loop indices or momenta
This command is discussed in the section on particle physics.
*** Id,Stats,#
This commands provides for some statistics. The counts are printed at
conclusion of a section (delimited by a * type line). Four counts may
be kept, specified by the number # which may be absent implying 0, or
one of numbers 1, 2 or 3. No error message is given if the number exceeds
3 or is negative; Schoonschip takes the number modulo 4. Every time
this command executes one is added to the appropiate count. Example:
IF a^3
Id,Stats,2
ENDIF
This construction counts the number of terms with a^3. The result is
printed at termination.
13. PARTICLE PHYSICS.
There are a few build-in facilities that are particularly useful to particle
physics. We refer here to gamma-matrices and traces of products of gamma
matrices.
The special functions G,Gi,G5,G6,G7,Ug and Ubg are reserved to denote gamma
matrices and spinors. Since in a given calculation more than one loop of
gamma-matrices can occur all functions have a loop index. Gamma's with
different loop indices are supposed to commute. The relation to the standard
notation for these quantities is (old notation):
G(L,mu) gamma-matrix with index mu of loop L.
Gi(L) the identity matrix of loop L.
G5(L) = G(L,1)*G(L,2)*G(L,3)*G(L,4).
G6(L) = Gi(L) + G5(L).
G7(L) = Gi(L) - G5(L).
Ug(L,m,p) spinor loop L, particle mass m, momentum p, spin 1/2.
Ubg(L,m,p) Conjg{Ug(L,m,p)}*G(L,4).
Ug(L,mu,m,p) spin 3/2 spinor.
Ubg(L,mu,m,p) Conjg{Ug(L,mu,m,p)}*G(L,4)
With the Schoonschip version of Jan 1, 1989 new notations have been introduced
for the gamma matrices. The above notation is still accepted, but the new
is more flexible and we will use that.
In this new notation gammas have two loop indices. They may also have more than
one index. The order of these two-index gammas is immaterial; at some point,
when traces or spin summation or whatever is to be done (usually with the
command Gammas) the gammas are chained on the basis of these two loop indices.
Example:
Ug(i3,M,q)*G(i1,i2,mu)*G6(i0,i1)*Ubg(i0,m,p)*G(i2,i3,nu,al)
This will be chained into one gamma string (called G-string in the following):
Ubg(i0,m,p)*G(i0,"s,"6,mu,nu,al)*Ug(i0,M,q)
equivalent to the old sequence
Ubg(i0,m,p)*G6(i0)*G(i0,mu)*G(i0,nu)*G(i0,al)*Ug(i0,M,q)
This takes the pain out of the process of ordering the gammas.
Inside G-strings "4, "5, "6 and "7 may occur next to Gi, G5, G6 and G7 but
they mean the same.
An anti-particle spinor may be represented as a particle spinor with -m
instead of m. The G's satisfy the rule:
G(L,"s,"4,...,mu,nu,..) =
- G(L,"s,"4,...,nu,mu,..) + 2*D(mu,nu)*G(L,"s,"4,.....)
which is the usual anti-commutation rule. All G are treated by Schoonschip as
imaginary, which corresponds to a hermitean set. In complex conjugation
the order of the G is to be reversed (i.e. the order inside a G-string is
reversed). G5 is imaginary, G6 and G7 are each others complex conjugate.
The commands Gammas and Spin allow for reduction of a product of G's to
at most 2 G's, Trace taking and Spin-summation. The build-in equations
can handle 4-dimensional and N-dimensional situations, with ot without G5's.
The command
*** Id,Spin,L1,p,...
leads to spin summation. Schoonschip looks for pairs of spinors Ug and Ubg
with the same arguments except the loop index (one of the loop indices must
be mentioned in the list), and replaces such pairs by the appropriate
combination. Instead of a loop index also vectors may serve as identification.
With the command
Id,Spin,p
or
Id,Spin,L1
the expression
Ug(L1,m,p)*Ubg(K1,m,p)
is replaced by
- i*G(L1,K1,p) + m*Gi(L1,K1)
Similarly for spin 3/2 spinors:
Ug(L1,mu,m,p)*Ubg(K1,nu,m,p)
is replaced by:
{ D(mu,nu) - 1/3*i*G(L1,K1,mu)*p(nu)/m + 1/3*i*G(L1,K1,nu)*p(mu)/m
- 1/3*G(L1,K1,mu,nu) + 2/3*Gi(L1,K1)*p(mu)*p(nu)/m^2 }
* { - i*G(L1,K1,p) + m*Gi(L1,K1) }
The command Gammas can be used to do work on G-strings. See the section on
gamma algebra.
Example 27 gives the complete calculation for muon decay in the V-A theory.
It is not repreduced here.
The Compo command is very useful if one wants to calculate diagrams.
The possible vertices can be given in terms of X-expressions. For a
given topology one sums over all possible propagators. Separate examples
exist for such cases.
14. INTERNAL PROCEDURES.
Some insight in how all this actually works inside Schoonschip is really
indispensible, and this section provides for some details. An example (Example
28 followed by Example 29) shows how to do a problem that could easily explode
if not worked out carefully.
Consider the expression:
Z XX = (a*x^2 + b*x)*dx
The process starts with reading the input. The input is encoded, and placed
into memory. Names are placed in arrays. This encoding stops when the line with
the * is encountered. Then Schoonschip starts working out the Z expressions,
one after the other. This happens at Level 0. At Level 1 one term after the
other passes by. In this case the first term passing by is the the term
a*x^2*dx. No new term is emitted then till this term has passed 40 Levels, and
at each Level the user has the opportunity to work on that term. Then this term
is collected in the output store, a large area of more than 40 kbytes. There
are provisions for handling overflow of that area, but more about that later.
Only when that term is stored is the next term issued, here b*x*dx.
The advantage of this procedure is that virtually no storage is needed for the
intermediate results. Often symbolic programs work out the whole expression
before going to the next level. Then one finds inside the initial expression,
the expression as it becomes after the first Level, and so on. The same
expression, in various stages of processing may then be found many times in
memory. This leads very quickly to memory overflow, which is not easily
manageable.
On the other hand, when collecting terms in the output store a substantial
reduction in the number of terms may take place. For instance, to take a very
trivial example, the initial expression (a+b)^2 leads to 4 terms, and all of
these 4 terms go through all 40 Levels (actually Schoonschip notes how many
Levels are active, and skips the empty Levels). If one were to collect these
terms immediately after the first Level there will then only be three terms:
a^2 + 2*a*b + b^2. That is what happens at the output store: identical terms
are recognized, and the coefficients are added rather then keeping the terms
separately (here that applies to a*b). Thus term collecting will in general
lead to a reduction in number of terms, and in fact this is usually very
substantial.
This fact was of course quickly realized, and an option is available to do this
term collecting at any time inbetween the substitutions and commands. This is
done through the *yep line. When encountering this line Schoonschip processes
all substitutions up to that point and then collects all terms in the output
store. Next this output store is emptied on the disk, and then read in again,
term by term. Again each term then passes through all Levels, possibly to
another *yep, till all substitutions have been exhausted. It is up to the user
to put these *yep lines judiciously in case of a large problem.
As may be clear from the above this procedure has the added advantage that
after a *yep the full 40 Levels can be used again. Thus there is basically no
limit on the amount of substitution and commands that can be done.
The assignment of substitutions and commands is essentially automatic. The user
has a number of options here. Putting Id in columns 1-2 of a substitution
assigns that substitution to the next Level. The characters Al put the
corresponding substitution on the same Level. Thus substitutions that do not
interfere with each other can so be put on the same Level: the first has Id,
the second Al in columns 1-2. Also, one may want some substitution to be done
at a number of consecutive Levels. In such cases one simply places a number
after the Id or Al. Thus Id,7,... implies that the corresponding substitution
is inspected for at 7 consecutive Levels.
When reading the input Schoonschip prints the associated Level in front of the
line. To understand this numbering it must be realized that working out
brackets requires Levels, namely one Level per nesting. Thus in the last
example the first substitution is put at Level 2, because Level one is used to
work out the brackets. In fact, working out the brackets is very much like a
substitution; the initial expression is translated to something like $AAA^2,
where $AAA is a symbol invented for this purpose, and at Level 1 the
substitution
Id,$AAA = a+b
is placed. For this reason the $ symbol must not be used in names. This process
may be seen in detail by requesting printing of these $ expressions by means of
a P brackets directive. Also X-expressions may require Levels, they are like
build-in substitutions. As soon as an X-expression materializes at some Level
Schoonschip substitutes its definition.
To make the whole process transparant we will here reproduce the contents of
memory for a simple case somewhere in the middle of a calculation. Consider:
Z xxx = (a*x + b)*dx
Id,x*dx = (x2^2 - x1^2)/2
*end
Typically at some point the following may be found in memory:
Level 0: $AAA*dx
Level 1: dx and a*x + b
Level 2: dx*a*x
Level 3: a and $AAB/2
Level 4: 0.5*a and x2^2 - x1^2
Level 5: - 0.5*a*x1^2
Levels 6-40: skipped
In output store: 0.5*a*x2^2
At this point the action is at Level 5. A little time later the term
-0.5*a*x1^2 will arrive at the output store, and that exhausts the work at
Level 4. Then Schoonschip goes back to Level 1 and produces the next term,
b*dx. After that has passed to the output store (for simplicity we have not
included the substitution for this one) Schoonschip goes all the way back to
Level 0, finds that the problem is all done, and passes to the next stage,
namely printing of the contents of the output store.
This rather complicated procedure has the great advantage that only very little
memory is used at any one time. One finds bits and pieces all the way down from
Level 0 to the output store, and Schoonschip keeps on climbing up and down all
Levels till all work at all Levels is exhausted. In dealing with large problems
one must have some idea of this procedure in order to organize the calculation
in the most efficient way. Any substitution with more than one term in the
right hand side leads to multiplication of the number of terms generated with
some factor, depending on how many terms occur in that right hand side, and
also on how often the sustitution is actually done.
To see how much work is done by Schoonschip use the directive P stats. Then
some statistics are printed, of which in this context the most interes- ting
ones are the number of multiplications and the number of terms. One
multiplication is counted for every time two terms (not factors) are multiplied
together. Thus (a*x + b)*(c*x + d) implies four multiplications. Often the
count comes out higher than expected at first sight due to for instance the way
brackets are worked out. The number of terms is simply a count of the terms
that arrive at the output store. That would be 4 in this case. Another example:
(a + b)^4 leads to 2^4=16 multiplications, and then to 16 terms, and after
sorting in the output store one will have 5 terms. In actual fact, the count
for multiplications comes in this case to 81, but we will not bore the reader
to explain this in detail. Mainly this is because Schoonschip begins by setting
a 1 before getting to the actual expression. In practice the number of terms
and also the number of multiplications are a good indication of the complexity
of a problem, and the time needed is roughly proportional to these numbers. For
large expressions with many terms most time is spent sorting the terms in the
output store. Try to avoid more than 100,000 terms. If one gets in this kind of
situation it is necessary to examine in detail the organization of the problem,
and the separation in various parts using *yep. See also the sections on large
problem handling and file handling commands. The largest calculation done so
far involved as many as 1,000,000 terms, but it is not known how much diskspace
was used. The present version needs about 20 seconds for 10,000 terms or
100,000 multiplications, but this must be seen as a very rough low estimate. If
diskwriting is involved times may increase drastically. The calculation
mentioned used 20 minutes on a CDC 7600, but that was counting only cpu time,
not actual time. It would probably take many hours on a 68000, assuming enough
diskspace. The important point is of course that at least there is no
limitation due to Schoonschip itself, and given time and diskspace it will work
its way through. If P stats is specified it will print statistics every time
8192 (= 2^13) terms have passed through, so that one can see some action.
In particular series expansions where the argument expanded in is again a
series can very easily lead to an enormous number of terms. Suppose some
function, f(y), is given in terms of a series expansion, and suppose also y is
a series expansion in terms of a variable x. Now suppose that the series
expansion of f in terms of x up to x^10 must be found. If y is a polynomium
involving up to x^9, thus 10 terms, then substitution of this in y^10 leads to
10^10 terms, which would take roughly 20*10^6 seconds if nothing else would
grow out of bounds. Such problems must be worked out really carefully, and in
Examples 28, 29 we have reproduced a substantial part of such a problem, enough
to understand the principle.
15. CHARACTER SUMMATION.
Characters have become quite useful in generating diagrams. Typically
a character is associated with every particle in the theory. Anti-particles
have the same character as the particles but appended with an underscore
(_). Certain particles are their own anti-particle. There is a way to let
Schoonschip know which particles are their own anti-particle.
In generating diagrams one must first have a list of vertices. The name
for a vertex is composed of the characters that correspond to the particles
entering that vertex. In that name the characters must be ordered in a
well defined way: alphabetically, upper case before lower case before numbers,
characters with an underscore before those without an underscore. Thus:
A_AB_BC_C......Z_Za_ab_b...1_12_2... Here some examples:
AWW Aww U_U AG_G Ue_e Ubt_ U_b_t U
Vertices have indices and momenta as parameters. Four particle vertices
have no momentum dependence.
The list of vertices must be given in terms of X-expressions. Each vertex
must have sufficient parameters to cover all cases. For a given particle
one may have momentum, vector index and spinor index. Even if the vector
and spinor index will normally not occur simultaneously they need to be
carried along. A 3-vertex will thus have 9 parameters. Examples:
X U_UW(AL,al,P,BE,be,Q,GA,ga,K) =
C*D(AL,BE)*(Q(GA)-P(GA)) + C*D(AL,GA)*(P(BE)-K(BE)) +
C*D(BE,GA)*(K(AL)-Q(AL))
This is a vertex for three vector particles. The spinor indices al, be, ga
are not used. Here two spinor vertices:
X Ubt_(AL,al,P,BE,be,Q,GA,ga,k) = i*G(ga,be,AL) + avc*i*G(ga,be,AL,G5)
X Ue1_(AL,al,P,BE,be,Q,GA,ga,k) = i*G(ga,be,AL,G6)
Note that spinor indices usually appear in reverse order. This is the
vertex for a vector particle (charged W) coupling to a fermion and an
anti-fermion (bottom and top or electron-neutrino 1). Here a fermion
propagator:
X t_t(L1,l1,L2,l2,K)=NOM(K,Mt)*G(l2,l1,K) + NOM(K,Mt)*Gi(l2,l1)*Mt
NOM is the usual propagator factor, 1/[KDK + Mt^2].
In this way all vertices and propagators must be defined. Now suppose
some diagram must be calculated, say W selfenergy (the charged W's are
represented by U and U_). After the type declarations all vertices and
propagators must be given in terms of X-functions:
C Calculation of charged vector boson (U, U_) self-energy.
F Fx,F2,B22,B21,B1,B0,VE3,PROP
I AL=N,al,BE=N,be,GA=N,ga,MU=N,mu,NU=N,nu,MUP=N,mup,NUP=N,nup,
L1=N,l1,L2=N,l2,L3=N,l3,L4=N,l4,L5=N,l5,L6=N,l6,L7=N,l7,L8=N,l8,
L9=N,l9,L0=N,l0
I Mu4,Nu4
V P,Q,K
C The use of these character tables, the Anti statement and the G line will be
C explained below.
T TAP: W,Z
T TFE: t,b
Anti,TAP
G 1
X t_t(L1,l1,L2,l2,K)= i*NOM(K,Mt)*G(l2,l1,K) + NOM(K,Mt)*Gi(l2,l1)*Mt
X b_b(L1,l1,L2,l2,K)= i*NOM(K,Mb)*G(l2,l1,K) + NOM(K,Mb)*Gi(l2,l1)*Mb
G 3
X Ubt_(AL,al,P,BE,be,Q,GA,ga,K)= i*G(ga,be,AL,G6)
X U_b_t(AL,al,P,BE,be,Q,GA,ga,K)= i*G(be,ga,AL,G6)
X Wt_t(AL,al,P,BE,be,Q,GA,ga,K)= i*[1-8/3s^2]*G(be,ga,AL) + i*G(be,ga,AL,G5)
X Wb_b(AL,al,P,BE,be,Q,GA,ga,K)= i*[4/3s^2-1]*G(be,ga,AL) - i*G(be,ga,AL,G5)
G
C First establish the topology, for example the simple two 3-vertex, two
C propagator diagram. Note that no _ may be used in file names.
Z IUUB=SELF("U,"U_)
C Now a character summation. I1 is the given input character,
C in this case the "U representing the positively charged W.
C The sum in DS goes over all characters J1 and J2 such that the name
C U J1 J2 properly symmetrized corresponds to some X-expression.
C In this case that will only be some b, b_, t, t_ combinations for J1, J2.
C The symbol 'Sym' implies symmtrization factor based on the characters
C following. If they are identical (will not happen here) a factor
C 1/2! will be added.
C The subsequent numbers, 2,3,5,6, imply that only X-expressions in
C groups 2,3,5 and 6 will be inspected. That is then the meaning of
C the G lines above: they specify a group number for the X-expressions
C following. Default is 0, and if no groups have been specified all
C will be considered.
C Whenever a match is found a term in the summation arises: the
C function DIB with the characters I1, J1, J2 and I2 as arguments.
C The function DC is used for various purposes; here it provides
C a factor -1^1 if both characters J1 and J2 appear in table TFE.
C If one uses "F_ rather then "F the factor is provided none of the
C characters appear in the table TFE.
C The second number 1, the exponent, may be omitted and is then 1.
C This is the factor -1 for a fermion loop. The "F in the DC function
C stands for factor.
C Other uses for DC are summarized later.
Id,SELF(I1~,I2~)=
DS(I1;J1;J2;Sym;J1;J2,2,3,5,6,(DIB(I1,J1,J2,I2)
*DC("F,TFE,-1,1,J1,J2) ))
C This is essentially the diagram. Mu4 and Nu4 are the external U and U_
C indices, P is the loop momentum, Q is the U momentum and K = P + Q.
C The * are used by the command Compo. In for example VE3 that command
C re-arranges the characters I1, K1 and K2 in the character order defined
C before. Every interchange also gives rise to an interchange of the
C argument groups delimited by the *.
Id,DIB(I1~,K1~,K2~,I2~)=
VE3(I1,K1,K2,*,Mu4,mu,Q,*,L1,l1,-K,*,L3,l3,P)*
VE3(-K1,I2,-K2,*,L2,l2,K,*,Nu4,nu,-Q,*,L4,l4,-P)*
PROP(K1,-K1,*,L1,l1,K,*,L2,l2,K)*
PROP(K2,-K2,*,L3,l3,P,*,L4,l4,P)
C Compo searches the X-expression list for the names composed of the first
C few characters that appear as arguments of the functions VE3 etc. and if
C found keeps the term, else makes it zero.
Id,Compo,<X>,VE3,PROP
C Compo has now composed the name and performed the necessary symmetrization.
C Now the functions themselves can be substituted. AA is a dummy name here.
Id,VE3(AA~,MU~,mu~,P0~,L2~,l2~,Q~,L1~,l1~,P~)=
AA(MU,mu,P0,L2,l2,Q,L1,l1,P)
Al,PROP(AA~,L4~,l4~,Q~,L3~,l3~,P~)=AA(L4,l4,L3,l3,Q)
C At this point the full expression for the diagram has been obtained.
C The next step is to do the loop integral. The loop momentum appears
C in the propagators through the functions NOM, and as arguments in the
C Gamma matrices.
Id,Commu,NOM
Id,NOM(P,M~)*NOM(K,M0~)=F2(M,M0)
Id,Gammas,"C
C Remove K as G argument, replacing it by the four dimensional Q
C and the loop momentum P. No index is created by this work, and the
C dimensionality of MU is irrelevant.
Id,Funct,K(MU~)=P(MU)+Q(MU)
C Now collect all P in the function Fx.
Id,All,P,N,Fx
*yep
C The P-integration can be done:
Id,F2(M~,M0~)*Fx(MU~,NU~) = D(MU,NU)*B22(M,M0) + Q(MU)*Q(NU)*B21(M,M0)
Al,F2(M~,M0~)*Fx(MU~) = Q(MU)*B1(M,M0)
Al,F2(M~,M0~)=B0(M,M0)
C Do Anomalous traces.
Id,Gammas,"A
*end
In this case only one diagram is evaluated simply because there are no
more vertices listed. If a complete set of vertices is given the complete
result obtains.
Character tables.
Character tables are distinguished from other tables (that can be used as
function arguments) by means of the colon (:) following the name.
To every character possible there corresponds a location in the table,
zero by default. Any character mentioned gives a 1 and a -1 in the
location for its antiparticle (denoted by a appended underscore).
Specific numbers may be assigned, for example
T TAB: A=3:5,B=7,a,z=3
This assigns 3 to A, 5 to A_, 7 to B, -7 to B_, 1 to a, -1 to a_,
3 to z and -3 to z_.
Important: all numbers appearing in character tables must be short integers
(-129 < # <128).
The function DC uses such tables. Other character manipulations often
need a table to specify which particles are their own anti-particles.
Except for DC calculations such an anti-particle table may be given
before a *fix, and is then the default for the character function DS
and the command Compo for example. In all cases one may specify a
particular anti-particle table for the specific case: for DS as an
argument before the group numbers, for Compo anywhere in the list.
Anti statement and command. The Anti statement
Anti,TAA
establishes character table TAA as the default anti-particle table. This
is used by default by DS and Compo work. The statement may be given in the
fix section and is then valid by default for all other sections.
The command:
Id,Anti,TXX
leads to inspection of all function arguments. The table TXX is used to
determine which particles are their own anti particles, and correspondingly
a possible appended undescore is removed.
Character summation function DS.
General format:
DS(C1;C2;C3;..;Sym;C4;C5,..,TX,#1,#2,...,(Expression) )
^--^---^--^ ^ ^ ^
The ^ indicate optional arguments. The characters C1, C2 etc must be followed
by a semicolom; they may be characters, or else they are taken as dummies. A
preceeding - sign adds or removes an underscore. The summation goes over all
names that fit the name of an X-expression. For example, if C1="A and there are
two additional dummies mentioned then DS searches for all X-expressions with a
name of three characters of which one is an A. C2 and C3 become then the other
two characters and may as such be used in the Expression.
If the symbol Sym is mentioned then a symmetrization factor is provided
based on the characters following this symbol.
If a table TX is mentioned it is taken to be the antiparticle table, listing
all characters X for which X=X_.
If group numbers are specified only X-expressions in the groups mentioned
are considered.
Example:
DS("A;J3;-J3;"B;Sym;J3,-J3,2,(Dic("A,J3,"B) )
Every X-expression name containing characters of the form AXX_B (or AX_XB)
leads to a term in the sum. For example the following names fit the pattern
twice:
AEBE_ (with J3="E and J3="E_)
Z_ZAB (with J3="Z and J3="Z_)
The order of the characters in the name is not of importance here. This
order is however important when using the command Compo. That command
orders the characters before searching the namelists.
The character function DC.
DC always equals some numerical factor depending on the character arguments.
DC("F,TFE,#1,#2,C1,C2,...)
DC("F_,TFE,#1,#2,C1,C2,...)
The value of the DC is #1^#2 (if #2 absent is taken to be 1) provided all
characters C1,C2 etc appear in the table TX. Else it is 0. For "F_ the
other way around. Here an example of a character table TX:
T TFE: t,b
DC("P,TX,#,C1,C2,...)
Compute and multiply with a permutational factor determined by the occurence
of identical characters in C1, C2 etc. The number # is used as exponent.
For example, with the value 2 for # and the characters "A "A "A "B "B the
value (3!*2!)^2 obtains. The table TX lists particles that are their own
anti-particles (X_ = X). Here an example of such a character table:
T TAP: W,Z
DC("C,TX,C1,C2,...)
DC("C_,TX,C1,C2,...)
DC("T,TX,C1,C2,...)
DC("T_,TX,C1,C2,...)
Compute the sum of the 'charges' of C1,C2,.. as listed in table TX. If zero DC
is 1, else 0. If the character "C_ is used the opposite. If the character "T
is used keep the term if the sum is positive including zero. If "T_ is used
keep if < 0. Here an example of such a character table: 1 is assigned to
particle Z, and also 1 to its antiparticle Z_. If the second 1 is not
given it is taken to be the opposite of the first one (thus here -1) for the
antiparticle.
T TX: Z=1:1
16. GAMMA ALGEBRA.
The equations and algoritms used in this section will not be derived here.
The derivations can be found in a publication (M. Veltman, Gammatrica, 1989,
to be submitted to either Nuclear Physics or Computer Physics Communications).
The treatment of gammas has become quite complicated, but things have been
organized in such a way that for most cases the default options will do
the necessary. Essentially, other then four dimensional gamma algebra can
be done. It is nonetheless essential that a number of things are well
understood.
The only quantities for which other than four dimensionality can be specified
are indices. There is no way to specify the dimensionality of a vector, or
of a dotproduct. In doing gamma matrix manipulations Schoonschip takes
vectors to be four dimensional, i.e. G(L,p) contains only G(L,1) to G(L,4).
That might be seen as a restriction, but it is not. Refer to the "C option
discussed below.
The type of non-four dimensional vectors in the sense just mentioned occurring
in practice are loop momenta. There are several ways to deal with that.
The easiest way seems to be to first do the loop integrations before
doing the gamma algebra. First all gamma's are collected using the "C
option (see below), and then occurring loop momenta are replaced by four-
dimensional momenta or index pairs with N dimensional range. These can be
handled properly. For the moment it will be assumed then that all momenta
occurring as arguments of the gammas matrices are four dimensional, but
that indices may either be four or N-dimensional. No provisions have been
made to consider indices with ranges other then these two, although one
may use any algebraic symbol instead of N.
New notations have been implemented. Instead of one loop index the gamma's may
now have two loop indices. This very much eases the task of ordering the
gamma's properly when generating them by means of some automatic procedure.
Gamma's can be rounded up and put in the proper sequence on the basis of
the indices. The notation is:
G(i1,i2,mu), Gi(i1,i2), G5(i1,i2), G6(i1,i2), G7(i1,i2)
Gi is the unit matrix. The meaning of G6 and G7 is as before:
G6 = Gi + G5, G7 = Gi - G5.
The ordering is based on the indices:
G(i1,i2,mu) * G(i3,i4,nu) * G(i2,i3,al) = G(i1,i4,mu,al,nu)
which is about the same as the old notation
G(L,mu)*G(L,al)*G(L,nu)
One may in fact directly use the multi-index notation G(i1,i3,mu,al,nu).
It actually was used internally (but with only one loop index) since a long
time. Also Gi, G5, G6 and G7 may appear in that list:
G(i1,i2,mu,G5,al,be,G6,ga,Gi,la,G7)
A string is called a trace if the first and second index are the same.
Otherwise the expression is called a gamma string, or shortly string.
A string may be odd or even depending on the number of arguments not counting
Gi, G5, G6 and G7. Thus the last shown is an odd string. Traces of odd strings
are always zero.
To avoid prolifiration of indices one may preferably use integer numbers
instead. For example:
G(1,2,mu) * G(3,4,nu) * G(2,3,al) = G(1,4,mu,al,nu)
When dealing with more then one string number ranges may be reserved for
the different strings, thus avoiding confusion. Example:
X Vert(n,mu) = G(n,n+1,mu,G6)
Z xx = Ubg(1,mm,p)*Vert(1,mu)*G(2,3,nu)*Ug(3,mn,q)
* Ubg(10,mn,k)*Vert(10,mu)*Ug(11,me,qq)
When starting work on gamma matrices Schoonschip begins by rounding up the
gammas. For two index gammas the ordering is determined by the indices.
For gammas with one index (the old notation) the ordering is based on the
order in which they appear in the expression considered. By default the
strings are normalized, i.e. direct neigbour equal arguments are eliminated
( G(....,X,X,...) = D(X,X)*G(........) ) and traces of an odd number of
gammas (not counting G5 etc) are set to zero. Optionally that normalization
may be suppressed.
After rounding up the strings and traces appear with only one loop index.
The index is chosen from the indices seen: the smallest number (or earliest
mentioned index) is taken. Indices are 'smaller' then numbers.
G(1,2,mu,al) * G(3,4,nu,G5) * G(2,3,la) =>
G(1,"s,"4,mu,al,nu,G5,la)
The character argument "s indicates a string rather then a trace. The "4
is the unit G matrix, the need for this argument will become clear below.
The 1 is now the loop index. Another example:
G(i1,2,mu,al) * G(3,i1,p,G5) * G(2,3,la) =>
G(i1,"t,"4,mu,al,p,G5,la)
For brevity these objects will be called G-strings in the following.
The arguments may be indices, vectors or Gi-G7.
At this point there are now two types of G strings, namely "s or "t strings.
This very first phase of the work is called collecting. Normalization is
optional. Optionally one may stop the work at this point.
The next step is to apply all the known algorithms to these objects.
Optionally one may specify which strings should be worked on, either by
a specific loop index or by number range. More about that below.
Schoonschip starts by considering all arguments in the G-string. If
all indices have the (default) range 1-4 then the string becomes a four-
dimensional G-string. Occurring vectors are considered four dimensional.
If a string becomes four dimensional the character argument "s or "t is
changed in "S or "T. Some work is done on the strings:
- adjacent identical arguments are eliminated. This includes for traces
first and last argument.
- for "S and "T strings the G5, G6 and G7 are anti-commuted to the
left and the result is placed instead of the "4 argument.
- simple cases such as the trace of the identity are completely worked out.
Examples:
I mu,nu,al=N,be=N
G(1,"s,"4,mu,nu,al) => unchanged.
G(1,"t,"4,mu,nu,al) => 0 (odd trace).
G(1,"s,"4,mu,al,al,nu) => N * G(1,"S,"4,mu,nu)
G(1,"t,"4,mu,al,be,mu) => 4 * G(1,"t,"4,al,be)
G(1,"t,"4,G5,mu,G6,nu) => G(1,"T,"6,mu,nu)
=> 4 * D(mu,nu)
G(1,"s,"4,G5,mu,G6,nu) => G(1,"S,"6,mu,nu)
=> G(1,"S,"4,mu,nu) + G(1,"S,"5,mu,nu)
The last step belongs also to the class of doing simple cases. The expansion
of G6 would not have been done if there had been more index arguments.
Optionally one may stop the work here.
The next step is sum-splitting. N-indices in "s or "t strings are split
in a four dimensional and an N-4 dimensional part. As a convention the
quantity N_ is understood and used as N-4. Here are the equations for
the case of two index pairs:
I mu,nu,al=N,be=N
G(1,"s,mu,nu,al,be,..,al,be) =>
G(1,"S,mu,nu,al,be,..,al,be)
+/- G(1,"s,"_,be) * G(1,"S,mu,nu,al,..,al)
+/- G(1,"s,"_,al) * G(1,"S,mu,nu,be,..,be)
+/- G(1,"s,"_,al,be,al,be) * G(1,"S,mu,nu,..)
The sign is determined by the convention that the indices to be split are first
moved to the very left. They are taken to anticommute with all four-dimensional
indices and vectors, and to commute with G5, G6 and G7. Optionally, for traces
containing an even number of G5 or for strings independent of the number of G5
one may specify anticommutation with G5. In that case G6 and G7 are expanded
before the sum-splitting is done. For traces with an odd number of G5
commutation is used even if the anticommutation option is specified, simply
because the trace is otherwise not well defined. The outcome would not be
invariant for a cyclic rotation of the arguments.
Note the "_ character argument. The range of the indices in an "_ string
is from 4 to N. Both the string and trace of the unit "_ are one:
G(1,"s,"_) = 1
G(1,"t,"_) = 1
Other then that "_ strings are treated as the other non-four dimensional
strings. For example elimination of a direct pair:
G(1,"s,"_,...,al,al,...) = N_ * G(1,"s,"_,.....)
Sum-splitting requires that all N-indices occur in pairs. This no real
restriction as the pairs need not to occur in one and the same string,
but for example one index may occur in a string and the other in another
string or even some other function.
If a string contains only N-range indices then it is called pure, and
no sum-splitting is done. Index pair eleimination and trace evaluation are
done directly on such a string.
Sum-splitting is done by default. Optionally work may be stopped here.
The next step is the unification of G-strings. By default this is not done,
because it is not always advantegeous, and because it may be necessary to
indicate explicitly which strings are to be unified. The unification is
based on the Chisholm's equation:
G(1,"X,a1,a2,...,mu,b1,b2,...) * G(2,"T,mu,c1,c2,...,cn)
= 2 * G(1,"X,a1,a2,...,c1,c2,...,cn,b1,b2,...)
+ 2 * G(1,"X,a1,a2,...,cn,...,c2,c1,b1,b2,...)
where "X may be "S or "T. The application requires
- the G-strings involved must be four-dimensional.
- they must have one index in common (mu in the above).
- at least one of them must be a trace.
The general rule is that it is advantageous if the G-strings have other
arguments then the explicitly shown index in common. That may be either
vectors or indices. Thus there is an advantage if for example c1 and b1
are the same, because in the second term that can be worked out.
This work is called unification, and optionally one may stop the work here.
The next step is to eliminate index pairs in the G-strings. For four-
dimensional strings there is the Kahane algorithm which eliminates all
pairs in a given string in one sweep, for "s and "t strings there is a
single pair algorithm that can be applied repeatedly. This is done by
default. One may specifically allow or inhibit index pair elimination
in _ type strings seperately. Optionally one may stop the work here.
The next step is the elimitation of vector pairs in four dimensional strings.
This is also a single pair algorithm that can be applied repeatedly.
It is called the P-algorithm. Optionally one may stop the work here.
The final step is to actually evaluate the traces, and to reduce the
four dimensional strings to a standard form. This is called the W-operation
(for final work).
In summary, the following is done:
- Rounding up of all strings. This step cannot be avoided. All occurring
G are rounded up, even those that are not to be worked on. By default
the strings are normalized.
- Sum-splitting. By default. With optionally Anticommuting G5 if an even
number of G5 present.
- Unification. Not done by default.
- Index pair elimination, also for pairs in _ type strings (the latter
may be inhibited with the i-option) Done by default.
- P-algorithm for four dimensional strings. By default.
- Work: final traces and reduction for four dimensional strings.
The options are characterized by a character, namely N, A, S, U, I, P and W.
The command for all this is
Id,Gammas
By default work is done on all occurring strings. For most cases, using
the two-index G notation this will do. If there are single index G's
(the old notation) then it must be possible to specify which are strings
and which traces. By default they are taken to be strings. If a trace is
intended loop indices must be mentioned:
Id,Gammas,Trace,i3,i4
In strings i3 and i4 the "s is replaced by "t.
As soon as one or more specific index is mentioned in the Gammas command only
loops with the loop indices as occurring in the list will be worked upon.
For any individual loop index options may be specified. Options may be on
or off. The are turned on by the appropriate character argument, and turned
off if the argument is followed by an undersore (_). Furthermore one may,
in case numbers are used as loop indices, indicate a range of loop numbers.
Here is the syntax:
Id,Gammas,C1,C2,i1,1-4:C3,C4,Trace,i2:C4,C5,i3,9-10
C1, C2 etc are character arguments, either one of these:
"N "N_ "A "A_ "S "S_ "U "U_ "I "I_ "P "P_ "W "W_ "i "i_
In addition there is the option "C. It is synonym for turning all
options except "N off, i.e. only collecting and normalization is done,
with the further difference that no specialization to four dimensions
is ever done. This is very essential if there is some integration vector
where this vector is not four dimensional. Typically, if n-dim integration
is to be done one first collects all G with the "C option, then the
integrations are done, and after that the remaining work can be
done through another Gammas command.
To avoid normalization specify "N_ in addition to "C.
The first mentioned character arguments define the default. If none is
mentioned the default is "N,"A_,"S,"U_,"I,"P,"W,"i. The "i refers to index
pairs in N_ (i.e. "_) type strings.
G strings with loop indices mentioned after the Trace argument are forced
to be traces ("t).
A loop index may also be specified by a number range. Any G-string with a
loop index within the range (inclusive the values mentioned) are considered.
If the loop index or the range is followed by a colon then the following
character arguments define the options for specific loop. Those options
override the default options.
Example:
Id,Gammas,"A,"U,1-9:"A_,10-20:"U_,"I_
Strings with loop indices 1-9 and 10-20 are considered. Unification is
attempted on loops 1-9. Loops 1-9 have commuting G5 with respect to
sum-splitting, 10-20 anticommuting for traces with an even number of G5 or
strings for any number of G5. No index pair elimination is attempted on 10-20
loops, but index pairs in N_ type strings are still worked on. To inhibit that
a "i must be mentioned in addition.
Please note the use of the colon (:). This is because at least in principle it
is not excluded to also use character arguments as loop indices for two-index G
(they are inbetween numbers and indices with respect to ordering). Several
characters are illegal in this respect: "S,"T,"s and "t, at least if they occur
as the second argument in a two-index G.
As noted before, in all gamma operations all vectors are considered four-
dimensional. There are at least two ways to handle things. Commands to
simplify the work have been introduced.
Consider a case in which there occurs some momentum p is to be integrated
over N-space, and suppose this p occurs as G argument:
G(1,2,al,be,p,al,be,p)
(the two index notation is and will be used from now on). The first step is
to get the p out. A new command, essentially a combination of existing
commands can be used here:
Id,All,p,N,F
In this command p is a vector, N is an optional argument specifying the
range of the indices to be created, and F is a function defined in an
F-list. This command rounds up all p, also those occurring in functions and
dot-products, and collects them in the function F. Example:
V p
F F
S N
Z xx = pDq*pDp*F1(aa,bb,p)*p(mu)
Id,All,p,N,F
*end
This is the output:
xx = + F1(aa,bb,Naa)*F(Naa,mu,q,Nab,Nab) + 0.
In here the quantities Naa and Nab are created indices with range N.
If one substitutes
F(i1~,i2~,i3~,i4~,i5~) = p(i1)*p(i2)*p(i3)*p(i4)*p(i5)
then the original expression re-emerges. This may actually be done
more easily with the command Iall, the inverse of All:
Id,Iall,p,F
searches for F and restores to the original expression.
Both All and Iall have also another syntax, see the description elsewhere
as well as the example further down.
The All command may now be used to eliminate the p from the G-string. Next
integration may be done, for example:
Id,F(i1~,i2~) = D(i1,i2)*F20(k) + k(i1)*k(i2)*F22(k)
where k is a four-dimensional vector. After this gamma work may be done.
Here is the full example with output:
I al,be,mu,nu
S N,N_
V p,k
F F,F20,F22
Z xx = G(1,1,al,be,p,al,be,p)
Id,All,p,N,F
Id,F(i1~,i2~) = D(i1,i2)*F20(k) + k(i1)*k(i2)*F22(k)
Id,Gammas
*end
xx = + F20(k) * ( 64 - 32*N_ ) + F22(k) * ( 16*kDk )
It should be emphasized that the symbol N, occurring in the All command
must be defined in the symbol list, together with the symbol N_. If
such a symbol occurs already as range in an index list this is done
automatically, but in this case that did not happen. The command All
will not work otherwise. Also p and F must have been defined before,
either implicit or explicit. N cannot be defined implicit, because
it would be taken as an index rather then an algebraic symbol.
Again, N_ is supposed to be N-4.
The command All is really a combination of three existing substitutions,
namely
Id,p(mu~) = ...
Id,Dotpr,p(mu~) = ...
Id,Funct,p(mu~) = ...
In addition All handles the creation of the function F with its undetermined
number of arguments smoothly.
The substitutions shown have been modified slightly. Now the range of the
index mu is taken into account. If an index is created in the course of the
work for these substitutions it is given the range of mu.
The second method for dealing with vectors in G-strings is as follows. Let
there be a string containing several vectors as aguments:
G(1,1,mu,G5,p,q,nu,G5,q,p)
Now use command All specifying the function G rather then the vector p:
Id,All,G,N,F
Again, N, N_ and F must have been defined before. This command takes
out all vectors from the specific function mentioned (here G) and collects
them, together with the indices created, into the function F1:
F F1
I mu,nu
V p,q
Z ft = G(1,1,mu,G5,p,q,nu,G5,q,p)
Id,All,G,N,F1
*end
The result is:
ft = + G(1,1,mu,G5,Naa,Nab,nu,G5,Nac,Nad)*F1(p,q,q,p,Naa,Nab,Nac,Nad)
Now the gamma work can be done. The result is rather messy, and it is displayed
here (slightly edited) for a simpler case:
F F1
I mu,nu
V p,q
A N,N_
Z ft = G(1,1,mu,G5,p,nu,G5,q)
Id,All,G,N,F1
P output
*yep
ft = + G(1,1,mu,G5,Naa,nu,G5,Nab)*F1(p,q,Naa,Nab)
Id,Gammas
P output
*yep
ft = + 4*F1(p,q,Dim_N_,Naa,Dim_N_,Naa)*D(mu,nu)
+ 4*F1(p,q,Dim_4,mu,Dim_4,nu)
+ 4*F1(p,q,Dim_4,nu,Dim_4,mu)
- 4*F1(p,q,Dim_4,Naa,Dim_4,Naa)*D(mu,nu) + 0.
As is clear Schoonschip has added on prefixes to the indices inside
the function F1 to show the range. The function F1 with those prefixes
cannot be handled by any substitution or command except the command
Ndotpr, specially created for this situation. It works out the F1
arguments and creates various symbols analogous to dotproducts (but
they are not, they are symbols) showing the summation range:
Id,Ndotpr,F1
P output
*end
ft = 4*p(mu)*q(nu) + 4*q(mu)*p(nu) + D(mu,nu) * ( 4*pq_ - 4*pq4 ) + 0.
In here pq_ means the dotproduct of p and q but only components 4 to N
enter in the dotproduct. Similarly pq4 denotes a dotproduct with only
the first four components entering. Obviously pq4 + pq_ = pDq, where
pDq is the normal dotproduct.
The symbols pq_ and pq4 are algebraic symbols. They are created during
execution, and if a symbol list is asked for in a subsequent section
(after another *yep for example) the A-list would be:
A i=i, N, N_, pq_, pq4
Just for curiosity: if the A option had been specified in the Gammas
command the term pq_ would have come out with the opposite sign. That
is because there is one G5 inbetween p and q.
Here is once more the example, but without the intermediate printing:
F F1
I mu,nu
V p,q
A N,N_
Z ft = G(1,1,mu,G5,p,nu,G5,q)
Id,All,G,N,F1
Id,Gammas,"A
Id,Ndotpr,F1
*end
ft = 4*p(mu)*q(nu) + 4*q(mu)*p(nu) + D(mu,nu) * ( - 4*pq_ - 4*pq4 )
This concludes the discussion. For the rest of this section some more
examples.
C G collection including spinors.
I mu=N,nu=N
V p,q
Z xx = G(i1,i2,mu)*G(i2,i3,nu)*Ubg(i1,M,p)*Ug(i3,M,q)
Id,Gammas,"C
*end
xx = + Ubg(i1,M,p)*G(i1,"s,"4,mu,nu)*Ug(i1,M,q) + 0.
C No problems with complex conjugation:
I mu=N,nu=N
V p,q
Z xx = Conjg( G6(i0,i1)*G(i1,i2,mu)*G(i2,i3,nu)*Ubg(i0,M,p)*Ug(i3,M,q))
Id,Gammas,"C
*end
xx = + Ubg(i3,M,q)*G(i3,"s,"4,nu,mu,G7)*Ug(i3,M,p) + 0.
where a G6 was included.
A string containing only N-indices is called pure. All index pairs can be
eliminated, and traces can be evaluted completely. Here an example
involving a string and a trace:
I mu=N, nu=N, al=N, be=N, ga=N
Z xx = G(i1,i2,mu,ga,nu,al,be,ga)
+ G(i1,i1,mu,ga,nu,al,be,ga)
Id,Gammas,"C
P output
*yep
xx = + G(i1,"s,"4,mu,ga,nu,al,be,ga) + G(i1,"t,"4,mu,ga,nu,al,be,ga)
Id,Gammas
*end
xx = + D(mu,nu)*D(al,be) * ( 8 - 4*N )
+ D(mu,al)*D(nu,be) * ( - 8 + 4*N )
+ D(mu,be)*D(nu,al) * ( 8 - 4*N )
+ G(i1,"s,"4,mu,nu,al,be) * ( - N_ )
- 2*G(i1,"s,"4,mu,be,al,nu) + 0.
Except the pair elimination nothing has been done about the string. One could
actually bring the strings into some normal form, but the advantages of that
are unclear, and it is also dubious as to what is the best normal form. The
work involved and the number of terms generated is considerable. For this
reason nothing has been implemented. But a possible way will be discussed now.
Define the function AG to be totally antisymmetric in all its arguments
except the first which is the loop index. If the number of arguments beyond
the first is m it is equal to the totally antisymmetric combinations of m
gammas divided by m!. Examples:
AG(L) = Gi(L)
AG(L,mu) = G(L,mu)
AG(L,mu,nu) = 1/2 * { G(L,mu)*G(L,nu) - G(L,nu)*G(L,mu) }
AG(L,mu,nu,al) = 1/6 * { G(L,mu)*G(L,nu)*G(L,al) - .... }
:
:
Any string can be written as a linear combination of such functions AG:
G(L,"s,m1,m2,m3,...) = a0*AG(L) + a1*AG(L,n1) + a2*AG(L,n1,n2) + ...
For example:
G(L,"s,"4,mu,nu) = D(mu,nu)*AG(L) + AG(L,mu,nu)
For the case of three indices:
G(L,"s,"4,mu,nu,al) =
D(nu,al)*AG(L,mu) - AG(L,nu)*D(mu,al) + AG(L,al)*D(mu,nu)
+ AG(L,mu,nu,al)
The number of terms increases faster then the number of terms for a trace.
For four indices the number of terms is 10 (3 for a trace), for five it is 11
and for six it is 76 (15). Here a program that computes this expansion for the
case of four indices (where only a0, a2 and a4 are non-zero):
I mu=N, nu=N, al=N, be=N, b1=N, b2=N, b3=N, b4=N
Z xx = { 1/(4*DB(4)) * G(L,"t,"4,mu,nu,al,be,b1,b2,b3,b4)} * AG(L,b4,b3,b2,b1)
+ 1/(4*DB(2)) * G(L,"t,"4,mu,nu,al,be,b1,b2) * AG(L,b2,b1)
+ 1/4 * G(L,"t,"4,mu,nu,al,be) * AG(L)
Id,Gammas
Id,Asymm,AG,2,3,4,5,6
*end
Note that AG was specified to be anti symmetric in more arguments then actually
occur. The excess is simply ignored by Schoonschip.
The time involved is considerable because of the large traces to be computed.
For six indices the time to evaluate AG is about 150 seconds (M68000).
The method shown is however not the most efficient.
17. R-INPUT.
Sometimes it is desirable to work on a very large input expression, larger
than Schoonschip can accomodate in its input space. The R-input facility
is designed specifically for this purpose. More precisely, it is geared
towards input that is exactly of the form as normal Schoonschip output.
Put an R in column 1 of the line with the file name; Schoonschip
will read the subsequent input and transform it into the same format
that is used in *yep situations. After a subsequent *yep the expression
can be worked on. As an example consider a case given before producing the
output
xxx = + [b-a]^-1
* ( [x+a]^-1 - [x+b]^-1 ) + 0.
To be sure that all symbols have the same meaning specify the P lists
option in the problem that produces that output, and include these
lists in the new input. Then put an R in column 1 and a blank in column 2
of the line with xxx:
A i=i, [b-a], [x+a], [x+b]
F D, Epf=i, G=i, Gi, G5=i, G6=c, G7, Ug=c, Ubg, DD, DB, DT, DS, DX,
DK, DP, DF=u, DC
R xxx = + [b-a]^-1
* ( [x+a]^-1 - [x+b]^-1 ) + 0.
*yep
Id,[b-a]^-1=bma
*end
There is no limit on the length of the expression other than available
disk space.
R-input can be very useful if one wants to edit expressions or process
parts of large expressions. It may also be used effictively to compare
outputs. To this purpose put the secons expression behind the first
but put an M (for minus) in column 1 rather then an R:
A i=i, [b-a], [x+a], [x+b]
F D, Epf=i, G=i, Gi, G5=i, G6=c, G7, Ug=c, Ubg, DD, DB, DT, DS, DX,
DK, DP, DF=u, DC
R xxx = + [b-a]^-1
* ( [x+a]^-1 - [x+b]^-1 ) + 0.
M xxx = + [b-a]^-1
* ( [x+a]^-1 - [x+b]^-1 ) + 0.
*yep
B [b-a]
*end
18. STATEMENTS. CONDITIONAL INPUT READING.
Several statements have already been mentioned before. Here is the complete
list.
Showl Show some statistics of large disk files being written.
Nshow Switches Showl off.
Write fname Write all common files to disk file fname.
Enter fname Enter common files from disk file fname.
Bdelete b1,.. Delete blocks
Read fname Start reading external file fname.
End End of an external file.
Screen Print in output lines up to 80 characters (default).
Lprinter Print in output lines up to 130 characters.
Anti TX Defines character table TX to contain the default anti-
particle list. May appear in *fix section.
Beep options
If no options all beep requests are cleared.
If #,t issue # beeps at termination.
If #,* issue # beeps when concluding a section (* delimited).
If #,e issue # beeps in case of an error.
Common ... Common declaration.
Delete ... Delete files.
Directory Defines directories to be used for large files. See section
on file handling.
Digits Defines number of digits to be printed for floating point
numbers.
Dryrun # Do a 'dry run'. Print at most # terms at completion.
External fnam Read fnam into memory. Command Extern executes that file.
Fortran type output has been shown to need often considerable editing.
The section of Schoonschip producing this has been rewritten. By default
the fortran output has only complete terms on any given line (if possible)
rather then the compressed form desirable in the old days when cards were
used. The compressed form is still available though. In addition, one may
specify how many continuation lines any given statement may have. Also
one may direct Schoonschip to place brackets around negative exponents.
Finally one may optionally direct Schoonschip to supplement every integer
with a decimal point, as some Fortran compilers require this.
All this may be achieved with the Fortran command. Every item is optional,
the defaults being: no compression, 9 continuation lines/statement, no
brackets, no . in integers, fortan type output.
Fortran #,Brackets,Compression,.,A
Only the first character of Brackets and Compression is significant and may
be lower or upper case. A minus sign in front of Brackets, Compression or .
switches back to the default, for example Fortran -Brackets instructs
Schoonschip not to put brackets around negative exponents.
The exponent of a number is normally shown using the character E (e.g.
1.23E+10). If a number of digits (Digit statement) larger than 5 has been
specified then D will be used instead (1.23D+10).
Finally, to specify output for the A-compiler mention the character A
on the Fortran statement.
Freeze xfile Freezes file xfile. See section on large problem
handling.
Keep fil1,... Keep files over a *next
Large # # is a number in the range 1 to 5 inclusive. Default is 2. It
specifies the number of intermediate output files to be used
for large file sorting. See section on file handling commands.
Maximum # Specifies the maximum size of intermediate output subfiles.
Default is 110 000. See section on file handling commands.
Names fname Enter names of a common file.
Nprint fil1,.. Do not print file1,..
Oldnew xx=yy Renames a quantity.
Outlimit # Sets a limit of # bytes on disk usage. In case of large file
usage this sets the limit on total disk space used for the
intermediate output files. Default: 500 000 = 0.5 Mb.
Overflow off Suppresses short number (exponents, function arguments)
overflow error trapping. May appear in *fix section.
Overflow on Reactivates overflow error trapping.
Print ... Specifies files to be printed.
Precision #
This specifies the precision required for dealing with numbers. This number #
applies internally at various instances. In the output two terms are taken to
cancel if the addition gives a cancellation up to # digits. Comparing numbers
with the Coef command uses the precision criterium. Also, when writing terms to
disk every number is truncated to 10 digits if # above is 9 or less. This saves
considerably on disk space. The default is 22 digits.
Progress In case of no output to the terminal print a . to the
terminal every 128 terms to show progress.
Punch ... Specifies files for which fortran output must be made.
Rationalize #
Schoonschip by default tries to rationalize numbers. The number # specifies
to how many digits the numbers must agree. For example, Schoonschip will
rationalize Pi = 3.141592654.. to 22/7 = 3.142857143... if 3 is specified.
Specifying 5 gives 355/113 = 3.14159292... which actually agrees 7 digits.
It should perhaps be noted that after every rationalization Schoonschip
actually performs the division and compares the result with the input number,
just to be sure. If 0 is put for # no rationalization is done. The default
is 22 digits, with check up to 26 digits.
Round on Numerical expressions as function arguments to be converted
to short integers are normally obtained by truncation. If
Round on the number is rounded to nearest integer. Round
off resets to the default, truncation.
Silence Instructs Schoonschip not to print "Ready" to the screen and
wait for an answer for certain PC's that normally clear the
screen immediately at termination.
Sum ... Specifies indicies to be summation indices.
Synonym name1=name2
Every occurrence of name1 between single quotes is replaced
by name2. This is very much like replacements of BLOCK
arguments, except that it is not limited to a block.
The end of the range of validity of some set of synonyms is
defined by the synonym statement without any arguments.
At most 16 synonyms allowed.
Traditional Do traditional sorting. See section on file handling commands.
The conditionional input reading statements may be used to formulate small
variations on a given problem. The idea is to define some parameters in the
beginning of a problem, and then to read input as a function of those
parameters. Many variations upon a given problem can then be run simply
by changing a few parameters in the beginning.
The parameters are called _Sw0 to _Sw9 and their default values are 0.
The initial value of the parameter _Sw0 may actually be set on the command line
when invoking Schoonschip. To this purpose use the notation S=#, where # must
be a number in byte range (-128, 127). Example:
Schip S=7 Ifile
The initial value of _Sw0 will be 7.
The _Swx may be changed by means of a Set statement. The syntax is:
Set _Sw? = expr
with ? a number in the range 0 - 9, and expr a simple numerical expression
(see below) in byte range, i.e. -128, 127. Example:
Set _Sw3 = 7
Every occurrence of _Sw3 is replaced by the number 7. This includes actual
occurences within any given expression, for example
... a^_Sw3 ...
is read as a^7. Other example:
Set _Sw5 = _Sw5 + 1
In addition the variables _Sw0 - _Sw9 may occur in a Gotoif (or Gotoifn)
statement. Here is the syntax:
Gotoif expr1, expr2 ? expr3
Expressions expr1, expr2 and expr3 must be simple numerical expressions,
defined below. They evaluate to a number. Expr1 must evaluate to a number
in the range 0 - 99. The other two expressions are evaluted on a 16 bit
basis (range -32000, 32000). The question mark ? may be >, < or =. The
expressions are compared and if the condition is true all following lines
are skipped until a line with an @ symbol in column 1 is seen. This @
symbol may be followed by a number, and if this number is equal to the
value of expr1 the skipping stops, else continues. If there is no number
after the @ symbol the skipping stops always.
The statement
Gotoifn expr1, expr2 ? expr3
is analagous to the above except that the skipping starts if the condition
is not true. Finally
Goto expr1
leads to an unconditional start of skipping.
The expressions may contain numbers separated by the operators + - | & * and /.
The operator | stands for logical OR and & is the logical AND. Precedence: +
etc as usual, | as +, & as *. The division is integer division, for example 3/2
equals 1. Furthermore the variables _Sw0 to _Sw9 are considered to be numbers
with whatever value that they have been set to (zero initially).
Here is a simple example, showing also the use of the Synonym statement:
Synonym Xxx = _Sw0
Set _Sw9 = 3
Set _Sw1 = 2-3*(22/2-4)
Set _Sw2 = 2-(22&2-4)*_Sw9
Set _Sw3 = 6
Set _Sw4 = 1 | 0x20
Z xx = (a + b) ^ 3 + a0^'Xxx' + a1^_Sw1 + a2^_Sw2 + a3^_Sw3 + a4*_Sw4
Gotoif 20, _Sw3 > 5
Id, b = 20*c
Goto 21
@20
Id,b = a + c
@21
*begin
Here is the output in case the value 62 was specified as initial value for
_Sw0, by means of a command line specification: Schip S=62 ... If no S=#
parameter present on the command line the value of _Sw0 would have been 0
giving 1 instead of a0^62.
xx = a0^62 + a1^-19 + a2^8 + a3^6 + 3*a4 + 6*a*c^2 + 12*a^2*c + 8*a^3 + c^3
Note the notation for a hexadecimal number, 0x20 (= 32 decimal). An OR with 1
produces 0x21, i.e. 33 decimal. The AND of 2 with 22 is 2 (in hexadecimal 22 =
0x16, which gives 0x02 when AND'ed with 0x02).
In the above case, since the condition is true, skipping starts immediately
after the Gotoif statement, and continues till the line with @20 is met. Thus
the problem reads:
Z xx = (a + b) ^ 3 + ...
Id,b = a + c
*begin
If _Sw3 is not set, or set to some value equal or less than 5 the problem
will be read as
Z xx = (a + b) ^ 3 + ...
Id, b = 20*c
*begin
Use of
Gotoifn 20, _Sw3 < 6
instead of the earlier Gotoif statement would give the same results.
If no skipping is going on lines with an @ in column 1 are ignored.
19. LARGE PROBLEM HANDLING.
Considerable attention has been focussed on the question of large output.
The traditional output sorting method of Schoonschip is inadequate for
truly large problems, with more then 50 0000 terms in the output.
Moreover, as small computer systems do not have infinite large disk
space (typically 20 Mb) a method economizing on that is important.
The traditional system works as follows. Generated terms arrive at the
sorting routine and are compared with the terms already present in the
output store. If found, coefficients are added. If not found, and there
is space left the term is entered in the output store. Else the term
is simply written to disk, and further adding of terms to the output
store is inhibited. This method is quite wasteful as far as disk space
is concerned. The timing depends crucially on the disk system, and
is generally slow.
The new method uses up to five output files. If the output store is full
the content of the output store is dumped on, say, file1, and sorting
resumes. If again the output is full the store is dumped on, say, file2,
etc. If the maximum number of files is reached then merging is done
rather then straight dumping. Assume for example that a maximum of three
output files has been specified. Assume now that already three files,
file1, file2 and file3 have been created. At this point, when the output
store is again full, a merge takes place. The smallest file (say file2)
is selected, and merged with the contents of the output store to a
new file, called file2a (for example, naming conventions are given below).
And so on. When the whole problem is finished there are then three
possibly very large files. As a final step these three files are
piecewise merged into the output store and printed etc.
With this method the disk usage is already considerably less than with
the traditional method, because only sorted expressions are written
to disk. Still, the disk use may be quite more than the final size of
the result; each of the above three files may well be of the order of
magnitude of the final size.
If disk space is really crucial then the above method may be used
specifying usage of only one file. The first overflow produces the
file. The second produces a merging of the file and storage, giving
rise to a new file. Disk usage is maximum at the moment that the last
part of the original file is read, and the new file is almost written
out. That disk usage is then about twice the size of the final result.
To deal with this final factor of two a fractured file system has been
implemented. A fractured file is a file split up in smaller files.
Each of these smaller files is a normal file to the operating system;
only one at the time is opened for reading or writing. Moreover, after
reading they are immediately deleted. In the case described one would
for example produce file1, fractured up into five files called file1_0
to file_5. When merging this with the output store file2, fractured
into file1a_0 to file1a_7 (for example) is created. At the moment that
the last subfiles are being created most of the subfiles of file1
will have been deleted. The maximum disk space used with this method
is usually about equal to the size of the final file plus an overshoot.
This overshoot may be one extra subfile size. In addition of course
the overshoot is problem dependent; computing the difference of two
large but equal expressions leads to a final size of zero, but the
intermediate result may at one point be as large as that of one expression
alone. Schoonschip assumes that an overshoot at least as large as the
size of the output memory is allowed. This is used to skip the last merging,
thus dumping the last output store onto file2 and then merging (possibly
very large) file1 with this much smaller file2 while printing.
This method appears to be the best one can do concerning disk usage.
The timing is reasonable, but goes up quadratically with the size
of the final file. To give an idea, a 6 Megabyte final result takes
about 6000 seconds merging time, depending on the system (M68000
assumed).
If space is no issue then more then one dump file may be specified.
The sorting time decreases roughly linearly with the number of files.
This is of course very problem dependent.
A very important factor is also output memory size. Sorting time
decreases roughly linearly with increasing memory size. To allow for
adaption to particular systems the size of the output memory may
now be specified on the command line when calling Schoonschip.
However, be careful with systems having dynamic memory management
such as the Sun. If to much memory is specified then the system will
accept that and swap memory onto disk as needed. This is of course
very counterproductive. It would bring Schoonschip virtually to a halt.
Also the format of numbers plays a role. Integers (limit 2 000 000 000)
take less space on the disk then most other numbers (6 versus 14 bytes
for anyone term). Thus if all numbers can be made integer by means
of some overall factor then that will improve both speed and output size.
The factor can be divided out later, or whatever. If a precision of
less then 9 digits is specified (N 9 or Precision 9) then all
numbers written to disk will be rounded such as to fit in 6 bytes.
Of importance is the way an expression is factored. This factorization
is under control of the user through the use of the B-list. In the
output store the terms are stored precisely as they are printed:
head1 * ( tail11 + tail12 + ...) + head2 * (tail21 + ...) + ...
Without factoring much more space would be used:
head1*tail11 + head1*tail12 + ...
Too much factoring is also wasteful:
head1 * (tail1) + head2 * (tail2) + ....
To adequately allow tailoring of a problem a number of facilities have
been provided. Notably, for a large problem, a "dry run" may be executed.
If that is specified then Schoonschip will not write any file, but simply
discard any full output store. An estimate of the time and disk space
needed will be made and printed. The estimate is for minimum disk space
(i.e. only one output file to be used). Optionally a limited number of
terms in the output will be printed, to inspect for optimal factorization.
If more then one device is available for storage then it might be desirable
to split up the output files over different devices or directories.
Also this may be done.
Finally the maximum size of the subfiles may be specified.
The naming of the files is as follows. All names are of the form
TAPxyyyL
where x and yyy are hexadecimal numbers. The equivalent of file1_0,
file1_1...file1_10,... etc. above is TAP6000L, TAP6001L ... TAP600AL,....
The equivalent of file1a_0 etc is TAPB000L etc. File2_0 is TAP7000L,
file2a_0 is TAPC000L, etc. Thus the two groups of output files are
TAP6 through TAPA and TAPB through TAPF. File TAP6 when merged with
storage produces file TAPB and conversely.
Also the "Yep" file has been made into a fractured file. The name used
is TAP4yyyL, with yyy starting at 000. In this way the disk usage is
minimized in the case of a *Yep.
A useful tool in handling large problems is the Freeze command. Suppose
there exits a large common file that must be worked on further. In
particular, suppose that work must be done on certain factors. If
the file has, say, 10000 terms then that work must be done 10000 times.
To cut down on the work as well on the size of the problem the
following may be done.
First, when producing the file specify on the B-list those factors on
which the work must be done. For example, if an expression must be
integrated over some variable x, with X1, X2 and X3 denoting x dependent
factors:
Common xfile
B x,X1,X2,X3
Z xfile = ....
Substitutions, commands
*begin
The result will be of the form:
xfile = x * (terms1...) + x^2 * (terms2...) + X1 * (terms3...) etc.
There may be many terms inside the brackets. As the file must be a common
file it now resides on disk. The subsequent command (after the *begin)
Freeze xfile
produces the following result. The file xfile is read and split up in one
main file and possibly many 'frozen' subfiles. The main file will still
be called xfile, and is as follows:
xfile = x * DF(xfile,1) + x^2 * DF(xfile,2) + X1 * DF(xfile,3) etc.
The subfiles are denoted as x_file:
x_file(1) = terms1
x_file(2) = terms2
x_file(3) = terms3
:
:
The frozen subfiles are not directly accesible like other files. They
may be referred to only by means of the DF function. There is a command,
Expand, that allows substution of the subfile for the DF function. For
example,
Z xx = DF(xfile,3)
Id,Expand,xfile
*end
will produce for xx the contents of x_file(3). This may also be used
to restore the file to its original shape:
Common xfilp
B x,X1,X2
Z xfilp = xfile
Id,Expand,xfile
Delete xfile
*begin
The new file xfilp will be precisely as the original xfile. Deleting
(but not replacing) a frozen main file leads to deletion of all frozen
subfiles.
It is clear that the work on the frozen main file xfile will be much
less voluminous since it will have many less terms. After the work has
been done one may re-establish the complete file using the Expand command.
Freeze is a very powerful tool. It must however be used with some care.
Most importantly: file arguments are not, repeat not, transferred to
the subfiles. For example, defining
Z xfile(a1,a2) = ...
and subsequently freezing xfile leads to a number of subfiles. Using
now xfile with some other arguments,
Z ha = xfile(mu,nu)
and subsequently expanding the subfiles will not lead to the replacement
of a1 and a2 in the subfiles by mu and nu. Thus as a general rule a
file to be frozen should not have arguments.
Particularly tricky are created indices here. If such indices are
summation indices then it may happen that of such a pair of indices
one appears outside parenthesis, and one inside, and thus may become
part of a frozen subfile. Since Schoonschip often renames summation
indices there may then result a situation where the index outside
is renamed, while that inside remains the same. See the discussion
at the All command.
20. FILE HANDLING COMMANDS.
This section assumes that the reader is familiar with the section on large
file handling. The commands may be in upper or lower case, and only the
first two (three if confusion possible) characters are significant.
To specify Traditional sorting:
Traditional
Whatever the default is and will be is a matter of time and experience.
The specify the new method:
Large #
where # is a number in the range 1 to 5 inclusive. Default is 2. It specifies
the number of output files to be used.
To specify the maximum size of the subfiles:
Maximum #
where # is the maximum size of the subfiles in bytes. Default is 110 000.
For each of the subfiles a prefix (directory) may be specified. One may
either specify a collective prefix for all subfiles regardless of the
first number (6-F), and/or specify individual prefixes. Here is the
syntax:
Directory #,prefix1,#,prefix2,#,prefix3,...
For any subfile the number designating the subfile is compared with
the chain. The prefix inbetween two numbers (including the first
but not the second) that have a range including the file number
will be used. If the number is less than 1000 hex (=4096) then only
the last three hexadecimal digits of the file number are used, else
all. The prefix is simply glued in front of the name TAP... as described
before. The special notation . (just one period) designates no prefix.
It should be noted that Schoonschip accepts hexadecimal numbers with
the notation 0x... where ... are hexadecimal digits. For example
0x100 is the same as 256.
Here some examples.
Directory 0,/usr/tmp/,10,/user1/tmp/,100,.
The numbers must be in ascending order. This statement must be the
very first in any Schoonschip program, and it must be in a *Fix section.
Files TAPx000L through TAPx009L are prefixed with /usr/tmp/:
/usr/tmp/TAP6000L
for example. Files TAPx00AL through TAPx063L are prefixed with
/usr1/tmp/. Files TAPx0064L and up get no prefix. There is collective
sharing of directories, for example TAP6001L and TAPB001L get the same
prefix.
Directory 0x4000,/usr/tmp/,0x6000,.,0xB000,/usr/tmp1/
The prefix /usr/tmp/ is assigned to files TAP4yyyL and TAP5yyyL.
Files TAP6yyyL through TAPAyyyL get no prefix, and files TAPB000L up
get /usr/tmp1/. Files TAP0yyyL through TAP3yyyL (not yet used) get
no prefix.
Default: no prefix.
The old statement
Outlimit #
specifies in all cases the maximum number of bytes that can be written.
Default: 500 000.
To obtain information on the size of the various files being written
use the statement
Showlength
It causes Schoonschip to print the total size and the name of the last
subfile after completion of that file. The statement
Nshow
Switches it off. The statement
Dryrun #
causes Schoonschip to do a dry run as described before. The number #
specifies the maximum number of terms that will be printed. This
statement may appear also after a yep for example. If # is 0 or absent
no dry run is made.
21. SUMMARY.
Lines with a C in column one (excluding Common) are comment lines.
Lines with a blank in column one are taken to be continuation lines (also
for C-line continuations).
Lines with a ~ in column one are ignored.
A ! signals the start of comments on a line, but otherwise is seen as
end-of-line.
Print options:
P brackets First 2 characters significant.
P heads First 2 characters significant.
P input First 2 characters significant.
P lists First 2 characters significant.
P ninput First 2 characters significant.
P nlists First 2 characters significant.
P noutput First 2 characters significant.
P nstatistics First 2 characters significant.
P output First 2 characters significant.
P statistics First 2 characters significant.
Lprinter Print output lines till 130 characters.
Screen Print output lines till 80 characters.
External file reading:
Read fname Start reading from external file fname.
In fname no Read statements allowed.
End Switch back to normal input and close the file.
A subsequent reading of that same file starts
again at the begin.
Common file manipulations:
Enter Cfile Enter common files contained in file Cfile.
Must be in first section, terminated by *fix
There may be several Enter statements in that section.
Write Cfile Write common files to file Cfile.
Blocks and DO-loops:
BLOCK Name{arg1,...} Defines Block Name. In text arguments between ''.
Call: Name{brg1,...} Name must start in col 1.
If an argument contains comma's this argument must
be enclosed in {}. Concerning nesting: Schoonschip
strips away one layer of {} at a time.
ENDBLOCK
DELETE Name1,Name2,... Delete blocks Name1,...
DO L1=n1,n2,n3 Optional n3. If absent is taken to be 1. In text
ENDDO argument L1 between ''.
File related statements:
Common Name1,Name2(0),Name3,.. Defines common files.
Delete Name1,Name2(5),Name3,.. Delete files.
Keep Name1,Name2(5),Name3,.... Keep local files over a *next.
Names Name1,Name2(5),Name3,... Enter namelists of these files.
Nprint Name1,Name2(5),Name3,.. Do not print these Z-expressions.
Print Name1,Name2(5),Name3,... Print these Z-expressions.
Punch Name1,Name2(5),Name3,... Write to tape8 in Fortran compatible
form.
In certain lists the name of an indexed file may appear without index. In
that case the command applies to all files with that name. This holds for
Delete, Keep, Nprint, Print and Punch.
Various 'first-column' types:
* Start execution or go on to next section. Options:
fix yep next begin end
The *fix section must be the first section.
All names, but not expressions in brackets are
kept over a *yep.
*next as *yep, except that local files not mentioned
in a Keep list are deleted.
All except fixed quantities and common files are
deleted over a *begin.
*end signals end of input file.
A a1,a2=x,.. Algebraic symbol list. If x is a number then powers
of a2 equal or higher than x are set to zero.
Alternatively x may be c, r or i, denoting reality
properties. Default is r. Constructions such as
a2=3=c are allowed.
Al Substitution or command on same Level. On a line
starting with Id subsequent ; are read as Al,
B b1,b2,.. List of symbols to be factored out in output.
Legal: symbols, vectors, dotproducts, vector comp.
If a vector name is mentioned all dotproducts and
vector components referring to that vector are
factored out.
D Name(n,..)=xpr,xpr,.. Data expression. Expressions must be single terms.
F f1,f2=x,.. Function list. Reality properties may be specified
through x, legal are i,c,r and u. Default is r.
I i1,i2=x,.. Index list. The dimension x may be a number or a
single character algebraic variable, defined before
in an A-list.
Id Substitution or command on next free Level. See Al.
Oldnew a1=b1,a2=... Change name a1 into b1 etc.
Outlimit # Change output byte limit. Default: 500 000.
Sum i1,i2,.. Declares i1,i2,.. to be summation indices. This is
not related to the summation indices of the DS
function, but indices appearing twice according
to the Einstein summation convention.
Indices in this list must have been defined before.
T Name(n,,,)=sy1,sy2,.. Table.
T Name: "X=1:1,.. Character table.
V p1,p2=z,.. Vector list. Names of 1 or 2 characters. The optional
z implies that p2 is to be set to zero as soon as
it occurs, also in vector-component or dot-product.
X Name(arg,..)=xpr X-expression.
Z Name(arg1,...)=xpr Z-expression. If arg1 is a number or simple numerical
expression Name is a subscripted file. The number
must be in the range 0-32767.
Here a simple numerical expression may contain
numbers, or block or DO-loop arguments that become
numbers, separated by +-* or /.
The general structure of a substitution or command involves several elements
that can be separated in groups. All groups and elements must be separated by
comma's.
The first group is the Id or Al itself (with possibly ; instead of Al,)
optionally followed by a number:
Id, Al, ; Id,#, Al,#, ;#,
The number specifies on how many Levels the substitution or command is to
be applied.
The next group may contain one item, namely a keyword. This only for
substitutions, not commands. Valid keywords are:
Multi Funct Dotpr Ainbe Adiso Always Once
This group may be empty.
The next group either defines a pattern followed by a = sign or is a command
followed by arguments separated by comma's (if any). Patterns are products of
factors, with dummies designated by a ~ following the symbol. Not all factors
can be dummies. See section 10.
The available commands and their formats are:
Absol Force coefficien positive.
Addfa Add factor.
Id,Addfa,expression
All Collect vectors p into function F. Created indices may be assigned
a dimension. First syntax:
Id,All,p,N,F
possibly followed by the character arguments "F_, "D_, and/or "V_
which inhibit function argument, dot-product or single vector
inspection (example: Id,All,p,N,F,"F_).
Second syntax:
Id,All,F1,N,F
Collect all vectors of function F1 into F. Substitute a created
index in F1, and also as additional argument of F.
Anti Check function arguments for characters, and if _ present remove
that if character mentioned in anit-particle chcracter table.
Id,Anti,TA
Asymm Re-arrange arguments of anti-symmetric function.
Id,Asymm,f1,2,3,4,f2,f3,4,5
Id,Asymm,F1:2,3,4:7,8,9:12,13,14:
Id,Asymm,F1:1-3:7-9:12-14:
Beep Generate a beep on the terminal.
Id,Beep
Coef Inspect numerical coefficient.
IF Coef,option
options: pl plus
ng negative
eq,# equal
lt,# less than
gt,# greater than
ib,#,# inbetween
Commu Re-arrange commuting functions.
Id,Commu,f1,f2,f3,...
Compo Compose names.
Id,Compo,<options>,f1,f2,<options>,f3,f4,..
options: AFIVX with AFV possibly twice. Optionally "S_ suppresses
symmetrization of the name. Optionally a character table may be
specified, to be used if characters with an underscore appear.
Count Count certain occurrences with certain weigths.
Id,Count,xxx,arg1,#,arg2,#,....
If xxx number then term kept if count equal or larger than xxx.
If xxx symbol or vector-component or dot-product xxx^# is made.
If xxx function or X,D expression then xxx(#) is made. In that case
a multiple count can be made:
Id,Count,Fx,arg1,#,..,# : arg2,#,..,# : arg3,#,...
Now Fx(#1,#2,#3,...) is made with #1 determined by the arguments up
till the first colon, #2 by the arguments between first and second
colon etc.
Cyclic Function invariant under cyclic permutation of the arguments.
Id,Cyclic,f1,2,3,4,f2,f3,4,5
Dostop Set, clear or test Dostop flag.
Id,Dostop,X
where X = On, off or test. Default test.
Epfred Reduce products of Epf functions.
Even Function even in sign of arguments.
Id,Even,f1,2,3,4,f2,f3,4,5
Expand Expand frozen subfiles (appearing as DF(fname,#) ).
Id,Expand,fname
Extern Jump to user defined routine.
Id,Extern,arg1,arg2,...
Iall Inverse of All.
Id,Iall,p,F
Id,Iall,F
Numer Insert numerical values.
Id,Numer,arg1,#,arg2,#,...
Odd Function odd in sign of arguments.
Id,Odd,f1,2,3,4,f2,f3,4,5
Order Order functions on the basis of their first two arguments.
Id,Order,F1,F2,...
Print Print a message, maximally # times.
Id,Print,#,Message
Ratio Rationalize.
Id,Ratio,xpa,xpb,bma
Stats Count passage in one of four counters (0-3). Result printed at end.
Id,Stats,#
Symme Re-arrange arguments of symmetric function.
Id,Symme,f1,2,3,4,f2,f3,4,5
Id,Symme,F1:2,3,4:7,8,9:12,13,14:
Id,Symme,F1:1-3:7-9:12-14:
Three commands are special to problems of relativistic quantum mechanics:
Gammas Collect, Reduce and/or take trace of products of G's.
Id,Gammas,options,L1,L2-L3:options,Trace,L3,L4-L5:options,...
options are designated by characters: "C collect only, "A anomalous
trace, "S do spinsum, "U unify strings, "I do index pair reduction,
"i do index pairs in _-type strings, "P do P-tricks, "W do final work.
All options except "C may be followed by an underscore, implying
switching off. The "C option when not combined with anything else
gives normalization, however without ever specialization to
four dimensions (essential if there are non-four-dimensional vectors)
Default: "A_,"S,"U_,"I,"i,"P,"W
Spin Replace pairs of Ug,Ubg by spin-summation expression. The spinors may
be defined by loop indices or vectors.
Id,Spin,L1,p,...
Ndotpr Create special dot-products. Closely related to Gammas command.
Id,Ndotpr,F1
A number of special functions is build in. They are:
D Delta function.
Epf Anti-symmetric Weyl tensor. May have any number of arguments.
DD Internal purposes (used to represent X and D expressions and
files).
DS Summation function. Format:
DS(J1,#,#,(xpr1),(xpr2)) xpr2 numeric, optional.
The sum over the given range is constructed. The numerical
coefficient is by recursion, using xpr2. The first coefficient
is 1. Example: e^x = DS(J,0,20,(x^J),(1/J)) + O(x^21).
Caution: summation symbols such as J may be used only once
in a given expression.
Character summation:
DS(C1;C2;..;Sym;C3;C4;TX,..,2:4,7,(xpr))
Numerical functions (may be part of expressions that must be numerical
such as for instance expressions occurring as exponents, or with a negative
exponent, but not of simple numerical expressions such as Z-expression index):
DB DB(n) = n! DB(n,m) = n!/{m! (n-m)!}
DB with two arguments is word-bound, fails if n=19, m=8,9,..
DT DT(n1,n2,..) 1 if all arguments positive or zero, else 0.
DK DK(n1,n2) 1 if n1=n2, else 0.
DP DP(n1,n2,..) 1 if permutation to smallest first is even,
else 0. Order normal: -127,..,0,...,+127.
0 if two arguments equal.
DF DF(xfile,#) or DF(xfile,#1,#2)
The last case is equivalent to the first
with # = 100*#1 + #2.
DC DC(n1,n2,..) 1 if sum of all arguments is 0, else 0.
DC("X,.....) "X is option character. May be "C, "F, "T
with or without underscore following.
Special functions relevant to particle physics are:
G(L,mu) Gi(L) G5(L) G6(L)=Gi(L)+G5(L) G7(L)=Gi(L)-G5(L)
Ug(L,m,p) Ug(L,mu,m,p) Ubg(L,m,p) Ubg(L,mu,m,p)
Use -m for anti-particle spinors.
New notation:
G(i1,i2,mu,nu,..,G6,..) Gi(i1,i2) G5(i1,i2) G6(i1,i2) G7(i1,i2)
Internally generated G-strings:
G(L1,"s,"4,mu,nu,..,G5,..) General 4 and N dim mixture.
G(L1,"t,"4,mu,nu,..,G5,..) General 4 and N dim mixture.
G(L1,"S,"X,mu,nu,........) 4-dim. "X may be "4, "5, "6 or "7.
G(L1,"T,"X,mu,nu,........) 4-dim. "X may be "4, "5, "6 or "7.
G(L1,"s,"_,mu,nu,........) N-4 dim.
G(L1,"t,"_,mu,nu,........) N-4 dim.
APPENDIX A. COMMAND LINE OPTIONS.
The standard usage is:
Schip file1 file2 options
Schoonschip input is supposedly contained in file1, the output is written
to file2. Fortran compatible output (directive Punch) is written to tape8.
If file2 absent then the output is written to standard output, i.e. the
screen. If in addition file1 absent then the standard input (the keyboard)
is used as input. When doing that remember that *end terminates the run.
Also errors lead to termination. Normally Schoonschip echo's the input lines
back to the screen.
Alternatively input, output and punch file (tape8 by default) can be
designated by means of the notations i=, o= or f= (the f stands for Fortran
compatible; upper case accepted as well):
Schip i=file1 o=file2 f=file3
This cannot be combined with the first method.
All options are optional. First one may specify certain options by
preceeding them with a - sign. These options are:
s For Schoonschip versions running on a PC with bitmap screen.
The "Ready" line and the requested keyboard input are suppressed
if s (for silence) specified.
b Certain Fortran compilers do not accept negative exponents without
brackets (for example A**-3). If b specified brackets are written.
The default is no brackets.
p Show progress by printing a point (.) to standard output every
128 terms.
. Place a . after every integer in the output. Some Fortran compilers
insist on this.
Also upper case characters may be used. Example:
Schip file1 file2 -b.p
Options b, . and p apply.
These options may also be selected inside a Schoonschip program by means of
the statements
Silence
Fortran options
Progress on
Progress off
These statements are discussed elsewhere (section Miscellaneous).
Another option leads to noise (Control-G is sent to the terminal) upon
completion. This may be specified as b=# where # is the number of beep's
the terminal is to receive. The option S=# where # is a number in the range
-128, 127 inclusive implies setting of the initial value of the parameter
_Sw0 to the value #. Example:
Schip file1 file2 b=10 s=19
Upon completion 10 beeps will be sent to the terminal (with some interval).
The initial value of _Sw0 is 19.
Most important, one may now specify memory usage to Schoonschip. There
are two large storage areas used during execution, called the input space
and the output space. The input space contains the expressions, substitutions,
etc. The output space is where the final result is collected. Performance
in case of large expressions is very sensitive to the size of the output
store. The larger the better. As an heritage of the old CDC days Schoonschip
has always been very frugal in memory usage. The build-in size of in- and
output space used to be 20 Kb and 50 Kb respectively. Given that nowadays
few machines have less than 1 Mb of memory that seems to frugal.
The version of Jan 1, 1989 is more expansive. To begin with an amount of
about 80 Kb is used separately for buffers etc. This used to be much less.
Default sizes for in- and out space are machine dependent, but typically
100 Kb and 250 Kb are taken. The total memory usage (excluding Schoonschip
itself, which is about 100 Kb) comes then to about 450 Kb.
The in- and out sizes may now be specified on the command line. To this
purpose one uses the notation IS=# and OS=# (lower case accepted also)
where the # stand for number specifying magnitude in Kb. Thus the old
situation is obtained with this command line:
Schip file1 file2 IS=20 OS=50
Finally a number # preceeded by a + sign can be specified on the command
line. Then Schoonschip skips the first # problems on the input file. Every
occurrence of a *end line counts as one problem. Example:
Schip +5 Varia Out
Problem five in file Varia is executed.
Some other examples:
Schip Infil Outfil -bp
The file Infil is taken to contain the input, output is written to Outfil.
Dots are printed when starting a problem, and further every 128 terms.
Brackets are placed around negative exponents.
Schip +1 i=Varia o=Vario -p
Problem 1 of Varia is executed, the output is written to Vario and meanwhile
dots on the screen show progress.
APPENDIX B. COMPATIBILITY.
Programs working with older 68000 versions will work provided the square
brackets [] are taken out and replaced by for example curly brackets.
In addition there is a slight change in Integ (evalution of numerical
expressions as function arguments). It now truncates, rather then rounding
to nearest integer. The statement 'Round on' may be used to re-instate
rounding (CDC versions of Schoonschip truncated).
The command Trick is now called Gammas, but will still be accepted. The block
delete command, DELETE (all upper case) has been replaced by BDELETE (case
insensitive, only the first four characters significant). The rarely used
statement 'Printer' has been replaced by Lprint.
Programs that executed on previous (CDC) versions of Schoonschip will
also run with this version with minor, mainly cosmetic modifications. The
main differences are in the use of lower case characters in this version,
and furthermore different notations for BLOCK and DO-loop arguments.
- Block arguments in the text of the block must be embedded in quotes.
The same holds for DO arguments. These latter can now take negative
values in all cases. Use of {} obligatory. Block arguments, in a call,
may now have comma's provided they are enclosed in {}.
The word COPY is no more needed when calling a block.
Block names may at most be 6 characters in length.
- The complex variable I is now written as i. If needed the statement
Oldnew i=I takes care of this.
- The S-list is now the A-list. However, S is still accepted.
- ID and AL are now Id and Al. However, both are accepted.
- GI is now Gi.
- CONJG and INTEG are now Conjg and Integ.
- Various keywords and commands have sometimes slightly different spelling,
ODDXX is now Odd.
- The Print options have different format. For example, PRINT INPUT
is now P input.
- Dummies are now characterized by a following ~ instead of a +.
- An exponent may now also be denoted by ^ instead of **.
- The special function DX is no more implemented. It is used internally
for purposes relating to the Gammas command.
- Characters as function argument are denoted by "X instead of =X.