On 10/9/11 7:46 AM, Phil Steitz wrote:
> On 10/9/11 5:39 AM, Luc Maisonobe wrote:
>> Hi Phil,
>>
>> Le 08/10/2011 23:42, Phil Steitz a écrit :
>>> On 10/8/11 2:24 PM, Luc Maisonobe wrote:
>>>>
>>>> Phil Steitz<[email protected]> a écrit :
>>>>
>>>>> I am getting RTE with message above when I try to run the example
>>>>> under "updating the base and differentiated objects" in the docs.
>> Digging into the code, here are the bytecode operations that are
>> not supported yet:
>>
>> DALOAD, DASTORE:
>> element access in double arrays
>> GETSTATIC, PUTSTATIC, GETFIELD, PUTFIELD:
>> field access (instance fields and class fields)
>> INVOKEVIRTUAL/INVOKESPECIAL/INVOKESTATIC/INVOKEINTERFACE:
>> method calls
>> NEWARRAY/ANEWARRAY/MULTIANEWARRAY:
>> array creation
>>
>>>>> Is this example supposed to work with the code in trunk? Also,
>>>>> I am
>>>> I'll look at this tomorrow, but I think for now you need to have
>>>> a standalone function, it cannot be split
>>>> as a main function calling subfunctions. The only allowed calls
>>>> are the static methods from Math/StrictMath.
>>>> I did not add our own FastMath, but it is trivial to do.
>>>>
>>>> Another limitation is that your function cannot store
>>>> intermediate results as clas attributes yet.
>>> Thanks, Luc! What I was trying to illustrate was partial
>>> derivatives, which IIUC you need something like that example to do.
>>> The following almost works:
>>>
>>> public void testPartialDerivatives() throws Exception {
>>> PartialFunction function = new PartialFunction(1);
>>> final UnivariateDerivative derivative = new
>>> ForwardModeAlgorithmicDifferentiator().differentiate(function);
>>> DifferentialPair t = DifferentialPair.newVariable(1);
>>> Assert.assertEquals(3,
>>> derivative.f(t).getFirstDerivative(), 0);
>>> Assert.assertEquals(2, derivative.f(t).getValue(), 0);
>>> function.setX(2);
>>> Assert.assertEquals(4,
>>> derivative.f(t).getFirstDerivative(), 0);
>>> Assert.assertEquals(3, derivative.f(t).getValue(), 0);
>>> }
>>>
>>> with
>>>
>>> public class PartialFunction implements UnivariateDifferentiable {
>>> private double x;
>>> public PartialFunction(double x) {
>>> this.x = x;
>>> }
>>> public void setX(double x) {
>>> this.x = x;
>>> }
>>> public double getX() {
>>> return x;
>>> }
>>> public double f(double y) {
>>> return x * y + y * y;
>>> }
>>> }
>>>
>>> But I end up with java.lang.VerifyError: (class:
>>> ExampleTest$1PartialFunction$NablaForwardModeUnivariateDerivative,
>>> method: f signature:
>>> (Lorg/apache/commons/nabla/core/DifferentialPair;)Lorg/apache/commons/nabla/core/DifferentialPair;)
>>>
>>> Incompatible type for getting or setting field
>>> at java.lang.Class.getDeclaredConstructors0(Native Method)
>>> at
>>> java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
>>> at java.lang.Class.getDeclaredConstructors(Class.java:1836)
>>> at
>>> org.apache.commons.nabla.algorithmic.forward.ForwardModeAlgorithmicDifferentiator.differentiate(ForwardModeAlgorithmicDifferentiator.java:107)
>>>
>>> at ExampleTest.testPartialDerivatives(ExampleTest.java:66)
>> This error seems to be due to the lack of support for the GETFIELD
>> instruction. As x is an instance field, the f method reads this
>> field before multiplying the result.
Right. As an exercise to help me understand the internals of the
code, I have been trying to figure out how to add this support.
Working backwards from the generated bytecode, the GETFIELD and the
ALOAD 0 before it seem to get copied unchanged:
ALOAD 0
GETFIELD PartialFunction.x : D
Working backwards to where it should get changed,
MethodDifferentiator#getReplacement throws RuntimeException when it
sees a GETFIELD; but in my example it does not throw. This means
the instruction is not making it into the changes set. The question
then is a) how to modify MethodDifferentiator#identifyChanges to
identify the need to change the instruction and b) how to transform
it (and other instructions that depend on it). A reference to the
enclosing class also has to be made available. Is that already
there somewhere?
Phil
>>
>> I have added a debug display message (to be removed later on) that
>> should print the generated bytecode to standard error when a
>> VerifyError exception occurs. It' clearly not targeted towards end
>> users, but it could help during development.
> Thanks, Luc!
>
> Phil
>> Luc
>>
>>>>
>>>> You can look at the junit tests for what is supported. Simple
>>>> expressions, calls to traditional functions like sin, cos, exp ...,
>>>> Simple loops and conditionals, local automatic variables should
>>>> all work (I hope ...)
>>> Yep, I have gotten all of this to work. Even "knows" the chain
>>> rule :)
>>>
>>>
>>> Phil
>>>>> assuming
>>>>> s/ForwardAlgorithmicDifferentiator/ForwardModeAlgorithmicDifferentiator
>>>>>
>>>>> throughout. Correct?
>>>> Yes, the name was changed because a distant goal will be to also
>>>> support reverse mode, which is especially
>>>> useful when computing gradients (i.e. when one scalar function
>>>> depends on many inputs and we want all partial
>>>> derivatives).
>>>>
>>>> Luc
>>>>
>>>>> Phil
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>>
>>>>> To unsubscribe, e-mail: [email protected]
>>>>> For additional commands, e-mail: [email protected]
>>>> ---------------------------------------------------------------------
>>>>
>>>> To unsubscribe, e-mail: [email protected]
>>>> For additional commands, e-mail: [email protected]
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>>
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [email protected]
>> For additional commands, e-mail: [email protected]
>>
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]