Home | About | Partners | Contact Us
SourceForge Logo

Quick Links

Home
News
Thoughts and Rants
License
SourceForge Info
Download
Browse CVS
Mailing Lists

Thin Tools Examples...

Symbolic Differentiation
Constant folding
Execution Tracer
Contracts in Java
Removing useless code

Understanding...

Concept programming
Moka
XL
Thin Tools
Active Libraries
Refactoring
Optimizations
Coda
Notes

More Info

Contributors
Related Ideas
Some history
Applications
Other links
The GNU Project

Differentiation Thin Tool

Concept programming is about correctly representing application concepts in the code. Symbolic differentiation is a relatively simple concept from mathematics, and a transformation that cheap calculators know how to do very well. It's cumbersome, it's error prone. In short, you don't want to do it manually.

Yet, a scientist who wants to introduce symbolic differentiation notations in her C, C++ or Java program cannot do so easily (papers have been written on how to do that in C++, it's hard). Mainstream programming languages today do not include a symbolic derivative feature, because it is too specialized. And they cannot easily be extended to incorporate it either.

Symbolic differentiation is a good example of application specific concept. The differentiation plugin is an example of thin tool which implements symbolic differentiation. The source code is about 400 lines of rather simple C++. You are invited to contrast this with the C++ approach.

Extending Java

Used in conjunction with Moka, the symbolic derivative plug-in recognizes the symbolic derivative notation in the following invalid Java program.

// This example shows the symbolic differentiation "plugin"
class Test
{

    public static final double omega = 3.276;
    public static final double theta = 0.227;
    public static final double decay = 1.447E-3;

    public static int main(String args[]) {

        // Tabulate the following expression
        for (double t = 0.0; t < 50.0; t += 0.01) {
            double y = d(sin(2 * omega * t + theta) * exp(-decay * t))/dt;
            System.out.println("t=" + t + ", y=" + y);
        }
    }
}

The plug-in can be invoked using the following command line (NB: 'derivation' is the french word for 'differentiation', which I incorrectly assumed applied in english as well):

% moka tests/derivation.java +derivation -out

The output is the following program, where the symbolic derivative has been transformed into valid Java and can now be compiled. Notice that the plug-in inserts annotation explaining the transformations that occured.

// This example shows the symbolic differentiation "plugin"
class Test
{  
   
   
public static final double omega = 3.276
;
   public static final double theta = 0.227;
   public static final double decay = 0.001447;
   
   
public static int main(String[] args)
   {  
      
      // Tabulate the following expression
      
for(double t = 0t < 50t += 0.01)
      {  
         double y = 
         /**d(x*y)/dz->dx/dz*y+x*dy/dz**/
         /**dsin(x)/dx->cos(x)**/cos (2 * omega * t + theta) * (
            /**d(x+y)/dz->dx/dz+dy/dz**/
            /**d(x*y)/dz->dx/dz*y+x*dy/dz**/(
               /**d(x*y)/dz->dx/dz*y+x*dy/dz**/
               /**Integer Constant->0**/0 * omega + 2 * 
               /**dx/dy->0**/0) * t + 2 * omega * 
            /**dx/dx->1**/1 + 
            /**dx/dy->0**/0) * exp (-decay * t) + sin (2 * omega * t + theta) * (
            /**dexp(x)/dx->exp(x)**/exp (-decay * t) * (
               /**d(x*y)/dz->dx/dz*y+x*dy/dz**/-decay * t + -decay * 
               /**dx/dx->1**/1));
         System.out.println ("t=" + t + ", y=" + y);
      }
   }

}

Symbolic Differentiation in XL

The XL pragmas are designed to support external plug-ins. Therefore, you can invoke the same differentiation plug-in on a local portion of an XL source file simply by prefixing the corresponding declaration or instruction with a pragma using the name of the plug-in, followed by possible arguments. The major difference compared to the Moka usage outlined above is that it doesn't apply to the whole source file. This is illustrated by the following XL compiler test:

// REF=.ref
import IO = XL.UI.CONSOLE
import XL.MATH
using  XL.MATH

function dcos(real X) return real is
    return X;

procedure Main is
   with real X := 3.14159265358
   with real Y := {derivation} dsin(X)/dX
   IO.WriteLn "With pragma, dsin(X)/dX for X=", X, " is ", Y
   with real dX := 0.1;
   with real Z := dcos(X)/dX
   IO.WriteLn "Without pragma, dcos(X)/dX for X=", X, " is ", Z

This test displays the following output:

With pragma, dsin(X)/dX for X=3.14159 is -1
Without pragma, dcos(X)/dX for X=3.14159 is 31.4159

The variable Y is computed by invoking the pragma, which computes cos(pi), which is -1, while the expression dcos(X)/dX is not processed by the derivative plug-in, and therefore computes pi/0.1.

Useful complements

If you need to actually deal with the resulting source code, the result of the symbolic differentiation can be further simplified by applying the constantfold plug-in. This removes the unnecessary operations from the original source code.


Copyright Christophe de Dinechin
First published Feb 17, 2000
Version 1.6 (updated 2004/01/20 06:16:14)