1.NH 1
2TEMPLATE PROCESSING
3.LP
4In some code generation applications, pieces of the target
5numerical program are known in advance.  A "template" file
6containing a program outline is supplied by the user, and
7formulas are derived in VAXIMA, converted to numerical code,
8and inserted in the corresponding places in the program outline
9to form a complete numerical program.  A template processor is
10provided by GENTRAN for use in these applications.
11.NH 2
12The Template Processing Command
13.SH
14User Level Syntax:
15.RS
16.DS L
17.ft CR
18\fIgentranin(\fRf1,f2,...,fn {,[f1,f2,...,fm]});
19.ft
20.DE
21.RE
22where f1,f2,...,fn is an argument list containing one or more
23f's, each of which is one of the following:
24.RS
25.DS L
26.ft CR
27a string  =  a template (input) file
28\fItrue\fR      =  the terminal
29.ft
30.DE
31.RE
32and [f1,f2,...,fm] is an optional argument list which, if
33supplied, contains one or more f's, each of which is one
34of the following:
35.RS
36.DS L
37.ft CR
38a string  =  an output file
39\fItrue\fR      =  the terminal
40\fIfalse\fR     =  the current output file(s)
41\fIall\fR       =  all files currently open for output by GENTRAN
42             (see section 4)
43.ft
44.DE
45.RE
46.SH
47LISP Level Syntax:
48.RS
49.DS L
50.ft CR
51\fI(gentranin '(\fRf1 f2 ... fn) '(f1 f2 ... fm))
52.ft
53.DE
54.RE
55where f1 f2 ... fn is an argument list containing one or
56more f's, each of which is one of the following:
57.RS
58.DS L
59.ft CR
60a string  =  a template (input) file
61\fIt\fR         =  the terminal
62.ft
63.DE
64.RE
65and (f1 f2 ... fm) is an argument list which
66contains zero or more f's, each of which is one of the
67following:
68.RS
69.DS L
70.ft CR
71a string  =  an output file
72\fIt\fR         =  the terminal
73\fInil\fR       =  the current output file(s)
74\fI$all\fR      =  all files currently open for output by GENTRAN
75             (see section 4)
76.ft
77.DE
78.RE
79.SH
80Side Effects:
81.LP
82\fIgentranin\fR processes each template file f1,f2,...,fn
83sequentially.
84.LP
85A template file may contain any number of parts, each of which
86is either an "active" or an "inactive" part.  Each active
87part starts with the delimiter << and ends with >>.
88.LP
89Inactive parts of template files are assumed to
90contain code in the target language, FORTRAN, RATFOR, or C, depending on the
91value of the global variable \fI*gentranlang\fR.  Each inactive
92part is copied to the output.  Each comment delimited by the
93appropriate characters,
94.RS
95.DS L
96.ft CR
97C  ... <cr>    for FORTRAN (beginning in column 1) or
98*  ... <cr>    for FORTRAN (beginning in column 1),
99#  ... <cr>    for RATFOR, and
100/* ...  */     for C
101.ft
102.DE
103.RE
104is also copied in its entirety to the output.  Thus the character
105sequences << and >> have no special meanings within
106comments.
107.LP
108Active parts may contain any number of VAXIMA expressions and
109statements.  They are not copied directly to the output.  Instead,
110they are given to VAXIMA for evaluation \fIat the user level\fR.  All
111output generated by each evaluation is sent to the output
112file(s).  Returned values are only printed on the terminal.
113.LP
114Active parts will most likely contain calls to \fIgentran\fR
115to generate code.  This means that the result of processing a template
116file will be the original template file with all active
117parts replaced by generated code.
118.LP
119If [f1,f2,...,fm] ((f1 f2 ... fn)) is empty, then
120generated code is simply written to the current output file(s).
121.LP
122However, if it is given, then the current output file is
123temporarily overridden.  Generated code is written to each file
124represented by f1,f2,...,fn for this command
125only.  Files which were open prior to the call to \fIgentranin\fR
126will remain open after the call, and files which did not exist
127prior to the call will be created, opened, written to, and
128closed.  The output file stack will be exactly the same both
129before and after the call.
130.SH
131Return Value:
132.LP
133\fIgentranin\fR returns the names of all files written to by this
134command.
135.SH
136Diagnostic Messages:
137.LP
138Nonexistent Input File
139.sp
140Template File Already Open for Input
141.sp
142Wrong Type of Arg
143.SH
144Example:
145.LP
146Suppose we wish to generate a FORTRAN subprogram to compute the determinant
147of a 3 x 3 matrix.  We can construct a template file with an outline of the
148FORTRAN subprogram and VAXIMA and GENTRAN commands to fill it in:
149.DS L
150.ft CR
151Contents of file det.tem:
152+----------------------------------------------+
153|      real*8 function det(m)                  |
154|      real*8 m(3,3)                           |
155|<<                                            |
156|      m : genmatrix(m, 3,3, 1,1)$             |
157|      gentran( rsetq( det, determinant(m) ) )$|
158|>>                                            |
159|      return                                  |
160|      end                                     |
161+----------------------------------------------+
162.ft
163.DE
164.LP
165Now we can generate a FORTRAN subprogram with the following VAXIMA session:
166.DS L
167.ft CR
168(c1) gentranlang(fortran)$
169.ft
170.DE
171.DS L
172.ft CR
173(c2) gentranin("det.tem", ["det.f"]);
174
175(d2)                       det.f
176.ft
177.DE
178.DS L
179.ft CR
180Contents of file det.f:
181+------------------------------------------------------------------------+
182|      real*8 function det(m)                                            |
183|      real*8 m(3,3)                                                     |
184|      det=m(1,3)*(-m(2,2)*m(3,1)+m(2,1)*m(3,2))-m(1,2)*(-m(2,3)*m(3,1)+m|
185|     . (2,1)*m(3,3))+m(1,1)*(-m(2,3)*m(3,2)+m(2,2)*m(3,3))              |
186|      return                                                            |
187|      end                                                               |
188+------------------------------------------------------------------------+
189.ft
190.DE
191.NH 3
192Copying Files into Template Files
193.LP
194Template files can be copied into other template files with recursive
195calls to \fIgentranin\fR; i.e., by calling \fIgentranin\fR from the
196active part of a template file.
197.LP
198For example, suppose we wish to copy the contents of the file det.f,
199generated in the previous section, into a file containing a main
200program.  The template file for the main program, main.tem, will
201contain an active part to copy the contents of det.f:
202.DS L
203.ft CR
204Contents of file main.tem:
205+----------------------------------------+
206|c                                       |
207|c --- Main Program ---                  |
208|c                                       |
209|      real*8 m(3,3),det                 |
210|      write(6,*) 'Enter 3 x 3 Matrix:'  |
211|      do 100 i=1,3                      |
212|          read(5,*) (m(i,j),j=1,3)      |
213|100   continue                          |
214|      write(6,*) 'Determinant = ',det(m)|
215|      stop                              |
216|      end                               |
217|c                                       |
218|c --- Determinant Calculation ---       |
219|c                                       |
220|<<                                      |
221|      gentranin("det.f")$               |
222|>>                                      |
223+----------------------------------------+
224.ft
225.DE
226.LP
227The following VAXIMA session will create the file main.f:
228.DS L
229.ft CR
230(c1) gentranin("main.tem", ["main.f"]);
231
232(d1)                       main.f
233.ft
234.DE
235.DS L
236.ft CR
237Contents of file main.f:
238+------------------------------------------------------------------------+
239|c                                                                       |
240|c --- Main Program ---                                                  |
241|c                                                                       |
242|      real*8 m(3,3),det                                                 |
243|      write(6,*) 'Enter 3 x 3 Matrix:'                                  |
244|      do 100 i=1,3                                                      |
245|          read(5,*) (m(i,j),j=1,3)                                      |
246|100   continue                                                          |
247|      write(6,*) 'Determinant = ',det(m)                                |
248|      stop                                                              |
249|      end                                                               |
250.ft
251.DE
252.DS L
253.ft CR
254|c                                                                       |
255|c --- Determinant Calculation ---                                       |
256|c                                                                       |
257|      real*8 function det(m)                                            |
258|      real*8 m(3,3)                                                     |
259|      det=m(1,3)*(-m(2,2)*m(3,1)+m(2,1)*m(3,2))-m(1,2)*(-m(2,3)*m(3,1)+m|
260|     . (2,1)*m(3,3))+m(1,1)*(-m(2,3)*m(3,2)+m(2,2)*m(3,3))              |
261|      return                                                            |
262|      end                                                               |
263+------------------------------------------------------------------------+
264.ft
265.DE
266.NH 3
267The Template File Stack
268.LP
269The VAXIMA \fIbatch\fR command takes one file name as its argument.  VAXIMA
270reads in the file and executes all statements and commands, any of which
271may be another \fIbatch\fR command.  A stack of input file names is
272maintained by VAXIMA to allow recursive invocation of the \fIbatch\fR
273command.  Similarly, a stack of template file names is maintained by
274GENTRAN to facilitate recursive invocation of the template
275processor.  Section 3.2 showed that the \fIgentranin\fR command can be
276called recursively to copy files into other files.  This section shows that
277template files which are copied into other template files can also contain
278active parts, and thus, the whole code generation process can be
279invoked recursively.
280.LP
281We can generalize the example of section 3.2 by generating code
282recursively.  We can extend it to generate code which will compute
283entries of the inverse matrix, also.  Suppose we have created the
284file init.in, which contains a VAXIMA command to create an
285n x n matrix, m, and initialize its entries to
286m(1,1), m(1,2), ..., m(n,n), for some user-entered value
287n:
288.DS L
289.ft CR
290Contents of file init.in:
291+---------------------------+
292|m : genmatrix(m, n,n, 1,1)$|
293+---------------------------+
294.ft
295.DE
296.LP
297We have also created template files det.tem and inv.tem
298which contain outlines of FORTRAN subprograms to compute the
299determinant and inverse of an n x n matrix, m,
300respectively:
301.DS L
302.ft CR
303Contents of file det.tem:
304+-------------------------------------------------------+
305|      real*8 function det(m)                           |
306|<<                                                     |
307|      gentran( type("real*8", m(eval(n),eval(n)) ),    |
308|               rsetq( det, determinant(m) )        )$  |
309|>>                                                     |
310|      return                                           |
311|      end                                              |
312+-------------------------------------------------------+
313.ft
314.DE
315.DS L
316.ft CR
317Contents of file inv.tem:
318+-------------------------------------------------------+
319|      subroutine inv(m,minv)                           |
320|<<                                                     |
321|      gentran( type("real*8", m(eval(n),eval(n)),      |
322|                              minv(eval(n),eval(n))),  |
323|               rsetq( minv, m^^(-1) )                )$|
324|>>                                                     |
325|      return                                           |
326|      end                                              |
327+-------------------------------------------------------+
328.ft
329.DE
330.LP
331Now we can construct a template file with a generalized version of
332the main program given in section 3.2 and can place \fIgentranin\fR
333commands in this file to generate code recursively from the template
334files det.tem and inv.tem:
335.DS L
336.ft CR
337Contents of file main.tem:
338+-------------------------------------------------------------------+
339|c                                                                  |
340|c  Main Program                                                    |
341|c                                                                  |
342|<<                                                                 |
343|      gentran( type("real*8", m(eval(n),eval(n)),                  |
344|                              det,                                 |
345|                              minv(eval(n),eval(n)) ),             |
346|               type("integer", n),                                 |
347|               literal(tab, "data n/", eval(n), "/", cr) )$        |
348|>>                                                                 |
349|      write(6,*) 'Enter ',n,' x ',n,' Matrix:'                     |
350|      do 100 i=1,n                                                 |
351|          read(5,*) (m(i,j),j=1,n)                                 |
352|100   continue                                                     |
353|      write(6,*) 'Determinant = ',det(m)                           |
354|      write(6,*) 'Inverse Matrix:'                                 |
355|      call inv(m,minv)                                             |
356|      do 200 i=1,n                                                 |
357|          write(6,*) (minv(i,j),j=1,n)                             |
358|200   continue                                                     |
359|      stop                                                         |
360|      end                                                          |
361.ft
362.DE
363.DS L
364.ft CR
365|c                                                                  |
366|c  Determinant Calculation                                         |
367|c                                                                  |
368|<<                                                                 |
369|      gentranin("det.tem")$                                        |
370|>>                                                                 |
371|c                                                                  |
372|c  Inverse Calculation                                             |
373|c                                                                  |
374|<<                                                                 |
375|      gentranin("inv.tem")$                                        |
376|>>                                                                 |
377+-------------------------------------------------------------------+
378.ft
379.DE
380.LP
381The following VAXIMA session will create the file main.f:
382.DS L
383.ft CR
384(c1) n : 3$
385.ft
386.DE
387.DS L
388.ft CR
389(c2) batch("init.in");
390
391(c3) m : genmatrix(m, n,n, 1,1)$
392
393(d4)                       BATCH DONE
394.ft
395.DE
396.DS L
397.ft CR
398(c5) gentranlang(fortran)$
399.ft
400.DE
401.DS L
402.ft CR
403(c6) gentranin("main.tem", ["main.f"]);
404
405(d6)                       main.f
406.ft
407.DE
408.DS L
409.ft CR
410Contents of file main.f:
411+------------------------------------------------------------------------+
412|c                                                                       |
413|c  Main Program                                                         |
414|c                                                                       |
415.ft
416.DE
417.DS L
418.ft CR
419|      real*8 m(3,3),det,minv(3,3)                                       |
420|      integer n                                                         |
421|      data n/3/                                                         |
422|      write(6,*) 'Enter ',n,' x ',n,' Matrix:'                          |
423|      do 100 i=1,n                                                      |
424|          read(5,*) (m(i,j),j=1,n)                                      |
425|100   continue                                                          |
426|      write(6,*) 'Determinant = ',det(m)                                |
427|      write(6,*) 'Inverse Matrix:'                                      |
428|      call inv(m,minv)                                                  |
429|      do 200 i=1,n                                                      |
430|          write(6,*) (minv(i,j),j=1,n)                                  |
431|200   continue                                                          |
432|      stop                                                              |
433|      end                                                               |
434|c                                                                       |
435|c  Determinant Calculation                                              |
436|c                                                                       |
437|      real*8 function det(m)                                            |
438|      real*8 m(3,3)                                                     |
439|      det=m(1,3)*(-m(2,2)*m(3,1)+m(2,1)*m(3,2))-m(1,2)*(-m(2,3)*m(3,1)+m|
440|     . (2,1)*m(3,3))+m(1,1)*(-m(2,3)*m(3,2)+m(2,2)*m(3,3))              |
441|      return                                                            |
442|      end                                                               |
443|c                                                                       |
444|c  Inverse Calculation                                                  |
445|c                                                                       |
446|      subroutine inv(m,minv)                                            |
447|      real*8 m(3,3),minv(3,3)                                           |
448|      minv(1,1)=(-m(2,3)*m(3,2)+m(2,2)*m(3,3))/((-m(1,3)*m(2,2)+m(1,2)*m|
449|     . (2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,1|
450|     . )+m(1,1)*m(2,2))*m(3,3))                                         |
451|      minv(1,2)=-(-m(1,3)*m(3,2)+m(1,2)*m(3,3))/((-m(1,3)*m(2,2)+m(1,2)*|
452|     . m(2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,|
453|     . 1)+m(1,1)*m(2,2))*m(3,3))                                        |
454|      minv(1,3)=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))/((-m(1,3)*m(2,2)+m(1,2)*m|
455|     . (2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,1|
456|     . )+m(1,1)*m(2,2))*m(3,3))                                         |
457|      minv(2,1)=-(-m(2,3)*m(3,1)+m(2,1)*m(3,3))/((-m(1,3)*m(2,2)+m(1,2)*|
458|     . m(2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,|
459|     . 1)+m(1,1)*m(2,2))*m(3,3))                                        |
460|      minv(2,2)=(-m(1,3)*m(3,1)+m(1,1)*m(3,3))/((-m(1,3)*m(2,2)+m(1,2)*m|
461|     . (2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,1|
462|     . )+m(1,1)*m(2,2))*m(3,3))                                         |
463|      minv(2,3)=-(-m(1,3)*m(2,1)+m(1,1)*m(2,3))/((-m(1,3)*m(2,2)+m(1,2)*|
464|     . m(2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,|
465|     . 1)+m(1,1)*m(2,2))*m(3,3))                                        |
466|      minv(3,1)=(-m(2,2)*m(3,1)+m(2,1)*m(3,2))/((-m(1,3)*m(2,2)+m(1,2)*m|
467|     . (2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,1|
468|     . )+m(1,1)*m(2,2))*m(3,3))                                         |
469|      minv(3,2)=-(-m(1,2)*m(3,1)+m(1,1)*m(3,2))/((-m(1,3)*m(2,2)+m(1,2)*|
470|     . m(2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,|
471|     . 1)+m(1,1)*m(2,2))*m(3,3))                                        |
472|      minv(3,3)=(-m(1,2)*m(2,1)+m(1,1)*m(2,2))/((-m(1,3)*m(2,2)+m(1,2)*m|
473|     . (2,3))*m(3,1)+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)+(-m(1,2)*m(2,1|
474|     . )+m(1,1)*m(2,2))*m(3,3))                                         |
475|      return                                                            |
476|      end                                                               |
477+------------------------------------------------------------------------+
478.ft
479.DE
480.LP
481This is an example of a modular approach to code generation;
482separate subprogram templates are given in separate
483files.  Furthermore, the template files are general; they can be
484used for matrices of any predetermined size.  Therefore, we
485can easily generate different subprograms to handle matrices
486of different sizes from the same template files simply by
487assigning different values to n, and reloading the file
488init.in.
489.NH 2
490Insertion of Generated Type Declarations
491.LP
492The \fIgendecs\fR flag makes it possible to generate declarations
493for variables generated from within active parts of template files.
494.SH
495Example:
496.LP
497Suppose we wish to process a template file which will cause GENTRAN
498to generate one or more temporary variables in an active part.  We can
499tell GENTRAN to generate declarations in the correct location by
500processing the template file twice as follows:
501.LP
502Construct the template file as usual, but with two additions:
503.IP 1)
504Insert an active part at the beginning of the file to turn the
505\fIgendecs\fR flag off:
506.DS L
507.ft CR
508<<  off(gendecs)$  >>
509.ft
510.DE
511.IP 2)
512Insert an active part immediately after the subprogram heading to write
513an active part to the output file.  This active part will cause the
514\fIgendecs\fR flag to be switched back on during the second pass over
515the template file:
516.DS L
517.ft CR
518<<  gentran( literal("<<  on(gendecs)\e$  \e>\e>", cr) )$  >>
519.ft
520.DE
521.LP
522For example, suppose the original template file contains the following:
523.DS L
524.ft CR
525Contents of file detinv.tem:
526+------------------------------------------------------------+
527|      subroutine detinv(m,det,inv)                          |
528|<<                                                          |
529|      off(gendecs)$                                         |
530|      gentran( literal("<<    on(gendecs)\e$    \e>\e>", cr) )$|
531|>>                                                          |
532|<<                                                          |
533|      m : genmatrix(m, n,n, 1,1)$                           |
534|      gentran( type("real*8", m(eval(n),eval(n))) )$        |
535|>>                                                          |
536|<<                                                          |
537|      gentran( type("real*8", det),                         |
538|               rsetq( det, determinant(m) ) )$              |
539|>>                                                          |
540|<<                                                          |
541|      gentran( type("real*8", inv(eval(n),eval(n))),        |
542|               rsetq( inv, m^^(-1) ) )$                     |
543|>>                                                          |
544|      return                                                |
545|      end                                                   |
546+------------------------------------------------------------+
547.ft
548.DE
549Now we are ready to invoke the template processor.  Since it must make
550two passes over the template file, we will invoke it twice and have it
551write to a temporary file as follows:
552.DS L
553.ft CR
554(c1) n : 3$
555.ft
556.DE
557.DS L
558.ft CR
559(c2) ?maxexpprintlen\* : 60$
560.ft
561.DE
562.DS L
563.ft CR
564(c3) gentranin("detinv.tem", ["##detinv"]);
565
566(d3)                       ##detinv
567.ft
568.DE
569.DS L
570.ft CR
571(c4) gentranin("##detinv", ["detinv.f"]);
572
573(d4)                       detinv.f
574.ft
575.DE
576.LP
577After the first template processing command has been executed, ##detinv
578contains the following:
579.DS L
580.ft CR
581Contents of file ##detinv:
582+------------------------------------------------------------+
583|      subroutine detinv(m,det,inv)                          |
584|<<    on(gendecs)$    >>                                    |
585|      t0=m(1,3)*(-m(2,2)*m(3,1)+m(2,1)*m(3,2))              |
586|      t0=t0-m(1,2)*(-m(2,3)*m(3,1)+m(2,1)*m(3,3))           |
587|      det=t0+m(1,1)*(-m(2,3)*m(3,2)+m(2,2)*m(3,3))          |
588|      t1=-m(2,3)*m(3,2)+m(2,2)*m(3,3)                       |
589|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
590|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
591|      inv(1,1)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
592|      t1=-(-m(1,3)*m(3,2)+m(1,2)*m(3,3))                    |
593|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
594|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
595|      inv(1,2)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
596|      t1=-m(1,3)*m(2,2)+m(1,2)*m(2,3)                       |
597|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
598|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
599|      inv(1,3)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
600|      t1=-(-m(2,3)*m(3,1)+m(2,1)*m(3,3))                    |
601|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
602|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
603|      inv(2,1)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
604|      t1=-m(1,3)*m(3,1)+m(1,1)*m(3,3)                       |
605|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
606|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
607|      inv(2,2)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
608|      t1=-(-m(1,3)*m(2,1)+m(1,1)*m(2,3))                    |
609|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
610|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
611|      inv(2,3)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
612|      t1=-m(2,2)*m(3,1)+m(2,1)*m(3,2)                       |
613|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
614|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
615|      inv(3,1)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
616|      t1=-(-m(1,2)*m(3,1)+m(1,1)*m(3,2))                    |
617|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
618|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
619|      inv(3,2)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
620|      t1=-m(1,2)*m(2,1)+m(1,1)*m(2,2)                       |
621|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
622|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
623|      inv(3,3)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
624|      return                                                |
625|      end                                                   |
626+------------------------------------------------------------+
627.ft
628.DE
629This is a temporary file.  It can be removed after the second \fIgentranin\fR
630command has been executed.
631.LP
632The final output file will contain the following:
633.DS L
634.ft CR
635Contents of file detinv.f:
636+------------------------------------------------------------+
637|      subroutine detinv(m,det,inv)                          |
638|      real*8 m(3,3),det,inv(3,3),t0,t1                      |
639|      t0=m(1,3)*(-m(2,2)*m(3,1)+m(2,1)*m(3,2))              |
640|      t0=t0-m(1,2)*(-m(2,3)*m(3,1)+m(2,1)*m(3,3))           |
641|      det=t0+m(1,1)*(-m(2,3)*m(3,2)+m(2,2)*m(3,3))          |
642|      t1=-m(2,3)*m(3,2)+m(2,2)*m(3,3)                       |
643|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
644|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
645|      inv(1,1)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
646|      t1=-(-m(1,3)*m(3,2)+m(1,2)*m(3,3))                    |
647|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
648|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
649|      inv(1,2)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
650|      t1=-m(1,3)*m(2,2)+m(1,2)*m(2,3)                       |
651|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
652|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
653|      inv(1,3)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
654|      t1=-(-m(2,3)*m(3,1)+m(2,1)*m(3,3))                    |
655|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
656|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
657|      inv(2,1)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
658|      t1=-m(1,3)*m(3,1)+m(1,1)*m(3,3)                       |
659|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
660|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
661|      inv(2,2)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
662|      t1=-(-m(1,3)*m(2,1)+m(1,1)*m(2,3))                    |
663|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
664|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
665|      inv(2,3)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
666|      t1=-m(2,2)*m(3,1)+m(2,1)*m(3,2)                       |
667|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
668|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
669|      inv(3,1)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
670|      t1=-(-m(1,2)*m(3,1)+m(1,1)*m(3,2))                    |
671|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
672|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
673|      inv(3,2)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
674|      t1=-m(1,2)*m(2,1)+m(1,1)*m(2,2)                       |
675|      t0=(-m(1,3)*m(2,2)+m(1,2)*m(2,3))*m(3,1)              |
676|      t0=t0+(m(1,3)*m(2,1)-m(1,1)*m(2,3))*m(3,2)            |
677|      inv(3,3)=t1/(t0+(-m(1,2)*m(2,1)+m(1,1)*m(2,2))*m(3,3))|
678|      return                                                |
679|      end                                                   |
680+------------------------------------------------------------+
681.ft
682.DE
683.NH 2
684Special Template Variables
685.LP
686
687    ** Not Implemented Yet **
688