<p dir="ltr">Thanks a lot. This worked perfectly. <br>
I saw the auto function but as the documentation says "embed a constant" I thought (as opposed to a variable) that it will not derive against it.<br>
Thanks again for the prompt and complete answer </p>
<br><div class="gmail_quote"><div dir="ltr">On Sat, Apr 1, 2017, 03:44 Li-yao Xia <<a href="mailto:lysxia@gmail.com">lysxia@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Frederic,<br class="gmail_msg">
<br class="gmail_msg">
As you have already noticed, it is best not to change the representation<br class="gmail_msg">
of the numerals in a function you pass to grad, as this destroys the<br class="gmail_msg">
metadata built up by the ad framework to compute derivatives. Revert<br class="gmail_msg">
ExprTreeToListFun. Having derived Functor for ExprTree, convert your<br class="gmail_msg">
tree and parameters using auto before applying exprTreeToListFun. This<br class="gmail_msg">
leaves grad free to pick the right type.<br class="gmail_msg">
<br class="gmail_msg">
gradList = AD.grad (exprTreeToListFun (fmap auto tree) (fmap auto<br class="gmail_msg">
paramDict)) varVals<br class="gmail_msg">
<br class="gmail_msg">
Cheers,<br class="gmail_msg">
Li-yao<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
On 03/31/2017 08:33 AM, Frederic Cogny wrote:<br class="gmail_msg">
> Hello Café<br class="gmail_msg">
><br class="gmail_msg">
> *Issue: *<br class="gmail_msg">
> I'm having trouble using the AD package presumably due to a wrong use of<br class="gmail_msg">
> types (Sorry I know it's a bit vague)<br class="gmail_msg">
> Any help or pointer on how to solve this would be greatly appreciated.<br class="gmail_msg">
> Thanks in advance<br class="gmail_msg">
><br class="gmail_msg">
> *Background: *<br class="gmail_msg">
> I've implemented a symbolic expression tree [full code here:<br class="gmail_msg">
> <a href="https://pastebin.com/FDpSFuRM" rel="noreferrer" class="gmail_msg" target="_blank">https://pastebin.com/FDpSFuRM</a>]<br class="gmail_msg">
> -- | Expression Tree<br class="gmail_msg">
> data ExprTree a = Const a -- ^ number<br class="gmail_msg">
> | ParamNode ParamName -- ^ parameter<br class="gmail_msg">
> | VarNode VarName -- ^ variable<br class="gmail_msg">
> | UnaryNode MonoOp (ExprTree a) -- ^ operator of<br class="gmail_msg">
> arity 1<br class="gmail_msg">
> | BinaryNode DualOp (ExprTree a) (ExprTree a) -- ^ operator<br class="gmail_msg">
> of arity 2<br class="gmail_msg">
> | CondNode (Cond a) (ExprTree a) (ExprTree a) -- ^<br class="gmail_msg">
> conditional node<br class="gmail_msg">
> deriving (Eq,Show, Generic)<br class="gmail_msg">
><br class="gmail_msg">
> An evaluation function on it<br class="gmail_msg">
> -- | evaluates an Expression Tree on its Context (Map ParamName a, Map<br class="gmail_msg">
> VarName a)<br class="gmail_msg">
> evaluate :: (Eq a, Ord a, Floating a) => ExprTree a -> Context a -> a<br class="gmail_msg">
><br class="gmail_msg">
> And a few instances on it:<br class="gmail_msg">
> instance Num a => Default (ExprTree a) where ...<br class="gmail_msg">
> instance Num a => Num (ExprTree a) where ...<br class="gmail_msg">
> instance Fractional a => Fractional (ExprTree a) where ...<br class="gmail_msg">
> instance Floating a => Floating (ExprTree a) where ...<br class="gmail_msg">
> instance (Arbitrary a) => Arbitrary (ExprTree a) where ...<br class="gmail_msg">
><br class="gmail_msg">
> This allows me to easily create (using derivation rules) the derivative(s)<br class="gmail_msg">
> of such a tree with respect to its variable(s):<br class="gmail_msg">
> diff :: (Eq a, Floating a) => ExprTree a -> VarName -> ExprTree a<br class="gmail_msg">
> grad :: (Eq a, Floating a) => ExprTree a -> Map VarName (ExprTree a)<br class="gmail_msg">
> hessian :: (Eq a, Floating a) => ExprTree a -> Map VarName (Map VarName<br class="gmail_msg">
> (ExprTree a))<br class="gmail_msg">
><br class="gmail_msg">
> So far, so good ...<br class="gmail_msg">
><br class="gmail_msg">
> Now, to gain assurance in my implementation I wanted to check the<br class="gmail_msg">
> derivatives against the Numeric.AD module<br class="gmail_msg">
> so I create the two following<br class="gmail_msg">
> -- | helper for AD usage<br class="gmail_msg">
> exprTreeToListFun :: (RealFloat a)<br class="gmail_msg">
> => ExprTree a -- ^ tree<br class="gmail_msg">
> -> Map ParamName a -- ^ paramDict<br class="gmail_msg">
> -> ([a] -> a) -- fun from var values to their<br class="gmail_msg">
> evaluation<br class="gmail_msg">
> exprTreeToListFun tree paramDict vals = res<br class="gmail_msg">
> where<br class="gmail_msg">
> res = evaluate tree (paramDict, varDict)<br class="gmail_msg">
> varDict = Map.fromList $ zip (getVarNames tree) vals<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> gradThroughAD :: RealFloat a => ExprTree a -> Context a -> Map VarName a<br class="gmail_msg">
> gradThroughAD tree (paramDict, varDict) = res<br class="gmail_msg">
> where<br class="gmail_msg">
> varNames = Map.keys varDict<br class="gmail_msg">
> varVals = Map.elems varDict<br class="gmail_msg">
> gradList = AD.grad (exprTreeToListFun tree paramDict) varVals<br class="gmail_msg">
> res = Map.fromList $ zip varNames gradList<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> it unfortunately does not type check with message:<br class="gmail_msg">
> • Couldn't match type ‘a’ with ‘Numeric.AD.Internal.Reverse.Reverse s a’ ‘a’<br class="gmail_msg">
> is a rigid type variable bound by the type signature for: gradThroughAD ::<br class="gmail_msg">
> forall a. RealFloat a => ExprTree a -> Context a -> Map VarName a at src/<br class="gmail_msg">
> SymbolicExpression.hs:452:18 Expected type: [Numeric.AD.Internal.Reverse.<br class="gmail_msg">
> Reverse s a] -> Numeric.AD.Internal.Reverse.Reverse s a Actual type: [a] -><br class="gmail_msg">
> a • In the first argument of ‘AD.grad’, namely ‘(exprTreeToListFun tree<br class="gmail_msg">
> paramDict)’ In the expression: AD.grad (exprTreeToListFun tree paramDict)<br class="gmail_msg">
> varVals In an equation for ‘gradList’: gradList = AD.grad (exprTreeToListFun<br class="gmail_msg">
> tree paramDict) varVals • Relevant bindings include gradList :: [a] (bound<br class="gmail_msg">
> at src/SymbolicExpression.hs:457:5) varVals :: [a] (bound at src/<br class="gmail_msg">
> SymbolicExpression.hs:456:5) varDict :: Map VarName a (bound at<br class="gmail_msg">
> src/SymbolicExpression.hs:453:32) paramDict :: Map ParamName a (bound at<br class="gmail_msg">
> src/SymbolicExpression.hs:453:21) tree :: ExprTree a (bound at src/<br class="gmail_msg">
> SymbolicExpression.hs:453:15) gradThroughAD :: ExprTree a -> Context a -><br class="gmail_msg">
> Map VarName a (bound at src/SymbolicExpression.hs:453:1)<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> I was a bit surprised (I guess naively) by this, since to me, 'a' is<br class="gmail_msg">
> polymorphic with RealFloat as type constraint and that is "supposed" to<br class="gmail_msg">
> work with AD<br class="gmail_msg">
><br class="gmail_msg">
> So anyway, I tried to modify as follow:<br class="gmail_msg">
> {-# LANGUAGE Rank2Types #-}<br class="gmail_msg">
><br class="gmail_msg">
> -- | helper for AD usage<br class="gmail_msg">
> exprTreeToListFun :: (RealFloat a)<br class="gmail_msg">
> => ExprTree a -- ^ tree<br class="gmail_msg">
> -> Map ParamName a -- ^ paramDict<br class="gmail_msg">
> -> *(RealFloat b => *[b] -> b) -- fun from var<br class="gmail_msg">
> values to their evaluation<br class="gmail_msg">
> exprTreeToListFun tree paramDict vals = res<br class="gmail_msg">
> where<br class="gmail_msg">
> res = *realToFrac* $ evaluate tree (paramDict, varDict)<br class="gmail_msg">
> varDict = Map.fromList $ zip (getVarNames tree) *$ map<br class="gmail_msg">
> realToFrac *vals<br class="gmail_msg">
><br class="gmail_msg">
> This now typechecks and runs but going through AD returns me *all<br class="gmail_msg">
> derivatives as zero* as if treating the variables (that passed through<br class="gmail_msg">
> *realToFrac*) as constants, so not that much helpful either.<br class="gmail_msg">
><br class="gmail_msg">
> Any idea how this can be solved ?<br class="gmail_msg">
><br class="gmail_msg">
> Apologies if this is a question that already has an answer somewhere but poking<br class="gmail_msg">
> around SO <<a href="http://stackoverflow.com/search?q=%5Bhaskell%5D+ad+package" rel="noreferrer" class="gmail_msg" target="_blank">http://stackoverflow.com/search?q=%5Bhaskell%5D+ad+package</a>> It<br class="gmail_msg">
> looks like I'm not the only one having similar issues and unfortunately<br class="gmail_msg">
> none of the answers I found really helped me, if anything it confirms the<br class="gmail_msg">
> same issue of null derivatives:<br class="gmail_msg">
> <a href="http://stackoverflow.com/questions/36878083/ad-type-unification-error-with-constrained-type-vector" rel="noreferrer" class="gmail_msg" target="_blank">http://stackoverflow.com/questions/36878083/ad-type-unification-error-with-constrained-type-vector</a><br class="gmail_msg">
><br class="gmail_msg">
> Thanks again<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> _______________________________________________<br class="gmail_msg">
> Haskell-Cafe mailing list<br class="gmail_msg">
> To (un)subscribe, modify options or view archives go to:<br class="gmail_msg">
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" class="gmail_msg" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="gmail_msg">
> Only members subscribed via the mailman list are allowed to post.<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div><div dir="ltr">-- <br></div><div data-smartmail="gmail_signature"><div dir="ltr"><div><font color="#000000">Frederic Cogny<br></font></div><font color="#000000"><font>+33 </font><span>7 83 12 61 69</span></font><br></div></div>