Computational Challenges in Heat Kernel Calculations


This is an evaluated Mathematica notebook. Since the notebook is intended to be interactive, it may be helpful to also view the unevaluated version. A version of this notebook will be published in the Proceedings of the Winnipeg Heat Kernel Conference. The notebook was converted to HTML with the mma2html program by Ed Donley inspired by Terry Robb's work.

Steve Christensen

MathTensor, Inc. & UNC-Chapel Hill
Winnipeg, August, 1994

Historical Introduction

I first came upon heat kernel calculations in 1971 when starting out as a student of Bryce DeWitt and reading Dynamical Theory of Groups and Fields - section 17. He was convinced that a computer eventually could be taught to do these calculations. At the time I had had about 8 years of programming experience with FORTRAN, FORMAC, and a little Schoonschip. None of these seemed appropriate for quantum gravity calculations and in any case, no computer had enough memory or disk space to store results of the really large calculations. I did what I could by hand over the next few years - mostly by brute force. (Protests to Bryce about the horrible length of such calculations would usually get a - "Come on, it's a straightforward calculation - Just Do It!" If I didn't want him to go away over the weekend and do it himself, I just did.)

In 1974, I took on the project to carefully carry out "point splitting" regularization for stress tensors. The majority of the calculations involved the computation of coincidence limits of the bi-scalar of geodetic interval $\sigma (x,x')$ and expansions of other bi-scalar and bi-tensor objects in terms of the tangent to the geodesic at the point x.

In the early 1980's, working on fourth order gravity theories, I found that I would no longer be able to carry out most of the renormalization calculations I wanted to do - at least not by brute force. Macsyma or Reduce held out some hope, but were LISP-based, only ran on mainframes or mini-computers, and usually took all of the resources of those expensive and hard-to-find machines. The advent of the 68000-based UNIX computers and C-compilers from Sun Microsystems and Berkeley encouraged new developments in computer algebra.

In 1982, I contacted Steve Wolfram in the hope that he would agree to move his SMP system - then running on VAX's - to a Sun workstation. I also ordered a workstation - one of the first Sun-1's (It had a 6 MHz 68000 16/8-bit processor with 1 megabyte of RAM and 60 megabytes of disk - and weighed a "ton". This little notebook computer has a lot more power.) While waiting for SMP, I wrote some of my own programs which did some of the coincidence limit calculations I wanted to do, but quickly overwhelmed the initial configuration of my Sun-1.

After 1985, with the advent of the Sun-3 machine, it finally became possible to run SMP and C programs on a personal machine that could really do a large computation. Parker, Fulling, and I independently were working on designing tensor analysis systems for specific purposes. Wolfram had dropped SMP development due to legal hassles and at the University of Illinois started creating Mathematica. I got the first copy of this from him to experiment on moving my coincidence limit programs from C to Mathematica. Eventually, Parker and I joined forces to create a general purpose tensor analysis system - now called MathTensor. Fulling focused on the deeper Mathematical analysis of pseudo-differential operators and a study of the normal forms for tensor polynomials.

Computers have now reached a level where calculations beyond human hand-calculations can be done with some strong belief that they are bugfree and reproducible in more than one way. The work outlined here was done on a 2-processor Sun SPARCstation 10 with 64 megabytes of RAM and 1-gigabyte of disk.

My philosophy for doing large calculations

Try doing a calculation in the most straigthforward and brute
force way before getting "clever."

Alway be able to show intermediate steps in a calculation - whether
done by hand or computer.

Do any large calculation in two different ways when possible.

Calculations - To Do List

There are a number of very large, very challanging, problems to
carry out by computer - some already being done - that I am
interested in doing or checking with new calculations:

Coincidence limits of sigma up to 12 derivatives.

Coincidence limits of I(x,x'), the bi-tensor of parallel transport, and
its derivatives for various fields up to 10 derivatives.

Coincidence limits for the HaMiDew coefficients and their derivatives for all interesting operators.

Use above results in deriving point splitting expansions for all two-point objects - including Green functions and stress tensors.

To do these calculations, we must define minimal sets of Riemann tensor products, derivatives, and coupling objects.

Repeat the above calculations adding in torsion and/or other background fields - Yang-Mills, for example.


It is probable that a group of people will have to be formed to act as a
"standard" group to define and archive the calculations above - and to
test all results obtained.

Today, I will take time only to look at the first two calculations where
I have made some progress in the last few months.

How big can the calculations get?

Steve Fulling has written a C program called sig which is very good
at computing coincidence limits of sigma. He has created a formula that relates the coincidence limit of p derivatives of sigma to a complicated
sum of terms with products of derivatives of the Riemann tensor and lower derivative coincidence limits of sigma.



The program computes all possible legal terms that can appear in the pth-derivative coincidence limit and then computes which ones actually appear and then the coefficient of that term. Here are a few typical runs:

The output gives a list of Riemann tensors and derivatives suitable for loading back into MathTensor. It also lists the number of terms checked and the ones with non-zero coefficients.

The next table shows in the numbers for higher derivative runs on my SPARC 10:


Order Indices   Gen. Terms	Non-Zero   Minimal  	Time       	Size 								         								   (bytes)
2 4 24 2 2 0:00 141
3 5 120 6 5 0:00 288
4 6 12,240 92 49 1:30 4,406
5 7 206,640 790 364 19:80 43,666
6 8 14,595,840 16,522 3,023 31:11 1,141,977
7 9 477,912,960 261,198 ??? 17:18:39 16,800,403
8 10 32,793,465,600 ??? ??? ??? ???
9 11 1,505,781,446,400 ??? ??? ??? ???
10 12 86,189,631,897,600 ??? ??? ??? ???


Order = number of derivatives of the metric in each term.
Indices = number of free indices on the terms.
Gen. Terms = number of terms generated by the SIGTREE routine.
Non-Zero = number of terms with non-zero coefficients.
Minimal = actual number of independent terms after Riemann symmetries.
Time = run time on SPARC 10 in hours:minutes:seconds
Size = size of result file in bytes.
??? = currently unknown or unavailable.

We can see that beyond order 6 we begin to deal with an extraordinary number of terms. Even at that order, reducing 16,522 terms down to a minimal set will be non-trivial initially.

The order 8 case creates some difficulties since the integers go beyond
machine precision. This is being looked into.

Step by step calculation of sigma coincidence limits

I now want to show how coincidence limits can be done in a step-by-step brute force way beginning from first principles. This is a Mathematica and MathTensor session run on the SPARC 10.

Start up

We start out by setting up a timer and loading the software.

In[1]:=

  timestart = SessionTime[];

In[2]:=

  <<MathTensor.m

  Loading MathTensor for UNIX . . . 



========================================================
MathTensor (TM) 2.2 (UNIX (R)) (January 6, 1994)
by Leonard Parker and Steven M. Christensen
Copyright (c) 1991-1994 MathTensor, Inc.
Runs with Mathematica (R) Versions 1.2 and 2.X.
Licensed to machine spock.
========================================================
No unit system is chosen. If you want one,
you must edit the file called Conventions.m,
or enter a command to interactively set units.
Units: {}
Sign conventions: Rmsign = 1 Rcsign = 1
MetricgSign = 1 DetgSign = -1
TensorForm turned on,
ShowTime turned off,
MetricgFlag = True.
=========================================

Due to the huge number of loops and substitutions in these calculations, the default value of the recursion limit has to be changed.

In[3]:=

  $RecursionLimit = 512000;

I enter the expression which defines sigma when set equal to zero. I also enter the first three well known coincidence limits of covariant derivatives of sigma.

In[4]:=

  DefineSigma :=
          Canonicalize[sigma - (1/2) CD[sigma,ua] CD[sigma,la]]

In[5]:=

  RuleUnique[sigmaonerule,CD[sigma,la_],0]

In[6]:=

  RuleUnique[sigmatworule,CD[sigma,la_,lb_],Metricg[la,lb]]

In[7]:=

  RuleUnique[sigmathreerule,CD[sigma,la_,lb_,lc_],0]

Four Derivative Case

I start by taking four derivatives of the sigma defining equation and then applying the known lower derivative rules:

In[8]:=

  DefineSigma

Out[8]=

                        p
          sigma   sigma
               ;p      ;
  sigma - ---------------
                 2

In[9]:=

  CD[%,la,lb,lc,ld]

Out[9]=

                                   p                      p
  sigma      + (-(sigma     sigma    ) - sigma     sigma     - 
       ;abcd           ;pcd      ;a b         ;pbd      ;a c
   
                        p                     p                     p
       sigma     sigma     - sigma     sigma     - sigma     sigma     - 
            ;pbc      ;a d        ;pad      ;b c        ;pac      ;b d
   
                        p           p                     p
       sigma     sigma     - sigma    sigma      - sigma    sigma      - 
            ;pab      ;c d        ;d       ;pabc        ;c       ;pabd
   
              p                     p                              p
       sigma    sigma      - sigma    sigma      - sigma    sigma      - 
            ;b       ;pacd        ;a       ;pbcd        ;pd      ;a bc
   
                       p                     p                     p
       sigma    sigma      - sigma    sigma      - sigma    sigma      - 
            ;pc      ;a bd        ;pb      ;a cd        ;pa      ;b cd
   
             p                              p
       sigma   sigma       - sigma   sigma      ) / 2
            ;       ;pabcd        ;p      ;a bcd

In[10]:=

  Expand[%]

Out[10]=

                     p                      p                     p
  -(sigma     sigma    )   sigma     sigma       sigma     sigma
         ;pcd      ;a b         ;pbd      ;a c        ;pbc      ;a d
  ---------------------- - ------------------- - ------------------- - 
            2                       2                     2
   
                     p                     p                     p
    sigma     sigma       sigma     sigma       sigma     sigma
         ;pad      ;b c        ;pac      ;b d        ;pab      ;c d
    ------------------- - ------------------- - ------------------- - 
             2                     2                     2
   
           p                     p                     p
    sigma    sigma        sigma    sigma        sigma    sigma
         ;d       ;pabc        ;c       ;pabd        ;b       ;pacd
    ------------------- - ------------------- - ------------------- - 
             2                     2                     2
   
           p                                           p
    sigma    sigma                     sigma    sigma
         ;a       ;pbcd                     ;pd      ;a bc
    ------------------- + sigma      - ------------------- - 
             2                 ;abcd            2
   
                    p                     p                     p
    sigma    sigma        sigma    sigma        sigma    sigma
         ;pc      ;a bd        ;pb      ;a cd        ;pa      ;b cd
    ------------------- - ------------------- - ------------------- - 
             2                     2                     2
   
          p                              p
    sigma   sigma         sigma   sigma
         ;       ;pabcd        ;p      ;a bcd
    ------------------- - -------------------
             2                     2

In[11]:=

  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule}]

Out[11]=

  -sigma      - sigma      - sigma
        ;abcd        ;acbd        ;adbc

The OrderCD function looks at the derivatives, sees that they are not in lexical order, and then commutes derivatives until they are. This generates more lower derivative terms that are eliminated by applying the sigmaonerule and sigmatworule:

In[12]:=

  OrderCD[%]

Out[12]=

              p                  p                                 p
  -(sigma   R      ) - sigma   R       - 3 sigma      - sigma    R     - 
         ;p  a bc;d         ;p  a bd;c          ;abcd        ;pd  a bc
   
               p                p                p
    sigma    R     - sigma    R     - sigma    R
         ;pc  a bd        ;pb  a cd        ;pa  b cd

In[13]:=

  ApplyRules[%,{sigmaonerule,sigmatworule}]

Out[13]=

  -3 sigma      - R     - R
          ;abcd    acbd    adbc

Finally, I solve for the coincidence limit of four derivatives of sigma and then define sigmafourrule using the RuleUnique function. This is saved to
a file later and can be used immediately.

In[14]:=

  Solve[%==0,CD[sigma,la,lb,lc,ld]]

Out[14]=

                  -R     - R
                    acbd    adbc
  {{sigma      -> --------------}}
         ;abcd          3

In[15]:=

  RuleUnique[sigmafourrule,CD[sigma,la_,lb_,lc_,ld_],
  %[[1]][[1]][[2]]]

Five Derivative Case

The five derivative case is done the same way as the four derivative case:

In[16]:=

  DefineSigma

Out[16]

In[17]:=

  Expand[CD[%,la,lb,lc,ld,le]]

Out[17]

In[18]:=

  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule}]

Out[18]

In[19]:=

  OrderCD[%]

Out[19]

In[20]:=

  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule}]

Out[20]

In[21]:=

  Solve[%==0,CD[sigma,la,lb,lc,ld,le]]

Out[21]

In[22]:=

  RuleUnique[sigmafiverule,CD[sigma,la_,lb_,lc_,ld_,le_],
  %[[1]][[1]][[2]]]

Six Derivative Case

In[23]:=
  DefineSigma

Out[23]

In[24]:=

  Expand[CD[%,la,lb,lc,ld,le,lf]]

Out[24]

In[25]:=

  Expand[%]

Out[25]

In[26]:=

  ApplyRules[%,
  {sigmaonerule,sigmatworule,sigmathreerule,sigmafourrule}]

Out[26]

In[27]:=

  OrderCD[%]

Out[27]

In[28]:=

  ApplyRules[%,
  {sigmaonerule,sigmatworule,sigmathreerule,sigmafourrule}]

Out[28]

In[29]:=

  Solve[%==0,CD[sigma,la,lb,lc,ld,le,lf]]

Out[29]

In[30]:=

  RuleUnique[sigmasixrule,CD[sigma,la_,lb_,lc_,ld_,le_,lf_],
  %[[1]][[1]][[2]]]

Seven Derivative Case

In[31]:=
  DefineSigma

Out[31]

In[32]:=

  Expand[CD[%,la,lb,lc,ld,le,lf,lg]]

Out[32]

In[33]:=

  ApplyRules[%,
  {sigmaonerule,sigmatworule,sigmathreerule,sigmafourrule,
  sigmafiverule}]

Out[33]

In[34]:=

  OrderCD[%]

Out[34]

In[35]:=

  ApplyRules[%,
  {sigmaonerule,sigmatworule,sigmathreerule,sigmafourrule,
  sigmafiverule}]

Out[35]

In[36]:=

  Solve[%==0,CD[sigma,la,lb,lc,ld,le,lf,lg]]

Out[36]

In[37]:=

  RuleUnique[sigmasevenrule,CD[sigma,la_,lb_,lc_,ld_,le_,lf_,lg_],
  %[[1]][[1]][[2]]]

Saving the Results

Since these calculations only need to be done once, we can save them
to a common file which can be loaded in other sessions. The entire
process of computing and saving these derivatives took about 40 minutes.
Is can be made faster by not printing the formatted results to the
screen.

In[38]:=

  Definition[$RecursionLimit] >> sigmarules.m

In[39]:=

  Definition[DefineSigma] >>> sigmarules.m

In[40]:=

  Definition[sigmaonerule] >>> sigmarules.m

In[41]:=

  Definition[sigmatworule] >>> sigmarules.m

In[42]:=

  Definition[sigmathreerule] >>> sigmarules.m

In[43]:=

  Definition[sigmafourrule] >>> sigmarules.m

In[44]:=

  Definition[sigmafiverule] >>> sigmarules.m

In[45]:=

  Definition[sigmasixrule] >>> sigmarules.m

In[46]:=

  Definition[sigmasevenrule] >>> sigmarules.m

In[47]:=

  timefinal = Expand[(SessionTime[] - timestart)/60]

Out[47]=

  40.8620413

Eight Derivative Case

The eight derivative case requires a few different commands due to its
extreme size.

In[48]:=

  DefineSigma

Out[48]

In[49]:=

  Expand[CD[%,la,lb,lc,ld,le,lf,lg,lh]]

Out[49]

In[50]:=

  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule}]

Out[50]

It is necessary to canonicalize this expression to reduce the number of
terms - here from 189 to 98.

In[51]:=

  Canonicalize[%]

Out[51]

In[52]:=

  Length[%%]

Out[52]=

  189

In[53]:=

  Length[%%]

Out[53]=

  98

It is also correct to split out the pure covariant derivative terms so that OrderCD will not look at them. There are seven pure derivative terms that appear at the end of the equation.

In[54]:=

  eightderivterms = Take[%%%,-7]

Out[54]=

  -sigma          - sigma          - sigma          - sigma          - 
        ;abcdefgh        ;acbdefgh        ;adbcefgh        ;aebcdfgh
   
    sigma          - sigma          - sigma
         ;afbcdegh        ;agbcdefh        ;ahbcdefg

In[55]:=

  mixedderivterms = Drop[%%%%,-7]

Out[55]

In[56]:=

  mixedderivtermsfinal = 
  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule,
  sigmafourrule,sigmafiverule,sigmasixrule}]

Out[56]

In[57]:=

  Clear[mixedderivterms]

In[58]:=

  OrderCD[eightderivterms]

Out[58]

In[59]:=

  eightderivtermsfinal = 
  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule,
  sigmafourrule,sigmafiverule,sigmasixrule}]

Out[59]

In[60]:=

  Clear[eightderivterms]

In[61]:=

  Clear["sigma*"]

In[62]:=

  Expand[-(mixedderivtermsfinal + eightderivtermsfinal)/7]

Out[62]

In[63]:=

  % >> sigma8.m
  

Index Sums

Now that we have the unsummed index terms, we can easily compute examples with index pair summations:

In[64]:=

  CD[sigma,la,ua,lc,uc,le,ue]

Out[64]=

         a c e
  sigma
       ;a c e

In[65]:=

  ApplyRules[%,sigmasixrule]

Out[65]=

        p         pq       q  p       q p       pq          q   p          pq
  -4 R      2 R        2 R        2 R        2 R        2 R   R     2 R   R
      ;p       pq;        p ;q       p ; q        ;pq      p   q       pq
  ------- - -------- - -------- - -------- - -------- + --------- + --------- - 
     5         5          5          5          5          15          15
   
      qrs     p       qrs     p     q s    pr       qrs   p         q     prs
    R     R       2 R     R       R     R       2 R     R       2 R     R
     p     qrs       p     qsr     p r   qs        p     q rs      p rs  q
    ----------- - ------------- - ----------- + ------------- + ------------- - 
        15             45             45             45              45
   
      q s   r p     q     rps       q     spr        rs    pq      rs   p q
    R     R       R     R       2 R     R       2 R     R       R     R
     p r   q s     p rs  q         p rs  q         pq    rs      pq    r s
    ----------- + ----------- + ------------- - ------------- - ----------- - 
        45            15             45              45             45
   
        s   pqr       s   qpr            pqrs          prqs
    R     R       R     R       2 R     R       R     R
     pqr   s       pqr   s         pqrs          pqrs
    ----------- + ----------- - ------------- - -----------
        45            45             45             45

In[66]:=

  Canonicalize[%]

Out[66]=

        p         pq         qp          pq            pqrs            prqs
  -4 R      6 R        2 R        4 R   R     8 R     R       8 R     R
      ;p       pq;        pq;        pq          pqrs            pqrs
  ------- - -------- - -------- + --------- - ------------- - -------------
     5         5          5          15            45              45

Some built in rules about Riemann tensor help to simplify the results. Ultimately, a very large list of rules will need to be produced so that the smallest possible results occur. Note that one possible invariant R^2
does not occur.

In[67]:=

  ApplyRules[%,RiemannRules]

  RiemannRule17::Applied: RiemannRule17 has been used.

  RiemannRule16::Applied: RiemannRule16 has been used.

  RiemannRule8::Applied: RiemannRule8 has been used.

Out[67]=

        p          pq            pqrs
  -8 R      4 R   R     4 R     R
      ;p       pq          pqrs
  ------- + --------- - -------------
     5         15            15

A final important note - It would be possible to compute this result from DefineSigma as was done with the non-sum cases. This proves to be
more time consuming for all cases than doing the sums on the non-summed
result stored in sigmarules.m.

Bi-vector Example

It is easy to consider other coincidence limits - like the bi-vector of parallel displacement. Here we need indices at the point x' and get
them by loading alternate indices.

In[68]:=

  AddIndexTypes

In[69]:=

  DefineTensor[bi,"I",{{1,2},1}]

  PermWeight::def: Object I defined

The define equation is defineI == 0 from:

In[70]:=

  defineI = Canonicalize[CD[bi[li,auj],uc] CD[sigma,lc]]

Out[70]=

            j' p
  sigma   I
       ;p  i  ;

In[71]:=

  RuleUnique[bizerorule,bi[li1_,auj],Metricg[li1,uj],!SameQ[li1,li]]

In[72]:=

  CD[defineI,la]

Out[72]=

    j' p                      j' p
  I      sigma    + sigma   I
   i  ;       ;pa        ;p  i  ; a

In[73]:=

  ApplyRules[%,{sigmaonerule,sigmatworule}]

Out[73]=

    j'
  I
   i  ;a

In[74]:=

  RuleUnique[bionerule,CD[bi[li_,auj],la_],0]

In[75]:=

  CD[defineI,la,lb]

Out[75]=

             j' p               j' p      j' p                       j' p
  sigma    I       + sigma    I       + I      sigma     + sigma   I
       ;pb  i  ; a        ;pa  i  ; b    i  ;       ;pab        ;p  i  ; ab

In[76]:=

  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule}]

Out[76]=

    j'        j'
  I       + I
   i  ;ab    i  ;ba

In[77]:=

  OrderCD[%]

Out[77]=

      j'        j'     p
  2 I       + I    R
     i  ;ab    p    abi

In[78]:=

  % /. bizerorule

Out[78]=

      j'          j
  2 I       + R
     i  ;ab    abi

In[79]:=

  Solve[%==0,CD[bi[li,auj],la,lb]]

Out[79]=

                    j
               -R
      j'         abi
  {{I       -> ------}}
     i  ;ab      2

In[80]:=

  RuleUnique[bitworule,CD[bi[li_,auj],la_,lb_],%[[1]][[1]][[2]]]

In[81]:=

  CD[defineI,la,lb,lc]

Out[81]=

    j' p                j' p                j' p
  I       sigma     + I       sigma     + I       sigma     + 
   i  ; c      ;pab    i  ; b      ;pac    i  ; a      ;pbc
   
               j' p                j' p                j' p
    sigma    I        + sigma    I        + sigma    I        + 
         ;pc  i  ; ab        ;pb  i  ; ac        ;pa  i  ; bc
   
      j' p                        j' p
    I      sigma      + sigma   I
     i  ;       ;pabc        ;p  i  ; abc

In[82]:=

  ApplyRules[%,{sigmaonerule,sigmatworule,sigmathreerule,sigmafourrule}]

Out[82]=

                                     j' p           j' p
                                   I      R       I      R
    j'         j'         j'        i  ;   pbac    i  ;   pcab
  I        + I        + I        - ------------ - ------------
   i  ;abc    i  ;bac    i  ;cab        3              3

In[83]:=

  ApplyRules[%,bionerule]

Out[83]=

    j'         j'         j'
  I        + I        + I
   i  ;abc    i  ;bac    i  ;cab

In[84]:=

  OrderCD[%]

Out[84]=

    j'     p       j'     p         j'         j'       p     j'       p
  I    R       + I    R       + 3 I        + I      R     + I      R     + 
   p    abi ;c    p    aci ;b      i  ;abc    p  ;c  abi     p  ;b  aci
   
      j'     p       j'       p
    I      R     + I      R
     i  ;p  a bc    p  ;a  bci

In[85]:=

  ApplyRules[%,{bizerorule,bionerule}]

Out[85]=

      j         j         j'
  R       + R       + 3 I
   abi ;c    aci ;b      i  ;abc

In[86]:=

  Solve[%==0,CD[bi[li,auj],la,lb,lc]]

Out[86]=

                     j         j
                -R       - R
      j'          abi ;c    aci ;b
  {{I        -> ------------------}}
     i  ;abc            3

In[87]:=

  RuleUnique[bithreerule,CD[bi[li_,auj],la_,lb_,lc_],
  %[[1]][[1]][[2]]]

Potential solutions to problem size

Faster Microprocessors

Multiprocessors or multiple computers in parallel

Faster Algorithms

Diagramatic representations of results

Minimize the size of all intermedicate expressions

Define what problems actually need to be solved

Find a general pattern from lower order results


Return to MathTensor Home Page.

Send comments or questions to steve@smc.vnet.net


See also the Other Interesting WWW Sites.
© Copyright 1995 MathTensor, Inc.
MathTensor is a Trademark of MathTensor, Inc.
Mathematica is a Registered Trademark of Wolfram Research, Inc.
This page was last updated on January 11, 1995.