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:44:48 UTC

svn commit: r1391543 - in /commons/sandbox/nabla/trunk/src: main/java/org/apache/commons/nabla/forward/instructions/InvokeStaticTransformer.java test/java/org/apache/commons/nabla/forward/PowGeneratorTest.java

Author: luc
Date: Fri Sep 28 16:44:47 2012
New Revision: 1391543

URL: http://svn.apache.org/viewvc?rev=1391543&view=rev
Log:
Fixed transformation for power function.

Pow is the only two-arguments function that is not static in
DerivativeStructure. It also supports a double argument natively. So it
has to be handled specially by the bytecode conversion code.

Modified:
    commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeStaticTransformer.java
    commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/PowGeneratorTest.java

Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeStaticTransformer.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeStaticTransformer.java?rev=1391543&r1=1391542&r2=1391543&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeStaticTransformer.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/forward/instructions/InvokeStaticTransformer.java Fri Sep 28 16:44:47 2012
@@ -79,24 +79,55 @@ public class InvokeStaticTransformer imp
         } else if (methodInsn.desc.equals(Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE))) {
             // this is a bivariate method like atan2, pow ...
 
-            // we may want to differentiate against first, second or both parameters
-            if (stack1Converted) {
-                if (!stack0Converted) {
-                    // the top level element is not a DerivativeStructure, convert it
-                    list.add(methodDifferentiator.doubleToDerivativeStructureConversion());
+            if (methodInsn.name.equals("pow")) {
+                // special case for pow: in DerivativeStructure, it is an instance method,
+                // not a static method as the other two parameters functions like atan2 or hypot
+
+                if (stack1Converted) {
+                    if (!stack0Converted) {
+                        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                    DS_TYPE.getInternalName(), methodInsn.name,
+                                                    Type.getMethodDescriptor(DS_TYPE, Type.DOUBLE_TYPE)));
+                    } else {
+                        list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                    DS_TYPE.getInternalName(), methodInsn.name,
+                                                    Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
+                   }
+                } else {
+
+                    // initial stack state: x, ds_y
+                    list.add(new InsnNode(Opcodes.DUP_X2));                                 // => ds_y, x, ds_y
+                    list.add(new InsnNode(Opcodes.POP));                                    // => ds_y, x
+                    list.add(methodDifferentiator.doubleToDerivativeStructureConversion()); // => ds_y, ds_x
+                    list.add(new InsnNode(Opcodes.SWAP));                                   // => ds_x, ds_y
+
+                    // call the static two parameters method for DerivativeStructure
+                    list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
+                                                DS_TYPE.getInternalName(), methodInsn.name,
+                                                Type.getMethodDescriptor(DS_TYPE, DS_TYPE)));
                 }
-            } else if (stack0Converted) {
-                // initial stack state: x, ds_y
-                list.add(new InsnNode(Opcodes.DUP_X2));                                 // => ds_y, x, ds_y
-                list.add(new InsnNode(Opcodes.POP));                                    // => ds_y, x
-                list.add(methodDifferentiator.doubleToDerivativeStructureConversion()); // => ds_y, ds_x
-                list.add(new InsnNode(Opcodes.SWAP));                                   // => ds_x, ds_y
-            }
 
-            // call the static two parameters method for DerivativeStructure
-            list.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
-                                        DS_TYPE.getInternalName(), methodInsn.name,
-                                        Type.getMethodDescriptor(DS_TYPE, DS_TYPE, DS_TYPE)));
+            } else {
+
+                if (stack1Converted) {
+                    if (!stack0Converted) {
+                        // the top level element is not a DerivativeStructure, convert it
+                        list.add(methodDifferentiator.doubleToDerivativeStructureConversion());
+                    }
+                } else {
+                    // initial stack state: x, ds_y
+                    list.add(new InsnNode(Opcodes.DUP_X2));                                 // => ds_y, x, ds_y
+                    list.add(new InsnNode(Opcodes.POP));                                    // => ds_y, x
+                    list.add(methodDifferentiator.doubleToDerivativeStructureConversion()); // => ds_y, ds_x
+                    list.add(new InsnNode(Opcodes.SWAP));                                   // => ds_x, ds_y
+                }
+
+                // call the static two parameters method for DerivativeStructure
+                list.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
+                                            DS_TYPE.getInternalName(), methodInsn.name,
+                                            Type.getMethodDescriptor(DS_TYPE, DS_TYPE, DS_TYPE)));
+
+            }
 
         } else {
             throw new DifferentiationException(NablaMessages.UNKNOWN_METHOD,

Modified: commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/PowGeneratorTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/PowGeneratorTest.java?rev=1391543&r1=1391542&r2=1391543&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/PowGeneratorTest.java (original)
+++ commons/sandbox/nabla/trunk/src/test/java/org/apache/commons/nabla/forward/PowGeneratorTest.java Fri Sep 28 16:44:47 2012
@@ -27,7 +27,7 @@ public class PowGeneratorTest extends Ab
         checkReference(new ReferenceFunction() {
             public double value(double t) { return FastMath.pow(t, 3.0); }
             public double firstDerivative(double t) { return 3 * FastMath.pow(t, 2.0); }
-        }, -2, 2, 50, 2e-15);
+        }, -2, 2, 50, 9.0e-16);
     }
 
     @Test
@@ -35,7 +35,7 @@ public class PowGeneratorTest extends Ab
         checkReference(new ReferenceFunction() {
             public double value(double t) { return FastMath.pow(3.0, t); }
             public double firstDerivative(double t) { return FastMath.log(3) * FastMath.pow(3, t); }
-        }, -2, 2, 50, 0.0);
+        }, -2, 2, 50, 6.0e-15);
     }
 
     @Test
@@ -43,7 +43,7 @@ public class PowGeneratorTest extends Ab
         checkReference(new ReferenceFunction() {
             public double value(double t) { return FastMath.pow(t, t); }
             public double firstDerivative(double t) { return (1 + FastMath.log(t)) * FastMath.pow(t, t); }
-        }, 0.1, 10, 20, 0);
+        }, 0.1, 3.0, 20, 2.0e-14);
     }
 
 }