~ubuntu-branches/ubuntu/karmic/maxima/karmic

« back to all changes in this revision

Viewing changes to share/contrib/gentran/man/sect3.ms

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-11-13 18:39:14 UTC
  • mto: (2.1.2 hoary) (3.2.1 sid) (1.1.5 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20041113183914-ttig0evwuatnqosl
Tags: upstream-5.9.1
ImportĀ upstreamĀ versionĀ 5.9.1

Show diffs side-by-side

added added

removed removed

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