You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/09/28 18:41:38 UTC

svn commit: r1391537 - in /commons/sandbox/nabla/trunk/src: main/java/org/apache/commons/nabla/forward/ main/java/org/apache/commons/nabla/forward/analysis/ main/java/org/apache/commons/nabla/forward/arithmetic/ main/java/org/apache/commons/nabla/forwa...

Author: luc
Date: Fri Sep 28 16:41:37 2012
New Revision: 1391537

URL: http://svn.apache.org/viewvc?rev=1391537&view=rev
Log:
Updated conversion of simple arithmetic expressions.

Arithmetic expressions now use DerivativeStructure to compute arbitrary
order and arbitrary number of parameters derivatives.

Added:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java   (with props)
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java   (with props)
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java   (with props)
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java   (with props)
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java   (with props)
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java   (contents, props changed)
      - copied, changed from r1391536, commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Pop2Transformer.java
      - copied, changed from r1391536, commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java
Removed:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer12.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer2.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer12.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer2.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer12.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer2.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer12.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer2.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer12.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer2.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer1.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer12.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer2.java
Modified:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/InstructionsTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DNegTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DLoadTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DStoreTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2Transformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X1Transformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/WideningTransformer.java
    commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/ForwardModeDifferentiator.java Fri Sep 28 16:41:37 2012
@@ -18,6 +18,7 @@ package org.apache.commons.nabla.forward
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
@@ -32,9 +33,11 @@ import org.apache.commons.math3.util.Fas
 import org.apache.commons.nabla.DifferentiationException;
 import org.apache.commons.nabla.NablaMessages;
 import org.apache.commons.nabla.forward.analysis.ClassDifferentiator;
+import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.util.TraceClassVisitor;
 
 /** Algorithmic differentiator class in forward mode based on bytecode analysis.
  * <p>This class is an implementation of the {@link UnivariateFunctionDifferentiator}
@@ -172,6 +175,9 @@ public class ForwardModeDifferentiator i
         throws DifferentiationException {
         try {
 
+            // TODO: the following print is for debug purpose only
+            new ClassReader(differentiableClass.getName()).accept(new TraceClassVisitor(new PrintWriter(System.err)), 0);
+
             // differentiate the function embedded in the differentiable class
             final ClassDifferentiator differentiator =
                 new ClassDifferentiator(differentiableClass, mathClasses);
@@ -186,6 +192,10 @@ public class ForwardModeDifferentiator i
             final String name = derived.name.replace('/', '.');
             derived.accept(writer);
             final byte[] bytecode = writer.toByteArray();
+
+            // TODO: the following print is for debug purpose only
+            new ClassReader(bytecode).accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
+
             Class<? extends UnivariateDifferentiableFunction> dClass =
                     new DerivativeLoader(differentiableClass).defineClass(name, bytecode);
             byteCodeMap.put(name, bytecode);

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/InstructionsTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/InstructionsTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/InstructionsTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/InstructionsTransformer.java Fri Sep 28 16:41:37 2012
@@ -16,7 +16,9 @@
  */
 package org.apache.commons.nabla.forward.analysis;
 
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.nabla.DifferentiationException;
+import org.objectweb.asm.Type;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
 
@@ -26,6 +28,9 @@ import org.objectweb.asm.tree.InsnList;
  */
 public interface InstructionsTransformer {
 
+    /** Type for {@link DerivativeStructure}. */
+    Type DS_TYPE = Type.getType(DerivativeStructure.class);
+
     /** Get the replacement instructions.
      * @param original original instruction
      * @param methodDifferentiator method differentiator driving this transformer

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/analysis/MethodDifferentiator.java Fri Sep 28 16:41:37 2012
@@ -29,22 +29,12 @@ import java.util.Set;
 import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.nabla.DifferentiationException;
 import org.apache.commons.nabla.NablaMessages;
-import org.apache.commons.nabla.forward.arithmetic.DAddTransformer1;
-import org.apache.commons.nabla.forward.arithmetic.DAddTransformer12;
-import org.apache.commons.nabla.forward.arithmetic.DAddTransformer2;
-import org.apache.commons.nabla.forward.arithmetic.DDivTransformer1;
-import org.apache.commons.nabla.forward.arithmetic.DDivTransformer12;
-import org.apache.commons.nabla.forward.arithmetic.DDivTransformer2;
-import org.apache.commons.nabla.forward.arithmetic.DMulTransformer1;
-import org.apache.commons.nabla.forward.arithmetic.DMulTransformer12;
-import org.apache.commons.nabla.forward.arithmetic.DMulTransformer2;
+import org.apache.commons.nabla.forward.arithmetic.DAddTransformer;
+import org.apache.commons.nabla.forward.arithmetic.DDivTransformer;
+import org.apache.commons.nabla.forward.arithmetic.DMulTransformer;
 import org.apache.commons.nabla.forward.arithmetic.DNegTransformer;
-import org.apache.commons.nabla.forward.arithmetic.DRemTransformer1;
-import org.apache.commons.nabla.forward.arithmetic.DRemTransformer12;
-import org.apache.commons.nabla.forward.arithmetic.DRemTransformer2;
-import org.apache.commons.nabla.forward.arithmetic.DSubTransformer1;
-import org.apache.commons.nabla.forward.arithmetic.DSubTransformer12;
-import org.apache.commons.nabla.forward.arithmetic.DSubTransformer2;
+import org.apache.commons.nabla.forward.arithmetic.DRemTransformer;
+import org.apache.commons.nabla.forward.arithmetic.DSubTransformer;
 import org.apache.commons.nabla.forward.functions.AcosTransformer;
 import org.apache.commons.nabla.forward.functions.AcoshTransformer;
 import org.apache.commons.nabla.forward.functions.AsinTransformer;
@@ -82,10 +72,9 @@ import org.apache.commons.nabla.forward.
 import org.apache.commons.nabla.forward.instructions.DcmpTransformer2;
 import org.apache.commons.nabla.forward.instructions.Dup2Transformer;
 import org.apache.commons.nabla.forward.instructions.Dup2X1Transformer;
-import org.apache.commons.nabla.forward.instructions.Dup2X2Transformer1;
-import org.apache.commons.nabla.forward.instructions.Dup2X2Transformer12;
-import org.apache.commons.nabla.forward.instructions.Dup2X2Transformer2;
+import org.apache.commons.nabla.forward.instructions.Dup2X2Transformer;
 import org.apache.commons.nabla.forward.instructions.NarrowingTransformer;
+import org.apache.commons.nabla.forward.instructions.Pop2Transformer;
 import org.apache.commons.nabla.forward.instructions.WideningTransformer;
 import org.apache.commons.nabla.forward.trimming.DLoadPop2Trimmer;
 import org.apache.commons.nabla.forward.trimming.SwappedDloadTrimmer;
@@ -96,7 +85,6 @@ import org.objectweb.asm.tree.AbstractIn
 import org.objectweb.asm.tree.FieldInsnNode;
 import org.objectweb.asm.tree.IincInsnNode;
 import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.InsnNode;
 import org.objectweb.asm.tree.LabelNode;
 import org.objectweb.asm.tree.LdcInsnNode;
 import org.objectweb.asm.tree.MethodInsnNode;
@@ -186,6 +174,15 @@ public class MethodDifferentiator {
         this.clonedLabels = new HashMap<LabelNode, LabelNode>();
     }
 
+    /** Get the index of the input {@link DerivativeStructure derivative structure} variable.
+     * @return index of the input {@link DerivativeStructure derivative structure} variable
+     */
+    public int getInputDSIndex() {
+        // TODO: this should be improved in the general case,
+        // as we are not sure the variable will always remain at index 1
+        return 1;
+    }
+
     /**
      * Differentiate a method.
      * @param primitiveName primitive class name
@@ -222,13 +219,18 @@ public class MethodDifferentiator {
 
             if (changes.isEmpty()) {
 
+                // TODO: merge this case with the general case: DRETURN must always be
+                // changed when the function signature changes, and the change is either
+                // converting DRETURN to ARETURN, possibly with a prepended call to
+                // convertDoubleToDerivativeStructure before the ARETURN when stack0converted
+                // is false
+
                 // the method does not depend on the parameter at all!
                 // we replace all "return d;" by "return new DerivativeStructure(parameters, order, d);"
                 for (final Iterator<AbstractInsnNode> i = method.instructions.iterator(); i.hasNext();) {
                     final AbstractInsnNode insn = i.next();
                     if (insn.getOpcode() == Opcodes.DRETURN) {
-                        final InsnList list = convertDoubleToDerivativeStructure(1);
-                        list.add(new InsnNode(Opcodes.ARETURN));
+                        final InsnList list = new DReturnTransformer(false).getReplacement(insn, this);
                         method.instructions.insert(insn, list);
                         method.instructions.remove(insn);
                     }
@@ -442,44 +444,6 @@ public class MethodDifferentiator {
 
     }
 
-    /** Create an instruction set converting a double into a constant {@link DerivativeStructure}.
-     * @param dsIndex index of the {@link DerivativeStructure} input variable
-     * @return instructions instructions converting the double into a {@link DerivativeStructure}
-     */
-    private InsnList convertDoubleToDerivativeStructure(final int dsIndex) {
-
-        final InsnList list = new InsnList();
-
-        // operand stack initial state: d
-        list.add(new TypeInsnNode(Opcodes.NEW,
-                                  Type.getInternalName(DerivativeStructure.class)));  // => d y_ds
-        list.add(new InsnNode(Opcodes.DUP_X2));                                       // => y_ds d y_ds
-        list.add(new InsnNode(Opcodes.DUP_X2));                                       // => y_ds y_ds d y_ds
-        list.add(new InsnNode(Opcodes.POP));                                          // => y_ds y_ds d
-        list.add(new VarInsnNode(Opcodes.ALOAD, dsIndex));                            // => y_ds y_ds d x_ds
-        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
-                                    Type.getInternalName(DerivativeStructure.class),
-                                    "getFreeParameters",
-                                    Type.getMethodDescriptor(Type.INT_TYPE)));        // => y_ds y_ds d params
-        list.add(new VarInsnNode(Opcodes.ALOAD, 1));                                  // => y_ds y_ds d params x_ds
-        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
-                                    Type.getInternalName(DerivativeStructure.class),
-                                    "getOrder",
-                                    Type.getMethodDescriptor(Type.INT_TYPE)));        // => y_ds y_ds d params order
-        list.add(new InsnNode(Opcodes.DUP2_X2));                                      // => y_ds y_ds params order d params order
-        list.add(new InsnNode(Opcodes.POP2));                                         // => y_ds y_ds params order d
-        list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
-                                    Type.getInternalName(DerivativeStructure.class),
-                                    "<init>",
-                                    Type.getMethodDescriptor(Type.VOID_TYPE,
-                                                             Type.INT_TYPE,
-                                                             Type.INT_TYPE,
-                                                             Type.DOUBLE_TYPE)));     // => y_ds
-
-        return list;
-
-    }
-
     /** Get the replacement list for an instruction.
      * @param insn instruction to replace
      * @return replacement instructions list
@@ -510,56 +474,22 @@ public class MethodDifferentiator {
             throw new RuntimeException("DASTORE not handled yet");
         case Opcodes.DUP2 :
             return new Dup2Transformer().getReplacement(insn, this);
+        case Opcodes.POP2 :
+            return new Pop2Transformer().getReplacement(insn, this);
         case Opcodes.DUP2_X1 :
             return new Dup2X1Transformer().getReplacement(insn, this);
         case Opcodes.DUP2_X2 :
-            if (stack1Converted) {
-                if (stack0Converted) {
-                    return new Dup2X2Transformer12().getReplacement(insn, this);
-                }
-                return new Dup2X2Transformer1().getReplacement(insn, this);
-            }
-            return new Dup2X2Transformer2().getReplacement(insn, this);
+            return new Dup2X2Transformer(stack0Converted, stack1Converted).getReplacement(insn, this);
         case Opcodes.DADD :
-            if (stack1Converted) {
-                if (stack0Converted) {
-                    return new DAddTransformer12().getReplacement(insn, this);
-                }
-                return new DAddTransformer1().getReplacement(insn, this);
-            }
-            return new DAddTransformer2().getReplacement(insn, this);
+            return new DAddTransformer(stack0Converted, stack1Converted).getReplacement(insn, this);
         case Opcodes.DSUB :
-            if (stack1Converted) {
-                if (stack0Converted) {
-                    return new DSubTransformer12().getReplacement(insn, this);
-                }
-                return new DSubTransformer1().getReplacement(insn, this);
-            }
-            return new DSubTransformer2().getReplacement(insn, this);
+            return new DSubTransformer(stack0Converted, stack1Converted).getReplacement(insn, this);
         case Opcodes.DMUL :
-            if (stack1Converted) {
-                if (stack0Converted) {
-                    return new DMulTransformer12().getReplacement(insn, this);
-                }
-                return new DMulTransformer1().getReplacement(insn, this);
-            }
-            return new DMulTransformer2().getReplacement(insn, this);
+            return new DMulTransformer(stack0Converted, stack1Converted).getReplacement(insn, this);
         case Opcodes.DDIV :
-            if (stack1Converted) {
-                if (stack0Converted) {
-                    return new DDivTransformer12().getReplacement(insn, this);
-                }
-                return new DDivTransformer1().getReplacement(insn, this);
-            }
-            return new DDivTransformer2().getReplacement(insn, this);
+            return new DDivTransformer(stack0Converted, stack1Converted).getReplacement(insn, this);
         case Opcodes.DREM :
-            if (stack1Converted) {
-                if (stack0Converted) {
-                    return new DRemTransformer12().getReplacement(insn, this);
-                }
-                return new DRemTransformer1().getReplacement(insn, this);
-            }
-            return new DRemTransformer2().getReplacement(insn, this);
+            return new DRemTransformer(stack0Converted, stack1Converted).getReplacement(insn, this);
         case Opcodes.DNEG :
             return new DNegTransformer().getReplacement(insn, this);
         case Opcodes.DCONST_0 :
@@ -569,7 +499,6 @@ public class MethodDifferentiator {
         case Opcodes.L2D :
         case Opcodes.F2D :
             return new WideningTransformer().getReplacement(insn, this);
-        case Opcodes.POP2 :
         case Opcodes.D2I :
         case Opcodes.D2L :
         case Opcodes.D2F :
@@ -584,7 +513,8 @@ public class MethodDifferentiator {
             }
             return new DcmpTransformer2().getReplacement(insn, this);
         case Opcodes.DRETURN :
-            return new DReturnTransformer().getReplacement(insn, this);
+            // TODO the constructor parameter forced to true seems strange...
+            return new DReturnTransformer(true).getReplacement(insn, this);
         case Opcodes.GETSTATIC :
             // TODO add support for GETSTATIC differentiation
             throw new RuntimeException("GETSTATIC not handled yet");

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java?rev=1391537&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java Fri Sep 28 16:41:37 2012
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward.arithmetic;
+
+import org.apache.commons.nabla.DifferentiationException;
+import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
+import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/** Differentiation transformer for DADD instructions.
+ */
+public class DAddTransformer implements InstructionsTransformer {
+
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
+    /** Indicator for next to top stack element conversion. */
+    private final boolean stack1Converted;
+
+    /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
+     * @param stack1Converted if true, the next to top level stack element has already been converted
+     */
+    public DAddTransformer(final boolean stack0Converted, final boolean stack1Converted) {
+        this.stack0Converted = stack0Converted;
+        this.stack1Converted = stack1Converted;
+    }
+
+    /** {@inheritDoc} */
+    public InsnList getReplacement(final AbstractInsnNode insn,
+                                   final MethodDifferentiator methodDifferentiator)
+        throws DifferentiationException {
+
+        final InsnList list = new InsnList();
+
+        if (stack1Converted) {
+            if (stack0Converted) {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "add",
+                                            Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
+            } else {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "add",
+                                            Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+            }
+        } else {
+            list.add(new InsnNode(Opcodes.DUP_X2));
+            list.add(new InsnNode(Opcodes.POP));
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "add",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+        }
+
+        return list;
+
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DAddTransformer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java?rev=1391537&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java Fri Sep 28 16:41:37 2012
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward.arithmetic;
+
+import org.apache.commons.nabla.DifferentiationException;
+import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
+import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/** Differentiation transformer for DDIV instructions.
+ */
+public class DDivTransformer implements InstructionsTransformer {
+
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
+    /** Indicator for next to top stack element conversion. */
+    private final boolean stack1Converted;
+
+    /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
+     * @param stack1Converted if true, the next to top level stack element has already been converted
+     */
+    public DDivTransformer(final boolean stack0Converted, final boolean stack1Converted) {
+        this.stack0Converted = stack0Converted;
+        this.stack1Converted = stack1Converted;
+    }
+
+    /** {@inheritDoc} */
+    public InsnList getReplacement(final AbstractInsnNode insn,
+                                   final MethodDifferentiator methodDifferentiator)
+        throws DifferentiationException {
+
+        final InsnList list = new InsnList();
+
+        if (stack1Converted) {
+            if (stack0Converted) {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "divide",
+                                            Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
+            } else {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "divide",
+                                            Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+            }
+        } else {
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "reciprocal",
+                                        Type.getMethodDescriptor(DS_TYPE)));
+            list.add(new InsnNode(Opcodes.DUP_X2));
+            list.add(new InsnNode(Opcodes.POP));
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "multiply",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+        }
+
+        return list;
+
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DDivTransformer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java?rev=1391537&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java Fri Sep 28 16:41:37 2012
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward.arithmetic;
+
+import org.apache.commons.nabla.DifferentiationException;
+import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
+import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/** Differentiation transformer for DMUL instructions.
+ */
+public class DMulTransformer implements InstructionsTransformer {
+
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
+    /** Indicator for next to top stack element conversion. */
+    private final boolean stack1Converted;
+
+    /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
+     * @param stack1Converted if true, the next to top level stack element has already been converted
+     */
+    public DMulTransformer(final boolean stack0Converted, final boolean stack1Converted) {
+        this.stack0Converted = stack0Converted;
+        this.stack1Converted = stack1Converted;
+    }
+
+    /** {@inheritDoc} */
+    public InsnList getReplacement(final AbstractInsnNode insn,
+                                   final MethodDifferentiator methodDifferentiator)
+        throws DifferentiationException {
+
+        final InsnList list = new InsnList();
+
+        if (stack1Converted) {
+            if (stack0Converted) {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "multiply",
+                                            Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
+            } else {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "multiply",
+                                            Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+            }
+        } else {
+            list.add(new InsnNode(Opcodes.DUP_X2));
+            list.add(new InsnNode(Opcodes.POP));
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "multiply",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+        }
+
+        return list;
+
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DMulTransformer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DNegTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DNegTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DNegTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DNegTransformer.java Fri Sep 28 16:41:37 2012
@@ -20,10 +20,10 @@ import org.apache.commons.nabla.Differen
 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
 import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
 
 /** Differentiation transformer for DNEG instructions.
  */
@@ -39,14 +39,10 @@ public class DNegTransformer implements 
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
 
-        final int tmp = methodDifferentiator.getTmp(1);
         final InsnList list = new InsnList();
-
-        list.add(new VarInsnNode(Opcodes.DSTORE, tmp));
-        list.add(new InsnNode(Opcodes.DNEG));
-        list.add(new VarInsnNode(Opcodes.DLOAD, tmp));
-        list.add(new InsnNode(Opcodes.DNEG));
-
+        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                    "negate",
+                                    Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
         return list;
 
     }

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java?rev=1391537&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java Fri Sep 28 16:41:37 2012
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward.arithmetic;
+
+import org.apache.commons.nabla.DifferentiationException;
+import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
+import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.VarInsnNode;
+
+/** Differentiation transformer for DREM instructions.
+ */
+public class DRemTransformer implements InstructionsTransformer {
+
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
+    /** Indicator for next to top stack element conversion. */
+    private final boolean stack1Converted;
+
+    /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
+     * @param stack1Converted if true, the next to top level stack element has already been converted
+     */
+    public DRemTransformer(final boolean stack0Converted, final boolean stack1Converted) {
+        this.stack0Converted = stack0Converted;
+        this.stack1Converted = stack1Converted;
+    }
+
+    /** {@inheritDoc} */
+    public InsnList getReplacement(final AbstractInsnNode insn,
+                                   final MethodDifferentiator methodDifferentiator)
+        throws DifferentiationException {
+
+        final InsnList list = new InsnList();
+
+        if (stack1Converted) {
+            if (stack0Converted) {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "remainder",
+                                            Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
+            } else {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "remainder",
+                                            Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+            }
+        } else {
+
+            // set up a temporary variable
+            final int tmp1 = methodDifferentiator.getTmp(1);
+
+            // operand stack initial state: a, ds_b
+            list.add(new InsnNode(Opcodes.DUP_X2));                                            // => ds_b, a, ds_b
+            list.add(new InsnNode(Opcodes.POP));                                               // => ds_b, a
+            list.add(new VarInsnNode(Opcodes.DSTORE, tmp1));                                   // => ds_b
+            list.add(new InsnNode(Opcodes.DUP));                                               // => ds_b, ds_b
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "getValue",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE))); // => ds_b, b0
+            list.add(new VarInsnNode(Opcodes.DLOAD,  tmp1));                                   // => ds_b, b0, a
+            list.add(new InsnNode(Opcodes.DUP2_X2));                                           // => ds_b, a, b0, a
+            list.add(new InsnNode(Opcodes.POP2));                                              // => ds_b, a, b0
+            list.add(new InsnNode(Opcodes.DREM));                                              // => ds_b, q=a%b0
+            list.add(new InsnNode(Opcodes.DNEG));                                              // => ds_b, -q
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "multiply",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE))); // => -q*b
+            list.add(new VarInsnNode(Opcodes.DLOAD,  tmp1));                                   // => -q*b, a
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "add",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE))); // => a-q*b
+
+        }
+
+        return list;
+
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DRemTransformer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java?rev=1391537&view=auto
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java (added)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java Fri Sep 28 16:41:37 2012
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.nabla.forward.arithmetic;
+
+import org.apache.commons.nabla.DifferentiationException;
+import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
+import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+
+/** Differentiation transformer for DSUB instructions.
+ */
+public class DSubTransformer implements InstructionsTransformer {
+
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
+    /** Indicator for next to top stack element conversion. */
+    private final boolean stack1Converted;
+
+    /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
+     * @param stack1Converted if true, the next to top level stack element has already been converted
+     */
+    public DSubTransformer(final boolean stack0Converted, final boolean stack1Converted) {
+        this.stack0Converted = stack0Converted;
+        this.stack1Converted = stack1Converted;
+    }
+
+    /** {@inheritDoc} */
+    public InsnList getReplacement(final AbstractInsnNode insn,
+                                   final MethodDifferentiator methodDifferentiator)
+        throws DifferentiationException {
+
+        final InsnList list = new InsnList();
+
+        if (stack1Converted) {
+            if (stack0Converted) {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "subtract",
+                                            Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
+            } else {
+                list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                            "subtract",
+                                            Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+            }
+        } else {
+            list.add(new InsnNode(Opcodes.DUP_X2));
+            list.add(new InsnNode(Opcodes.POP));
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "subtract",
+                                        Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                        "negate",
+                                        Type.getMethodDescriptor(DS_TYPE)));
+        }
+
+        return list;
+
+    }
+
+}

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/arithmetic/DSubTransformer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DLoadTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DLoadTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DLoadTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DLoadTransformer.java Fri Sep 28 16:41:37 2012
@@ -26,8 +26,9 @@ import org.objectweb.asm.tree.VarInsnNod
 
 /** Differentiation transformer for DLOAD instructions.
  * <p>Each DLOAD instruction for double variable <i>k</i>
- * is replaced by two DLOAD instructions for double variables
- * <i>k</i> and <i>k+2</i> representing an expanded derivative structure.
+ * is replaced by one DLOAD instruction for {@link
+ * org.apache.commons.math3.analysis.differentiation.DerivativeStructure}
+ * variable <i>k</i>.
  */
 public class DLoadTransformer implements InstructionsTransformer {
 
@@ -42,8 +43,7 @@ public class DLoadTransformer implements
         throws DifferentiationException {
         final int var = ((VarInsnNode) insn).var;
         final InsnList list = new InsnList();
-        list.add(new VarInsnNode(Opcodes.DLOAD, var));
-        list.add(new VarInsnNode(Opcodes.DLOAD, var + 2));
+        list.add(new VarInsnNode(Opcodes.ALOAD, var));
         return list;
     }
 

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DReturnTransformer.java Fri Sep 28 16:41:37 2012
@@ -30,16 +30,21 @@ import org.objectweb.asm.tree.TypeInsnNo
 import org.objectweb.asm.tree.VarInsnNode;
 
 /** Differentiation transformer for DRETURN instructions.
- * <p>DRETURN instructions are replaced by instructions
- * that build a {@link DerivativeStructure} instance from the expanded derivative structure
- * on operand stack head and an ARETURN instruction returning this
- * instance.</p>
+ * <p>DRETURN instructions are replaced by ARETURN instructions
+ * as a reference to a {@link
+ * org.apache.commons.math3.analysis.differentiation.DerivativeStructure}
+ * instance uses only one stack slot instead of two.</p>
  */
 public class DReturnTransformer implements InstructionsTransformer {
 
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
     /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
      */
-    public DReturnTransformer() {
+    public DReturnTransformer(final boolean stack0Converted) {
+        this.stack0Converted = stack0Converted;
     }
 
     /** {@inheritDoc} */
@@ -47,24 +52,41 @@ public class DReturnTransformer implemen
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
 
-        final Type dsType = Type.getType(DerivativeStructure.class);
+        final InsnList list = new InsnList();
+        if (!stack0Converted) {
+            // add conversion for top level stack element
 
-        // reuse local variables slots 1, 2, 3 and 4 for temporary storage
-        // (this may reduce the number of needed local variables)
-        methodDifferentiator.useLocal(1, 4);
+            // operand stack initial state: d
+            list.add(new TypeInsnNode(Opcodes.NEW,
+                                      Type.getInternalName(DerivativeStructure.class)));      // => d y_ds
+            list.add(new InsnNode(Opcodes.DUP_X2));                                           // => y_ds d y_ds
+            list.add(new InsnNode(Opcodes.DUP_X2));                                           // => y_ds y_ds d y_ds
+            list.add(new InsnNode(Opcodes.POP));                                              // => y_ds y_ds d
+            list.add(new VarInsnNode(Opcodes.ALOAD, methodDifferentiator.getInputDSIndex())); // => y_ds y_ds d x_ds
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                        Type.getInternalName(DerivativeStructure.class),
+                                        "getFreeParameters",
+                                        Type.getMethodDescriptor(Type.INT_TYPE)));            // => y_ds y_ds d params
+            list.add(new VarInsnNode(Opcodes.ALOAD, 1));                                      // => y_ds y_ds d params x_ds
+            list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                        Type.getInternalName(DerivativeStructure.class),
+                                        "getOrder",
+                                        Type.getMethodDescriptor(Type.INT_TYPE)));            // => y_ds y_ds d params order
+            list.add(new InsnNode(Opcodes.DUP2_X2));                                          // => y_ds y_ds params order d params order
+            list.add(new InsnNode(Opcodes.POP2));                                             // => y_ds y_ds params order d
+            list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
+                                        Type.getInternalName(DerivativeStructure.class),
+                                        "<init>",
+                                        Type.getMethodDescriptor(Type.VOID_TYPE,
+                                                                 Type.INT_TYPE,
+                                                                 Type.INT_TYPE,
+                                                                 Type.DOUBLE_TYPE)));         // => y_ds
+
+        }
+
+        // add the return instruction for a reference type
+        list.add(new InsnNode(Opcodes.ARETURN));
 
-        final InsnList list = new InsnList();
-        // operand stack initial state: a0, a1
-        list.add(new VarInsnNode(Opcodes.DSTORE, 3));                      // => a0
-        list.add(new VarInsnNode(Opcodes.DSTORE, 1));                      // =>
-        list.add(new TypeInsnNode(Opcodes.NEW, dsType.getInternalName())); // => o,
-        list.add(new InsnNode(Opcodes.DUP));                               // => o, o
-        list.add(new VarInsnNode(Opcodes.DLOAD, 1));                       // => o, o, a0
-        list.add(new VarInsnNode(Opcodes.DLOAD, 3));                       // => o, o, a0, a1
-        list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
-                                    dsType.getInternalName(),
-                                    "<init>", "(DD)V"));              // => dp
-        list.add(new InsnNode(Opcodes.ARETURN));                      // =>
         return list;
 
     }

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DStoreTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DStoreTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DStoreTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/DStoreTransformer.java Fri Sep 28 16:41:37 2012
@@ -26,8 +26,9 @@ import org.objectweb.asm.tree.VarInsnNod
 
 /** Differentiation transformer for DSTORE instructions.
  * <p>Each DSTORE instruction for double variable <i>k</i>
- * is replaced by two DSTORE instructions for double variables
- * <i>k+2</i> and <i>k</i> representing an expanded derivative structure.
+ * is replaced by one DSTORE instruction for {@link
+ * org.apache.commons.math3.analysis.differentiation.DerivativeStructure}
+ * variable <i>k</i>.
  */
 public class DStoreTransformer implements InstructionsTransformer {
 
@@ -42,8 +43,7 @@ public class DStoreTransformer implement
         throws DifferentiationException {
         final int var = ((VarInsnNode) insn).var;
         final InsnList list = new InsnList();
-        list.add(new VarInsnNode(Opcodes.DSTORE, var + 2));
-        list.add(new VarInsnNode(Opcodes.DSTORE, var));
+        list.add(new VarInsnNode(Opcodes.ASTORE, var));
         return list;
     }
 

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2Transformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2Transformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2Transformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2Transformer.java Fri Sep 28 16:41:37 2012
@@ -23,11 +23,12 @@ import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
 
 /** Differentiation transformer for DUP2 instructions.
- * <p>DUP2 instructions are replaced by instructions
- * that duplicate the two parts of a derivative structure on stack.</p>
+ * <p>DUP2 instructions are replaced by DUP instructions
+ * as a reference to a {@link
+ * org.apache.commons.math3.analysis.differentiation.DerivativeStructure}
+ * instance uses only one stack slot instead of two.</p>
  */
 public class Dup2Transformer implements InstructionsTransformer {
 
@@ -41,14 +42,8 @@ public class Dup2Transformer implements 
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
 
-        final int tmp1 = methodDifferentiator.getTmp(1);
-
         final InsnList list = new InsnList();
-        // operand stack initial state: a0, a1
-        list.add(new VarInsnNode(Opcodes.DSTORE, tmp1)); // => a0
-        list.add(new InsnNode(Opcodes.DUP2));            // => a0, a0
-        list.add(new VarInsnNode(Opcodes.DLOAD, tmp1));  // => a0, a0, a1
-        list.add(new InsnNode(Opcodes.DUP2_X2));         // => a0, a1, a0, a1
+        list.add(new InsnNode(Opcodes.DUP));
         return list;
 
     }

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X1Transformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X1Transformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X1Transformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X1Transformer.java Fri Sep 28 16:41:37 2012
@@ -23,11 +23,12 @@ import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
 
 /** Differentiation transformer for DUP2_X1 instructions.
- * <p>DUP2_X1 instructions are replaced by instructions
- * that duplicate the two parts of a derivative structure on stack.</p>
+ * <p>DUP2_X1 instructions are replaced by DUP_X1 instructions
+ * as a reference to a {@link
+ * org.apache.commons.math3.analysis.differentiation.DerivativeStructure}
+ * instance uses only one stack slot instead of two.</p>
  */
 public class Dup2X1Transformer implements InstructionsTransformer {
 
@@ -41,21 +42,8 @@ public class Dup2X1Transformer implement
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
 
-        final int tmp1 = methodDifferentiator.getTmp(1);
-        final int tmp2 = methodDifferentiator.getTmp(2);
-
         final InsnList list = new InsnList();
-        // operand stack initial state: v, a0, a1
-        list.add(new VarInsnNode(Opcodes.DSTORE, tmp1)); // => v, a0
-        list.add(new InsnNode(Opcodes.DUP2));            // => v, a0, a0
-        list.add(new VarInsnNode(Opcodes.DSTORE, tmp2)); // => v, a0
-        list.add(new InsnNode(Opcodes.DUP2_X1));         // => a0, v, a0
-        list.add(new InsnNode(Opcodes.POP2));            // => a0, v
-        list.add(new VarInsnNode(Opcodes.DLOAD,  tmp1)); // => a0, v, a1
-        list.add(new InsnNode(Opcodes.DUP2_X1));         // => a0, a1, v, a1
-        list.add(new InsnNode(Opcodes.POP2));            // => a0, a1, v
-        list.add(new VarInsnNode(Opcodes.DLOAD,  tmp2)); // => a0, a1, v, a0
-        list.add(new VarInsnNode(Opcodes.DLOAD,  tmp1)); // => a0, a1, v, a0, a1
+        list.add(new InsnNode(Opcodes.DUP_X1));
         return list;
 
     }

Copied: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java (from r1391536, commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer1.java)
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java?p2=commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java&p1=commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer1.java&r1=1391536&r2=1391537&rev=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer1.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java Fri Sep 28 16:41:37 2012
@@ -23,17 +23,24 @@ import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
 
 /** Differentiation transformer for DUP2_X2 instructions.
- * <p>DUP2_X2 instructions are replaced by instructions
- * that duplicate the two parts of a derivative structure on stack.</p>
  */
-public class Dup2X2Transformer1 implements InstructionsTransformer {
+public class Dup2X2Transformer implements InstructionsTransformer {
+
+    /** Indicator for top stack element conversion. */
+    private final boolean stack0Converted;
+
+    /** Indicator for next to top stack element conversion. */
+    private final boolean stack1Converted;
 
     /** Simple constructor.
+     * @param stack0Converted if true, the top level stack element has already been converted
+     * @param stack1Converted if true, the next to top level stack element has already been converted
      */
-    public Dup2X2Transformer1() {
+    public Dup2X2Transformer(final boolean stack0Converted, final boolean stack1Converted) {
+        this.stack0Converted = stack0Converted;
+        this.stack1Converted = stack1Converted;
     }
 
     /** {@inheritDoc} */
@@ -41,17 +48,18 @@ public class Dup2X2Transformer1 implemen
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
 
-        final int tmp1 = methodDifferentiator.getTmp(1);
-
         final InsnList list = new InsnList();
-        // operand stack initial state: a0, a1, w
-        list.add(new InsnNode(Opcodes.DUP2_X2));         // => a0, w, a1, w
-        list.add(new InsnNode(Opcodes.POP2));            // => a0, w, a1
-        list.add(new VarInsnNode(Opcodes.DSTORE, tmp1)); // => a0, w
-        list.add(new InsnNode(Opcodes.DUP2_X2));         // => w, a0, w
-        list.add(new VarInsnNode(Opcodes.DLOAD,  tmp1)); // => w, a0, w, a1
-        list.add(new InsnNode(Opcodes.DUP2_X2));         // => w, a0, a1, w, a1
-        list.add(new InsnNode(Opcodes.POP2));            // => w, a0, a1, w
+
+        if (stack1Converted) {
+            if (stack0Converted) {
+                list.add(new InsnNode(Opcodes.DUP_X1));
+            } else {
+                list.add(new InsnNode(Opcodes.DUP2_X1));
+            }
+        } else {
+            list.add(new InsnNode(Opcodes.DUP_X2));
+        }
+
         return list;
 
     }

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Dup2X2Transformer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java Fri Sep 28 16:41:37 2012
@@ -20,15 +20,14 @@ import org.apache.commons.nabla.Differen
 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
 import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
 
-/** Differentiation transformer for narrowing a differential part on the stack
+/** Differentiation transformer for narrowing a derivative structure on the stack
  * to a double.
- * <p>Some instructions (D2I, D2L, D2F, POP2) may handle derivative structure
- * on the stack by simply popping the differential part out before being
- * applied.</p>
  */
 public class NarrowingTransformer implements InstructionsTransformer {
 
@@ -41,10 +40,18 @@ public class NarrowingTransformer implem
     public InsnList getReplacement(final AbstractInsnNode insn,
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
+
         final InsnList list = new InsnList();
-        list.add(new InsnNode(Opcodes.POP2));
-        list.add(methodDifferentiator.clone(insn));
+
+        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, DS_TYPE.getInternalName(),
+                                    "getValue",
+                                    Type.getMethodDescriptor(Type.DOUBLE_TYPE)));
+
+        // copy the instruction consuming the double (D2I, D2L or D2F)
+        list.add(new InsnNode(insn.getOpcode()));
+
         return list;
+
     }
 
 }

Copied: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Pop2Transformer.java (from r1391536, commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java)
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Pop2Transformer.java?p2=commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Pop2Transformer.java&p1=commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java&r1=1391536&r2=1391537&rev=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/NarrowingTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/Pop2Transformer.java Fri Sep 28 16:41:37 2012
@@ -24,27 +24,28 @@ import org.objectweb.asm.tree.AbstractIn
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
 
-/** Differentiation transformer for narrowing a differential part on the stack
- * to a double.
- * <p>Some instructions (D2I, D2L, D2F, POP2) may handle derivative structure
- * on the stack by simply popping the differential part out before being
- * applied.</p>
+/** Differentiation transformer for POP2 instructions.
+ * <p>POP2 instructions are replaced by a POP instruction
+ * as a reference to a {@link
+ * org.apache.commons.math3.analysis.differentiation.DerivativeStructure}
+ * instance uses only one stack slot instead of two.</p>
  */
-public class NarrowingTransformer implements InstructionsTransformer {
+public class Pop2Transformer implements InstructionsTransformer {
 
     /** Simple constructor.
      */
-    public NarrowingTransformer() {
+    public Pop2Transformer() {
     }
 
     /** {@inheritDoc} */
     public InsnList getReplacement(final AbstractInsnNode insn,
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
+
         final InsnList list = new InsnList();
-        list.add(new InsnNode(Opcodes.POP2));
-        list.add(methodDifferentiator.clone(insn));
+        list.add(new InsnNode(Opcodes.POP));
         return list;
+
     }
 
 }

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/WideningTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/WideningTransformer.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/WideningTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/WideningTransformer.java Fri Sep 28 16:41:37 2012
@@ -16,20 +16,22 @@
  */
 package org.apache.commons.nabla.forward.instructions;
 
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.nabla.DifferentiationException;
 import org.apache.commons.nabla.forward.analysis.InstructionsTransformer;
 import org.apache.commons.nabla.forward.analysis.MethodDifferentiator;
 import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
 import org.objectweb.asm.tree.AbstractInsnNode;
 import org.objectweb.asm.tree.InsnList;
 import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+import org.objectweb.asm.tree.VarInsnNode;
 
 /** Differentiation transformer for promoting a double on the stack
  * to a derivative structure.
- * <p>Some instructions pushing a double on the stack simply need to
- * be completed by pushing a 0 afterwards to form a derivative structure
- * representing a constant value. These instructions are replaced by
- * a copy of themselves followed by a DCONST_0 instruction.</p>
  */
 public class WideningTransformer implements InstructionsTransformer {
 
@@ -42,10 +44,44 @@ public class WideningTransformer impleme
     public InsnList getReplacement(final AbstractInsnNode insn,
                                    final MethodDifferentiator methodDifferentiator)
         throws DifferentiationException {
+
         final InsnList list = new InsnList();
-        list.add(methodDifferentiator.clone(insn));
-        list.add(new InsnNode(Opcodes.DCONST_0));
+
+        // copy the instruction creating the double (DCONST_0, DCONST_1, LDC, I2D, L2D or F2D)
+        if (insn.getOpcode() == Opcodes.LDC) {
+            list.add(new LdcInsnNode(((LdcInsnNode) insn).cst));
+        } else {
+            list.add(new InsnNode(insn.getOpcode()));
+        }
+
+        // operand stack initial state: d
+        list.add(new TypeInsnNode(Opcodes.NEW,
+                                  Type.getInternalName(DerivativeStructure.class)));      // => d y_ds
+        list.add(new InsnNode(Opcodes.DUP_X2));                                           // => y_ds d y_ds
+        list.add(new InsnNode(Opcodes.DUP_X2));                                           // => y_ds y_ds d y_ds
+        list.add(new InsnNode(Opcodes.POP));                                              // => y_ds y_ds d
+        list.add(new VarInsnNode(Opcodes.ALOAD, methodDifferentiator.getInputDSIndex())); // => y_ds y_ds d x_ds
+        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                    Type.getInternalName(DerivativeStructure.class),
+                                    "getFreeParameters",
+                                    Type.getMethodDescriptor(Type.INT_TYPE)));            // => y_ds y_ds d params
+        list.add(new VarInsnNode(Opcodes.ALOAD, 1));                                      // => y_ds y_ds d params x_ds
+        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                    Type.getInternalName(DerivativeStructure.class),
+                                    "getOrder",
+                                    Type.getMethodDescriptor(Type.INT_TYPE)));            // => y_ds y_ds d params order
+        list.add(new InsnNode(Opcodes.DUP2_X2));                                          // => y_ds y_ds params order d params order
+        list.add(new InsnNode(Opcodes.POP2));                                             // => y_ds y_ds params order d
+        list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
+                                    Type.getInternalName(DerivativeStructure.class),
+                                    "<init>",
+                                    Type.getMethodDescriptor(Type.VOID_TYPE,
+                                                             Type.INT_TYPE,
+                                                             Type.INT_TYPE,
+                                                             Type.DOUBLE_TYPE)));         // => y_ds
+
         return list;
+
     }
 
 }

Modified: commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java?rev=1391537&r1=1391536&r2=1391537&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java (original)
+++ commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/ForwardModeDifferentiatorTest.java Fri Sep 28 16:41:37 2012
@@ -44,7 +44,7 @@ public class ForwardModeDifferentiatorTe
     @Test
     public void testParameterIndependent() {
         checkReference(new ReferenceFunction() {
-            public double value(double t) { return 1; }
+            public double value(double t) { return 12; }
             public double firstDerivative(double t) { return 0; }
         }, 0.1, 5, 20, 2.0e-12);
     }