Version 12 of a tcl script for function value listing based on a fortran expression

Updated 2005-04-06 17:01:45 by lwv

tv

As part of some maxima ramblings, a little script to take a FORTRAN expression, which is used to generate efficiently computed list of function values.

A possible use for this is to generate heavy graphs from mathematica expressions, which can be converted into fortran expressions with the fortran command:

   fortran(diff(sin(x)/x,x));
      COS(x)/x-SIN(x)/x**2

The idea is to have an easy to use C program that calls a little fortran subroutine, and that whole program is invoked by a tcl proc, which also takes care of the combined compilation of the fortran and C function value loop code, and the exec of the resulting executable:

 # Feed this Tcl proc a fortran expression
 proc formake {e} {
   global f
   set t [subst -nocommand {
      subroutine sayhello(x,r)
        real x,r
        r = $e
        return 
      end 
   }]
   set f [open sub.f w]
   puts $f [string trim $t \n]
   close $f
   exec gcc -o fm sub.f main.c -lm
   return [exec fm]
 }

(DKF: Adapted the above to use subst for greater code clarity.) (TV Isn't there a backward compatibility issue with this ?) (DKF: Certainly not if your version of Tcl is less than 10 years old.)

[TV} (apr 6 '05) I've changed the declaration of the reals; I guess this is correct according to the fortran way...

This, or an adapted, C program is needed in the current directory:

 /* This is file: main.c */
 #include<stdio.h>
 #include<math.h>

 extern void sayhello_(float *, float *);

 int main(argc, argv)
 int argc;
 char *argv[];
 {
   float in, out;
   float x, start, stop, incr;

   if (argc == 1) {
      start = -10.0;
      stop = 10.0;
      incr = 2.0;
   } else exit(-1);
   for (x=start; x<=stop; x+=incr) {
      in = x;
      sayhello_(&in,&out);
      printf("%f %f\n", x, (float) out);
   }
   return(0);
 }

Calling the formake routine in this case returns a formatted list of 21 X Y values, but it could return more. Of course braces could be added to automatically create a Tcl list as result.

There is nothing against using these methods in Bwise blocks.

Note that this approach assumes running on a linux like or compatible (like maybe cygwin) system, with gcc present with fortran extensions, I tested on RH9, which worked fast.


LV Too bad that critcl couldn't do the FORTRAN compilation...

TV Maybe some day Maxima will on top of a Tk interface also have tcl/expr inteface, or who knowns, maybe somebody has time and vision to replace the LISP based code with tcl code... (wish wish). But Linux and cygwin (for windows) have the gnu compiler which does the job fine and fast.

LV and in fact, critcl makes use of the gnu compiler to do its job - so in theory, the above code could be modified so that the FORTRAN subroutine were somehow passed to critcl to compile. That would seem to eliminate the need for the special C hooks.

[TV} Well, when you have the gnu complier already, it's not hard to do the compilation:

   exec gcc -o fm sub.f main.c -lm

isn't exactly the holy grail in university research...

LV I guess the reference to critcl isn't being understood. What critcl currently allows the developer to do is to put C code in-line in the Tcl program, dynamically create a loadable function, and invoke it, 'transparently' to the developer. No coding of an exec, no main.c, etc. needed. The end result is a Tcl function that can be called as if it were a part of Tcl.


Category Example