Up | Next | Prev | PrevTail | Tail |
ASSIST contains a large number of additional general purpose functions that allow a user to better adapt REDUCE to various calculational strategies and to make the programming task more straightforward and more efficient.
The package ASSIST contains an appreciable number of additional general purpose operators which allow one to better adapt REDUCE to various calculational strategies, to make the programming task more straightforward and, sometimes, more efficient.
In contrast with all other packages, ASSIST does not aim to provide either a new facility to compute a definite class of mathematical objects or to extend the base of mathematical knowledge of REDUCE. The operators it contains should be useful independently of the nature of the application which is considered. They were initially written while applying REDUCE to specific problems in theoretical physics. Most of them were designed in such a way that their applicability range is broad. Though it was not the primary goal, efficiency has been sought whenever possible.
The source code in ASSIST contains many comments concerning the meaning and use of the supplementary operators available in the algebraic mode. These comments, hopefully, make the code transparent and allow a thorough exploitation of the package. The present documentation contains a non-technical description of it and describes the various new facilities it provides.
An elementary help facility is available, independent of the help facility of REDUCE itself. It includes two operators:
assist
is a operator which takes no argument. If entered, it returns the informations
required for a proper use of assisthelp
.assisthelp
takes one argument.
If the argument is the identifier assist
, the operator returns the information
necessary to retrieve the names of all the available operators.
If the argument is an integer equal to one of the section numbers of the
present documentation. The names of the operators described in that section
are obtained.
There is, presently, no possibility to retrieve the number and the type of the
arguments of a given operator.
The package contains several modules. Their content reflects closely the various categories of facilities listed below. Some operators do already exist inside the Core of REDUCE. However, their range of applicability is extended.
Control of Switches:
switches
switchorg
Operations on Lists and Bags:
mklist
kernlist
algnlist
length
position
frequency
sequences
split
insert
insert_keep_order
merge_list
first
second
third
rest
reverse
last
belast
cons
(
.
)
append
appendn
remove
delete
delete_all
delpair
member
elmult
pair
depth
mkdepth_one
repfirst
represt
asfirst
aslast
asrest
asflist
asslist
restaslist
substitute
bagprop
putbag
clearbag
bagp
baglistp
alistp
abaglistp
listbag
Operations on Sets:
mkset
setp
union
intersect
diffset
symdiff
General Purpose Utility Functions:
list_to_ids
mkidn
mkidnew
dellastdigit
detidnum
oddp
followline
==
randomlist
mkrandtabl
permutations
cyclicpermlist
perm_to_num
num_to_perm
combnum
combinations
symmetrize
remsym
sortnumlist
sortlist
algsort
extremum
gcdnl
depatom
funcvar
implicit
explicit
remnoncom
korderlist
simplify
checkproplist
extractlist
Properties and Flags:
putflag
putprop
displayprop
displayflag
clearflag
clearprop
Control Statements, Control of Environment:
nordp
depvarp
alatomp
alkernp
precp
show
suppress
clearop
clearfunctions
Handling of Polynomials:
alg_to_symb
symb_to_alg
distribute
leadterm
redexpr
monom
lowestdeg
divpol
splitterms
splitplusminus
Handling of Transcendental Functions:
trigexpand
hypexpand
trigreduce
hypreduce
Coercion from Lists to Arrays and converse:
list_to_array
array_to_list
Handling of n-dimensional Vectors:
sumvect
minvect scalvect
crossvect
mpvect
Handling of Grassmann Operators:
putgrass
remgrass
grassp
grassparity
ghostfactor
Handling of Matrices:
unitmat
mkidm
baglmat
coercemat
submat
matsubr
matsubc
rmatextr
rmatextc
hconcmat
vconcmat
tpmat
hermat
seteltmat
geteltmat
Control of the HEPHYS package:
remvector
remindex
mkgam
In the following all these operators are described.
The two available operators i.e. switches
, switchorg
have no argument and are
called as if they were mere identifiers.
switches
displays the actual status of the most frequently used switches when
manipulating rational operators. The chosen switches are
exp
,allfac
,ezgcd
,gcd
,mcd
,lcm
,div
,rat
,intstr
,rational
,precise
,reduced
,rationalize
,combineexpt
,complex
,revpri
,distribute
.
The selection is somewhat arbitrary but it may be changed in a trivial fashion by the user.
The new switch distribute
allows one to put polynomials in a distributed form (see
the description below of the new operators for manipulating them).
Most of the symbolic variables !*exp
, !*div
, … which have either the value t
or the
value nil
are made available in the algebraic mode so that it becomes possible to write
conditional statements of the kind
if !*exp then do ...... if !*gcd then off gcd;
SWITCHORG
resets the switches enumerated above to the status they had when starting
REDUCE.
Additional operators for list manipulations are provided and some already defined
operators in the kernel of REDUCE are modified to properly generalize them to the
available new structure bag
.
Generation of a list of length n with all its elements initialized to 0 and possibility to append to a list \(l\) a certain number of zero’s to make it of length \(n\):
mklist n ; n is an integer mklist(l,n); l is List-like, n is an integer
Generation of a list of sublists of length n containing p elements equal to 0 and q elements equal to 1 such that
sequences
works both
in algebraic and symbolic modes. Here is an example in the algebraic
mode:
sequences 2 ; ==> {{0,0},{0,1},{1,0},{1,1}}
An arbitrary splitting of a list can be done. The operator split
generates a list
which contains the splitted parts of the original list.
split({a,b,c,d},{1,1,2}) ==> {{a},{b},{c,d}}
The operator algnlist
constructs a list which contains n copies of a list bound
to its first argument.
algnlist({a,b,c,d},2); ==> {{a,b,c,d},{a,b,c,d}}
The operator kernlist
transforms any prefix of a kernel into the list
prefix.
The output list is a copy:
kernlist (<kernel>); ==> {<kernel arguments>}
Four operators to delete elements are delete
, remove
, delete_all
and
delpair
. The first two act as in symbolic mode, and the third eliminates from a
given list all elements equal to its first argument. The fourth acts on a list of pairs
and eliminates from it the first pair whose first element is equal to its first argument
:
delete(x,{a,b,x,f,x}); ==> {a,b,f,x} remove({a,b,x,f,x},3); ==> {a,b,f,x} delete_all(x,{a,b,x,f,x}); ==> {a,b,f} delpair(a,{{a,1},{b,2},{c,3}}; ==> {{b,2},{c,3}}
The operator elmult
returns an integer which is the multiplicity of its first
argument inside the list which is its second argument. The operator frequency
gives a list of pairs whose second element indicates the number of times the first
element appears inside the original list:
elmult(x,{a,b,x,f,x}) ==> 2 frequency({a,b,c,a}); ==> {{a,2},{b,1},{c,1}}
The operator insert
allows one to insert a given object into a list at the
desired position.
The operators insert_keep_order
and merge_list
allow one to keep a
given ordering when inserting one element inside a list or when merging two lists.
Both have 3 arguments. The last one is the name of a binary boolean ordering
function:
ll:={1,2,3}$ insert(x,ll,3); ==> {1,2,x,3} insert_keep_order(5,ll,lessp); ==> {1,2,3,5} merge_list(ll,ll,lessp); ==> {1,1,2,2,3,3}
Notice that merge_list
will act correctly only if the two lists are well ordered
themselves.
Algebraic lists can be read from right to left or left to right. They look
symmetrical. One would like to dispose of manipulation functions which reflect
this. So, to the already defined functions first
and rest
are added the
functions last
and belast
. last
gives the last element of the list while
belast
gives the list without its last element.
Various additional functions are provided. They are:
.
(“dot
”),position
,depth
,mkdepth_one
,pair
,appendn
,repfirst
,represt
The token “dot” needs a special comment. It corresponds to several different operations.
cons
infix operator. Note
however that blank spaces are required around the dot:
4 . {a,b}; ==> {4,a,b}
part
operator:
{a,b,c}.2; ==> b
position
returns the position of the first occurrence of x in a list or a message if
x is not present in it.
depth
returns an integer equal to the number of levels where a list is found if and
only if this number is the same for each element of the list otherwise it returns a
message telling the user that the list is of unequal depth. The function
mkdepth_one
allows to transform any list into a list of depth equal to
1.
pair
has two arguments which must be lists. It returns a list whose elements
are lists of two elements. The \(n^{th}\) sublist contains the \(n^{th}\) element of the first
list and the \(n^{th}\) element of the second list. These types of lists are called
association lists or short alists in the following. To test for these type of
lists a boolean function abaglistp
is provided. It will be discussed
below.appendn
has any fixed number of lists as arguments. It generalizes the already
existing function append
which accepts only two lists as arguments. It may also
be used for arbitrary kernels but, in that case, it is important to notice that the
concatenated object is always a list.repfirst
has two arguments. The first one is any object, the second one is a list.
It replaces the first element of the list by the object. It works like the
symbolic mode (lisp) function rplaca
except that the original list is not
destroyed.represt
has also two arguments. It replaces the rest of the list by its first
argument and returns the new list without destroying the original list. It
is analogous to the symbolic mode (lisp) function rplacd
. Here are
examples:
ll:={{a,b}}$ ll1:=ll.1; ==> {a,b} ll.0; ==> list 0 . ll; ==> {0,{a,b}} depth ll; ==> 2 pair(ll1,ll1); ==> {{a,a},{b,b}} repfirst{new,ll); ==> {new} ll3:=appendn(ll1,ll1,ll1); ==> {a,b,a,b,a,b} position(b,ll3); ==> 2 represt(new,ll3); ==> {a,new}
The functions asfirst
, aslast
, asrest
, asflist
, asslist
, and
restaslist
act on alists or on lists of lists of well defined depths and have two
arguments. The first is the key object which one seeks to associate in
some way with an element of the association list which is the second
argument.asfirst
returns the pair whose first element is equal to the first argument.aslast
returns the pair whose last element is equal to the first argument.asrest
needs a list as its first argument. The function seeks the first sublist of a
list of lists (which is its second argument) equal to its first argument and returns
it.restaslist
has a list of keys as its first argument. It returns the collection of
pairs which meet the criterium of asrest
.asflist
returns a list containing all pairs which satisfy the criteria of the
function asfirst
. So the output is also an association list.asslist
returns a list which contains all pairs which have their second element
equal to the first argument.
Here are a few examples:
lp:={{a,1},{b,2},{c,3}}$ asfirst(a,lp); ==> {a,1} aslast(1,lp); ==> {a,1} asrest({1},lp); ==> {a,1} restaslist({a,b},lp); ==> {{1},{2}} lpp:=append(lp,lp)$ asflist(a,lpp); ==> {{a,1},{a,1}} asslist(1,lpp); ==> {{a,1},{a,1}}
The function substitute
has three arguments. The first is the object to be
substituted, the second is the object which must be replaced by the first, and
the third is the list in which the substitution must be made. Substitution
is made to all levels. It is a more elementary function than sub
but its
capabilities are less. When dealing with algebraic quantities, it is important to
make sure that all objects involved in the function have either the prefix
lisp or the standard quotient representation otherwise it will not properly
work.
The list structure of REDUCE is very convenient for manipulating groups of objects
which are, a priori, unknown. This structure is endowed with other properties such as
“mapping” i.e. the fact that if op
is an operator one gets, by default,
op({x,y}); ==> {op(x),op(y)}
It is not permitted to submit lists to the operations valid on rings so that, for example,
lists cannot be indeterminates of polynomials.
Very frequently too, procedure arguments cannot be lists. At the other extreme, so to say,
one has the kernel structure associated with the algebraic declaration operator
. This
structure behaves as an “unbreakable” one and, for that reason, behaves like an
ordinary identifier. It may generally be bound to all non-numeric procedure
parameters and it may appear as an ordinary indeterminate inside polynomials.
The BAG
structure is intermediate between a list and an operator. From the operator it
borrows the property of being a kernel and, therefore, may be an indeterminate of a
polynomial. From the list structure it borrows the property of being a composite
object.
Definition:
A bag is an object endowed with the following properties:
noncom
or symmetric
, etc.Available Functions:
A default bag envelope
textttbag is defined. It is a reserved identifier. An identifier other than list
or
one which is already associated with a boolean function may be defined as a bag
envelope through the command putbag
. In particular, any operator may also be
declared to be a bag. When and only when the identifier is not an already defined
function then putbag
set for it the property of an operator prefix. The
command:
putbag id1,id2,....idn;
declares id1
,…,idn
as bag envelopes. Analogously, the command
clearbag id1,...idn;
eliminates the bag property on id1
,…,idn
.
The boolean operator bagp
detects the bag property. Here is an example:
aa:=bag(x,y,z)$ if bagp aa then "ok"; ==> ok
The functions listed below may act both on lists or bags. Moreover, functions subsequently defined for setsSETS also work for a bag when its content is a set. Here is a list of the main ones:
FIRST
,second
,last
,rest
,belast
,depth
,length
,reverse
,member
,append
,.
(“dot
”),repfirst
,represt
, …
However, since they keep track of the envelope, they act somewhat differently. Remember that
the name of the envelope is kept by the operators
first
, second
and last
.
Here are a few examples (more examples are given inside the test file):
putbag op; ==> t aa:=op(x,y,z)$ first op(x,y,z); ==> op(x) rest op(x,y,z); ==> op(y,z) belast op(x,y,z); ==> op(x,y) append(aa,aa); ==> op(x,y,z,x,y,z) appendn(aa,aa,aa); ==> {x,y,z,x,y,z,x,y,z} length aa; ==> 3 depth aa; ==> 1 member(y,aa); ==> op(y,z)
When “appending” two bags with different envelopes, the resulting bag gets the
name of the one bound to the first parameter of append
. When appendn
is used,
the output is always a list.
The function length
gives the number of objects contained in the bag.
The connection between the list and the bag structures is made easy thanks to
kernlist
which transforms a bag into a list and thanks to the coercion function
listbag
which transforms a list into a bag. This function has 2 arguments and is
used as follows:
listbag
(\(\langle \)list\(\rangle \),\(\langle \)id\(\rangle \)); ==> \(\langle \)id\(\rangle \)(\(\langle \)arg_list\(\rangle \))The identifier \(\langle \)id\(\rangle \), if allowed, is automatically declared as a bag envelope or an error
message is generated.
Finally, two boolean functions which work both for bags and lists are
provided. They are baglistp
and abaglistp
. They return t or nil (in a
conditional statement) if their argument is a bag or a list for the first one, or if
their argument is a list of sublists or a bag containing bags for the second
one.
Functions for sets exist at the level of symbolic mode. The package makes them available in algebraic mode but also generalizes them so that they can be applied to bag-like objects as well.
The constructor mkset
transforms a list or bag into a set by eliminating
duplicates.
mkset({1,a,a}); ==> {1,a} mkset bag(1,a,1,a); ==> bag(1,a)
setp
is a boolean function which recognizes set–like objects.
if setp {1,2,3} then ... ;
union
, intersect
, diffset
, symdiff
.
They have two arguments which must be sets otherwise an error message is issued. Their meaning is transparent from their name. They respectively give the union, the intersection, the difference and the symmetric difference of two sets.
Functions in this sections have various purposes. They have all been used many times in applications in some form or another. The form given to them in this package is adjusted to maximize their range of applications.
The operators mkidnew
, dellastdigit
, detidnum
,
list_to_ids
handle identifiers.
mkidnew
has either 0 or 1 argument. It generates an identifier which has not yet
been used before.
mkidnew(); ==> g0001 mkidnew(a); ==> ag0002
dellastdigit
takes an integer as argument and strips from it its last
digit.
dellastdigit 45; ==> 4
detidnum
deletes the last digit from an identifier. It is a very convenient
function when one wants to make a do loop starting from a set of indices
\( a_1, \ldots , a_{n} \).
detidnum a23; ==> 23
list_to_ids
generalizes the function mkid
to a list of atoms. It creates and
intern an identifier from the concatenation of the atoms. The first atom cannot be
an integer.
list_to_ids {a,1,id,10}; ==> a1id10
The boolean operator oddp
detects odd integers.
The function followline
is convenient when using the function prin2
. It
allows one to format output text in a much more flexible way than with the write
statement.
Try the following examples :
<<prin2 2; prin2 5>>$ ==> ? <<prin2 2; followline(5); prin2 5;>>; ==> ?
The infix operator ==
is a short and convenient notation for the set
function. In fact it is a generalization of it to allow one to deal also with
kernels:
operator op; op(x):=abs(x)$ op(x) == x; ==> x op(x); ==> x abs(x); ==> x
The function randomlist
generates a list of random numbers. It takes
two arguments which are both integers. The first one indicates the range
inside which the random numbers are chosen. The second one indicates
how many numbers are to be generated. Its output is the list of generated
numbers.
randomlist(10,5); ==> {2,1,3,9,6}
mkrandtabl
generates a table of random numbers. This table is either a one or
two dimensional array. The base of random numbers may be either an integer or a
decimal number. In this last case, to work properly, the switch rounded
must be
ON. It has three arguments. The first is either a one integer or a two integer list.
The second is the base chosen to generate the random numbers. The third is the
chosen name for the generated array. In the example below a two-dimensional
table of random integers is generated as array elements of the identifier
a
r.
mkrandtabl({3,4},10,ar); ==> *** array ar redefined {3,4}
The output is the dimension of the constructed array.
permutations
gives the list of permutations of \(n\) objects. Each permutation is
itself a list. cyclicpermlist
gives the list of cyclic permutations. For both
functions, the argument may also be a bag.
permutations {1,2} ==> {{1,2},{2,1}} cyclicpermlist {1,2,3} ==> {{1,2,3},{2,3,1},{3,1,2}}
perm_to_num
and num_to_perm
allow to associate to a given permutation
of n numbers or identifiers a number between \(0\) and \(n! - 1\). The first function has the two
permutated lists as its arguments and it returns an integer. The second one has an
integer as its first argument and a list as its second argument. It returns the list of
permutated objects.
perm_to_num({4,3,2,1},{1,2,3,4}) ==> 23 num_to_perm(23,{1,2,3,4}); ==> {4,3,2,1}
combnum
gives the number of combinations of \(n\) objects taken \(p\) at a time. It has
the two integer arguments \(n\) and \(p\).
combinations
gives a list of combinations on \(n\) objects taken \(p\) at a time. It has
two arguments. The first one is a list (or a bag) and the second one is the integer
\(p\).
combinations({1,2,3},2) ==> {{2,3},{1,3},{1,2}}
remsym
is a command that suppresses the effect of the REDUCE commands
symmetric
or antisymmetric
.
symmetrize
is a powerful function which generates a symmetric expression. It
has 3 arguments. The first is a list (or a list of lists) containing the expressions
which will appear as variables for a kernel. The second argument is the
kernel-name and the third is a permutation function which exists either in algebraic
or symbolic mode. This function may be constructed by the user. Within this
package the two functions permutations
and cyclicpermlist
may be
used. Examples:
ll:={a,b,c}$ symmetrize(ll,op,cyclicpermlist); ==> op(a,b,c) + op(b,c,a) + op(c,a,b) symmetrize(list ll,op,cyclicpermlist); ==> op({a,b,c}) + op({b,c,a}) + op({c,a,b})
Notice that, taking for the first argument a list of lists gives rise to an expression
where each kernel has a list as argument. Another peculiarity of this function is the
fact that, unless a pattern matching is made on the operator op
, it needs to be
reevaluated. This peculiarity is convenient when op
is an abstract operator if
one wants to control the subsequent simplification process. Here is an
illustration:
op(a,b,c):=a*b*c$ symmetrize(ll,op,cyclicpermlist); ==> op(a,b,c) + op(b,c,a) + op(c,a,b) reval ws; ==> op(b,c,a) + op(c,a,b) + a*b*c for all x let op(x,a,b)=sin(x*a*b); symmetrize(ll,op,cyclicpermlist); ==> op(b,c,a) + sin(a*b*c) + op(a,b,c)
The functions sortnumlist
and sortlist
are functions which sort lists.
They use the bubblesort and the quicksort algorithms.
sortnumlist
takes as argument a list of numbers. It sorts it in increasing
order.
sortlist
is a generalization of the above function. It sorts the list according to
any well defined ordering. Its first argument is the list and its second argument is
the ordering function. The content of the list need not necessarily be numbers
but must be such that the ordering function has a meaning. algsort
exploits the PSL sort
function. It is intended to replace the two functions
above.
l:={1,3,4,0}$ sortnumlist l; ==> {0,1,3,4} ll:={1,a,tt,z}$ sortlist(ll,ordp); ==> {a,z,tt,1} l:={-1,3,4,0}$ algsort(l,>); ==> {4,3,0,-1}
It is important to realise that using these functions for kernels or bags may be
dangerous since they are destructive. If it is necessary, it is recommended to first
apply kernlist
to them to act on a copy.
The function extremum
is a generalization of the already defined functions min
,
max
to include general orderings. It is a 2 argument function. The first is the list
and the second is the ordering function. With the list ll
defined in the last
example, one gets
extremum(ll,ordp); ==> 1
GCDNL
takes a list of integers as argument and returns their gcd.
There are four functions to identify dependencies. funcvar
takes any
expression as argument and returns the set of variables on which it depends.
Constants are eliminated.
funcvar(e+pi+sin(log(y)); ==> {y}
depatom
has an atom as argument. It returns it if it is a number or if no
dependency has previously been declared. Otherwise, it returns the list of variables
which the previous DEPEND
declarations imply.
depend a,x,y; depatom a; ==> {x,y}
The operators explicit
and implicit
make explicit or implicit the
dependencies. This example shows how they work:
depend a,x; depend x,y,z; explicit a; ==> a(x(y,z)) implicit ws; ==> a
These are useful when one wants to trace the names of the independent variables and (or) the nature of the dependencies.
korderlist
is a zero argument function which displays the actual
ordering.
korder x,y,z; korderlist; ==> (x,y,z)
A command remnoncom
to remove the non-commutativity of operators
previously declared non-commutative is available. Its use is like the one of the
command noncom
.
Filtering functions for lists.
checkproplist
is a boolean function which checks if the elements of a list
have a definite property. Its first argument is the list, its second argument is
a boolean operator (fixp
, numberp
, …) or an ordering function (as
ordp
).
extractlist
extracts from the list given as its first argument the elements
which satisfy the boolean function given as its second argument. For
example:
if checkproplist({1,2},fixp) then "ok"; ==> ok l:={1,a,b,"st")$ extractlist(l,fixp); ==> {1} extractlist(l,stringp); ==> {st}
Since lists and arrays have quite distinct behaviour and storage properties, it is
interesting to coerce lists into arrays and vice-versa in order to fully exploit
the advantages of both datatypes. The functions array_to_list
and
list_to_array
are provided to do that easily. The first function has the
array identifier as its unique argument. The second function has three
arguments. The first is the list, the second is the dimension of the array
and the third is the identifier which defines it. If the chosen dimension is
not compatible with the the list depth, an error message is issued. As
an illustration suppose that \(ar\) is an array whose components are 1,2,3,4.
then
array_to_list ar; ==> {1,2,3,4} list_to_array({1,2,3,4},1,arr}; ==>
generates the array \(arr\) with the components 1,2,3,4.
Control of the HEPHYS package.
The commands remvector
and remindex
remove the property of being a
4-vector or a 4-index respectively.
The function mkgam
allows to assign to any identifier the property of a Dirac
gamma matrix and, eventually, to suppress it. Its interest lies in the fact that, during
a calculation, it is often useful to transform a gamma matrix into an abstract
operator and vice-versa. Moreover, in many applications in basic physics, it is
interesting to use the identifier \(g\) for other purposes. It takes two arguments. The
first is the identifier. The second must be chosen equal to t
if one wants to
transform it into a gamma matrix. Any other binding for this second argument
suppresses the property of being a gamma matrix the identifier is supposed to
have.
In spite of the fact that many facets of the handling of property lists is easily accessible in algebraic mode, it is useful to provide analogous functions genuine to the algebraic mode. The reason is that, altering property lists of objects, may easily destroy the integrity of the system. The functions, which are here described, do ignore the property list and flags already defined by the system itself. They generate and track the addtional properties and flags that the user issues using them. They offer him the possibility to work on property lists so that he can design a programming style of the “conceptual” type.
We first consider “flags”.
To a given identifier, one may associate another one linked to it
“in the background”. The three functions putflag
, displayflag
and
clearflag
handle them.
putflag
has 3 arguments. The first one is the identifier or a list of identifiers, the
second one is the name of the flag, and the third one is t
(true) or 0 (zero). When
the third argument is t
, it creates the flag, when it is 0 it destroys it. In
this last case, the function does return nil (not seen inside the algebraic
mode).
putflag(z1,flag_name,t); ==> flag_name putflag({z1,z2},flag1_name,t); ==> t putflag(z2,flag1_name,0) ==>
displayflag
allows one to extract flags. The previous actions give:
displayflag z1; ==>{flag_name,flag1_name} displayflag z2 ; ==> {}
clearflag
is a command which clears all flags associated with the identifiers
\(id_1, \ldots , id_n .\)
Properties are handled by similar operators. putprop
has four arguments. The
second argument is, here, the indicator of the property. The third argument may be
any valid expression. The fourth one is also t or 0.
putprop(z1,property,x^2,t); ==> z1
In general, one enters
putprop(list(idp1,idp2,..),<propname>,<value>,t);
To display a specific property, one uses displayprop
which takes two
arguments. The first is the name of the identifier, the second is the indicator of the
property.
2 displayprop(z1,property); ==> {property,x }
Finally, clearprop
is a nary commmand which clears all properties of the
identifiers which appear as arguments.
Here we describe additional functions which improve user control on the environment.
The first set of functions is composed of unary and binary boolean functions. They are:
alatomp x; x is anything. alkernp x; x is anything. depvarp(x,v); x is anything.
(v
is an atom or a kernel.) alatomp
has the value t
iff x
is an integer or an
identifier after it has been evaluated down to the bottom.
alkernp
has the value t
iff x
is a kernel after it has been evaluated down to the
bottom.
depvarp
returns t
iff the expression x
depends on v
at any level.
The above functions together with precp
have been declared operator functions
to ease the verification of their value.
nordp
is equal to not ordp
.
The next functions allow one to analyze and to clean the environment of
REDUCE created by the user while working interactively. Two functions are
provided:
show
allows the user to get the various identifiers already assigned and to see
their type. suppress
selectively clears the used identifiers or clears them all.
It is to be stressed that identifiers assigned from the input of files are
ignored. Both functions have one argument and the same options for this
argument:
show (suppress) all show (suppress) scalars show (suppress) lists show (suppress) saveids (for saved expressions) show (suppress) matrices show (suppress) arrays show (suppress) vectors (contains vector, index and tvector) show (suppress) forms
The option all
is the most convenient for show
but, with it, it may takes some
time to get the answer after one has worked several hours. When entering
REDUCE the option all
for show
gives:
show all; ==> scalars are: NIL arrays are: NIL lists are: NIL matrices are: NIL vectors are: NIL forms are: NIL
It is a convenient way to remind the various options. Here is an example which is valid when one starts from a fresh environment:
a:=b:=1$ show scalars; ==> scalars are: (a b) suppress scalars; ==> t show scalars; ==> scalars are: nil
The clear
command of the system does not do a complete cleaning of operators
and functions. The following two commands do a more complete cleaning and,
also, automatically takes into account the user flag and properties that the
functions putflag
and putprop
may have introduced.
Their names are clearop
and clearfunctions
. clearop
takes one
operator as its argument.clearfunctions
is a nary command. If one issues
clearfunctions a1,a2, ... , an $
The functions with names a1
, a2
, …, an
are cleared. One should be careful when
using this facility since the only functions which cannot be erased are those which
are protected with the lose
flag.
The module contains some utility functions to handle standard quotients and several new facilities to manipulate polynomials.
Two operators alg_to_symb
and symb_to_alg
allow one to change an
expression which is in the algebraic standard quotient form into a prefix lisp form
and vice-versa. This is done in such a way that the symbol list
which appears in
the algebraic mode disappears in the symbolic form (there it becomes a parenthesis
“()” ) and it is reintroduced in the translation from a symbolic prefix lisp
expression to an algebraic one. Here, is an example, showing how the wellknown
lisp function flattens
can be trivially transposed inside the algebraic
mode:
algebraic procedure ecrase x; lisp symb_to_alg flattens1 alg_to_symb algebraic x; symbolic procedure flattens1 x; % ll; ==> ((a b) ((c d) e)) % flattens1 ll; (a b c d e) if atom x then list x else if cdr x then append(flattens1 car x, flattens1 cdr x) else flattens1 car x;
gives, for instance,
ll:={a,{b,{c},d,e},{{{z}}}}$ ecrase ll; ==> {a, b, c, d, e, z}
The function mkdepth_one
described above implements that functionality.
leadterm
and redexpr
are the algebraic equivalent of the symbolic mode
functions lt
and red
. They give, respectively, the leading term and the reductum
of a polynomial. They also work for rational functions. Their interest lies in the
fact that they do not require one to extract the main variable. They work according
to the current ordering of the system:
pol:=x++y+z$ leadterm pol; ==> x korder y,x,z; leadterm pol; ==> y redexpr pol; ==> x + z
By default, the representation of multivariate polynomials is recursive. It is
justified since it is the one which takes the least memory. With such a
representation, the function leadterm
does not necessarily extract a true
monom. It extracts a monom in the leading indeterminate multiplied by a
polynomial in the other indeterminates. However, very often, one needs to
handle true monoms separately. In that case, one needs a polynomial in
distributive form. Such a form is provided by the package GROEBNER (H.
Melenk et al.). The facility there is, however, much too involved in many
applications and the necessity to load the package makes it interesting to
construct an elementary facility to handle the distributive representation of
polynomials. A new switch has been created for that purpose. It is called
distribute
and a new function distribute
puts a polynomial in
distributive form. With that switch set to on, leadterm
returns true
monoms.
monom
transforms a polynomial into a list of monoms. It works whatever the
position of the switch distribute
.
splitterms
is analoguous to monom
except that it gives a list of two lists. The
first sublist contains the positive terms while the second sublist contains the
negative terms.
splitplusminus
gives a list whose first element is the positive part of the
polynomial and its second element is its negative part.
Two complementary operators lowestdeg
and divpol
are provided. The
first takes a polynomial as its first argument and the name of an indeterminate as its
second argument. It returns the lowest degree in that indeterminate. The
second function takes two polynomials and returns both the quotient and its
remainder.
The functions trigreduce
and trigexpand
and the equivalent ones for
hyperbolic functions hypreduce
and hypexpand
make the transformations to
multiple arguments and from multiple arguments to elementary arguments. Here is a
simple example:
aa:=sin(x+y)$ trigexpand aa; ==> sin(x)*cos(y) + sin(y)*cos(x) trigreduce ws; ==> sin(y + x)
When a trigonometric or hyperbolic expression is symmetric with respect to the
interchange of sin
(sinh
) and cos
(cosh
), the application of trigreduce
(hypreduce
) may often lead to great simplifications. However, if it is highly
asymmetric, the repeated application of trigreduce
(hypreduce
) followed by the
use of trigexpand
(hypexpand
) will lead to more complicated but more symmetric
expressions:
aa:=(sin(x)^2+cos(x)^2)^3$ trigreduce aa; ==> 1
bb:=1+sin(x)^3$ trigreduce bb; ==> - sin(3*x) + 3*sin(x) + 4 --------------------------- 4 trigexpand ws; ==> 3 2 sin(x) - 3*sin(x)*cos(x) + 3*sin(x) + 4 ------------------------------------------- 4
Explicit vectors in euclidean space may be represented by list-like or bag-like
objects of depth 1. The components may be bags but may not be lists. Functions
are provided to do the sum, the difference and the scalar product. When the
space-dimension is three there are also functions for the cross and mixed products.
sumvect
, minvect
, scalvect
, and crossvect
have two arguments. mpvect
has three arguments. The following example is sufficient to explain how they
work:
l:={1,2,3}$ ll:=list(a,b,c)$ sumvect(l,ll); ==> {a + 1,b + 2,c + 3} minvect(l,ll); ==> { - a + 1, - b + 2, - c + 3} scalvect(l,ll); ==> a + 2*b + 3*c crossvect(l,ll); ==> { - 3*b + 2*c, 3*a - c, - 2*a + b} mpvect(l,ll,l); ==> 0
Grassman variables are often used in physics. For them the multiplication operation is associative, distributive but anticommutative. The core of REDUCE does not provide it. However, implementing it in full generality would almost certainly decrease the overall efficiency of the system. This small module together with the declaration of antisymmetry for operators is enough to deal with most calculations. The reason is, that a product of similar anticommuting kernels can easily be transformed into an antisymmetric operator with as many indices as the number of these kernels. Moreover, one may also issue pattern matching rules to implement the anticommutativity of the product. The functions in this module represent the minimum functionality required to identify them and to handle their specific features.
putgrass
is a (nary) command which give identifiers the property of being the
names of Grassmann kernels. remgrass
removes this property.
grassp
is a boolean function which detects grassmann kernels.
GRASSPARITY
takes a monom as argument and gives its parity. If the monom is a
simple grassmann kernel it returns 1.
GHOSTFACTOR
has two arguments. Each one is a monom. It is equal to
(-1)**(grassparity u * grassparity v)
Here is an illustration to show how the above functions work:
putgrass eta; ==> t if grassp eta(1) then "grassmann kernel"; ==> grassmann kernel aa:=eta(1)*eta(2)-eta(2)*eta(1); ==> aa := - eta(2)*eta(1) + eta(1)*eta(2) grassparity eta(1); ==> 1 grassparity (eta(1)*eta(2)); ==> 0 ghostfactor(eta(1),eta(2)); ==> -1 grasskernel:= {eta(~x)*eta(~y) => -eta y * eta x when nordp(x,y), (~x)*(~x) => 0 when grassp x}; exp:=eta(1)^2$ exp where grasskernel; ==> 0 aa where grasskernel; ==> - 2*eta(2)*eta(1)
This module provides functions for handling matrices more comfortably.
Often, one needs to construct some unit matrix of a given dimension. This
construction is done by the system thanks to the command unitmat
. It takes any
number of arguments:
unitmat m1(n1), m2(n2), .....mi(ni) ;
where m1
, m2
,…,mi
are names of matrices and n1
, n2
,…,ni
are integers.
mkidm
is a generalization of mkid
. It allows one to connect two or
several matrices. If u
and u1
are two matrices, one can go from one to the
other:
matrix u(2,2);$ unitmat u1(2)$ u1; ==> [1 0] [ ] [0 1] mkidm(u,1); ==> [1 0] [ ] [0 1]
This operators allows one to make loops on matrices like in the following
illustration. If u
, u1
, u2
,…, u5
are matrices:
for i:=1:5 do u:=u-mkidm(u,i);
can be issued.
The next functions map matrices on bag-like or list-like objects and conversely they generate matrices from bags or lists.
coercemat
transforms the matrix u
into a list of lists. The entry is
coercemat(u,id)
where id
is equal to list
, otherwise it transforms it into a bag of bags whose
envelope is equal to id
.
baglmat
does the opposite job. The first argument is the bag-like or
list-like object while the second argument is the matrix identifier. The input
is
baglmat(bgl,u)
bgl
becomes the matrix u
. The transformation is not done if u
is already the
name of a previously defined matrix. This is to avoid accidental redefinition of that
matrix.
The operators submat
, matextr
, and matextc
take parts of a given
matrix.
submat
has three arguments. The entry is
submat(u,nr,nc)
The first is the matrix name, and the other two are the row and column numbers. It
gives the submatrix obtained from u
by deleting the row nr
and the column
nc
. When one of them is equal to zero only column nc
or row nr
is
deleted.
matextr
and matextc
extract a row or a column and place it into a list-like or
bag-like object. The entries are
matextr(u,vn,nr) matextc(u,vn,nc)
where u
is the matrix, vn
is the “vector name”, nr
and nc
are integers. If vn
is
equal to list
the vector is returned as a list otherwise as a bag.
Functions which manipulate matrices. They are matsubr
, matsubc
,
hconcmat
, vconcmat
, tpmat
, and hermat
.
matsubr
and matsubc
substitute rows and columns. They have three
arguments. Entries are:
matsubr(u,bgl,nr) matsubc(u,bgl,nc)
The meaning of the variables u
, nr
, and nc
is the same as above while bgl
is a
list-like or bag-like vector. Its length should be compatible with the dimensions of
the matrix.
hconcmat
and vconcmat
concatenate two matrices. The entries are
hconcmat(u,v) vconcmat(u,v)
The first function concatenates horizontally, the second one concatenates vertically. The dimensions must match.
tpmat
makes the tensor product of two matrices. It is also an infix operator. The
entry is
tpmat(u,v) or u tpmat V
hermat
takes the hermitian conjuguate of a matrix. The entry is
hermat(u,hu)
where
textttu is the identifier for the hermitian conjugate of matrix u
. It should be
unassigned for this function to work successfully. This is done on purpose to
prevent accidental redefinition of an already used identifier.
setelmat
getelmat
are functions of two integers. The first one resets the
element \((i,j)\) while the second one extracts an element identified by \((i,j)\). They may be
useful when dealing with matrices inside procedures.
Up | Next | Prev | PrevTail | Front |