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.
12
The Template Processing Command
17
\fIgentranin(\fRf1,f2,...,fn {,[f1,f2,...,fm]});
20
where f1,f2,...,fn is an argument list containing one or more
21
f's, each of which is one of the following:
24
a string = a template (input) file
25
\fItrue\fR = the terminal
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
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
44
\fI(gentranin '(\fRf1 f2 ... fn) '(f1 f2 ... fm))
47
where f1 f2 ... fn is an argument list containing one or
48
more f's, each of which is one of the following:
51
a string = a template (input) file
52
\fIt\fR = the terminal
55
and (f1 f2 ... fm) is an argument list which
56
contains zero or more f's, each of which is one of the
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
70
\fIgentranin\fR processes each template file f1,f2,...,fn
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 >>.
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,
84
C ... <cr> for FORTRAN (beginning in column 1) or
85
* ... <cr> for FORTRAN (beginning in column 1),
86
# ... <cr> for RATFOR, and
90
is also copied in its entirety to the output. Thus the character
91
sequences << and >> have no special meanings within
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.
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.
105
If [f1,f2,...,fm] ((f1 f2 ... fn)) is empty, then
106
generated code is simply written to the current output file(s).
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.
119
\fIgentranin\fR returns the names of all files written to by this
124
Nonexistent Input File
126
Template File Already Open for Input
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:
136
Contents of file det.tem:
137
+----------------------------------------------+
138
| real*8 function det(m) |
141
| m : genmatrix(m, 3,3, 1,1)$ |
142
| gentran( rsetq( det, determinant(m) ) )$|
146
+----------------------------------------------+
149
Now we can generate a FORTRAN subprogram with the following VAXIMA session:
151
(c1) gentranlang(fortran)$
154
(c2) gentranin("det.tem", ["det.f"]);
159
Contents of file det.f:
160
+------------------------------------------------------------------------+
161
| real*8 function det(m) |
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)) |
167
+------------------------------------------------------------------------+
170
Copying Files into Template Files
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.
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:
181
Contents of file main.tem:
182
+----------------------------------------+
184
|c --- Main Program --- |
186
| real*8 m(3,3),det |
187
| write(6,*) 'Enter 3 x 3 Matrix:' |
189
| read(5,*) (m(i,j),j=1,3) |
191
| write(6,*) 'Determinant = ',det(m)|
195
|c --- Determinant Calculation --- |
198
| gentranin("det.f")$ |
200
+----------------------------------------+
203
The following VAXIMA session will create the file main.f:
205
(c1) gentranin("main.tem", ["main.f"]);
210
Contents of file main.f:
211
+------------------------------------------------------------------------+
213
|c --- Main Program --- |
215
| real*8 m(3,3),det |
216
| write(6,*) 'Enter 3 x 3 Matrix:' |
218
| read(5,*) (m(i,j),j=1,3) |
220
| write(6,*) 'Determinant = ',det(m) |
226
|c --- Determinant Calculation --- |
228
| real*8 function det(m) |
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)) |
234
+------------------------------------------------------------------------+
237
The Template File Stack
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
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
259
Contents of file init.in:
260
+---------------------------+
261
|m : genmatrix(m, n,n, 1,1)$|
262
+---------------------------+
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,
270
Contents of file det.tem:
271
+-------------------------------------------------------+
272
| real*8 function det(m) |
274
| gentran( type("real*8", m(eval(n),eval(n)) ), |
275
| rsetq( det, determinant(m) ) )$ |
279
+-------------------------------------------------------+
282
Contents of file inv.tem:
283
+-------------------------------------------------------+
284
| subroutine inv(m,minv) |
286
| gentran( type("real*8", m(eval(n),eval(n)), |
287
| minv(eval(n),eval(n))), |
288
| rsetq( minv, m^^(-1) ) )$|
292
+-------------------------------------------------------+
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:
300
Contents of file main.tem:
301
+-------------------------------------------------------------------+
306
| gentran( type("real*8", m(eval(n),eval(n)), |
308
| minv(eval(n),eval(n)) ), |
309
| type("integer", n), |
310
| literal(tab, "data n/", eval(n), "/", cr) )$ |
312
| write(6,*) 'Enter ',n,' x ',n,' Matrix:' |
314
| read(5,*) (m(i,j),j=1,n) |
316
| write(6,*) 'Determinant = ',det(m) |
317
| write(6,*) 'Inverse Matrix:' |
320
| write(6,*) (minv(i,j),j=1,n) |
327
|c Determinant Calculation |
330
| gentranin("det.tem")$ |
333
|c Inverse Calculation |
336
| gentranin("inv.tem")$ |
338
+-------------------------------------------------------------------+
341
The following VAXIMA session will create the file main.f:
346
(c2) batch("init.in");
348
(c3) m : genmatrix(m, n,n, 1,1)$
353
(c5) gentranlang(fortran)$
356
(c6) gentranin("main.tem", ["main.f"]);
361
Contents of file main.f:
362
+------------------------------------------------------------------------+
368
| real*8 m(3,3),det,minv(3,3) |
371
| write(6,*) 'Enter ',n,' x ',n,' Matrix:' |
373
| read(5,*) (m(i,j),j=1,n) |
375
| write(6,*) 'Determinant = ',det(m) |
376
| write(6,*) 'Inverse Matrix:' |
379
| write(6,*) (minv(i,j),j=1,n) |
384
|c Determinant Calculation |
386
| real*8 function det(m) |
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)) |
393
|c Inverse Calculation |
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)) |
426
+------------------------------------------------------------------------+
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
438
Insertion of Generated Type Declarations
440
The \fIgendecs\fR flag makes it possible to generate declarations
441
for variables generated from within active parts of template files.
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:
450
Construct the template file as usual, but with two additions:
452
Insert an active part at the beginning of the file to turn the
453
\fIgendecs\fR flag off:
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
463
<< gentran( literal("<< on(gendecs)\e$ \e>\e>", cr) )$ >>
466
For example, suppose the original template file contains the following:
468
Contents of file detinv.tem:
469
+------------------------------------------------------------+
470
| subroutine detinv(m,det,inv) |
473
| gentran( literal("<< on(gendecs)\e$ \e>\e>", cr) )$|
476
| m : genmatrix(m, n,n, 1,1)$ |
477
| gentran( type("real*8", m(eval(n),eval(n))) )$ |
480
| gentran( type("real*8", det), |
481
| rsetq( det, determinant(m) ) )$ |
484
| gentran( type("real*8", inv(eval(n),eval(n))), |
485
| rsetq( inv, m^^(-1) ) )$ |
489
+------------------------------------------------------------+
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:
498
(c2) ?maxexpprintlen\* : 60$
501
(c3) gentranin("detinv.tem", ["##detinv"]);
506
(c4) gentranin("##detinv", ["detinv.f"]);
511
After the first template processing command has been executed, ##detinv
512
contains the following:
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))|
559
+------------------------------------------------------------+
561
This is a temporary file. It can be removed after the second \fIgentranin\fR
562
command has been executed.
564
The final output file will contain the following:
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))|
611
+------------------------------------------------------------+
614
Special Template Variables
617
** Not Implemented Yet **