anchor.diff:          if (float a) <= 0. then invalidArgLog()
           match a with
           | D(a) -> D(log a)
  -        | DD(ap, at, ai) -> DD(log ap, at / ap, ai)
  +        | DF(ap, at, ai) -> DF(log ap, at / ap, ai)
       static member Log10 (a:D) =
           if (float a) <= 0. then invalidArgLog10()
           match a with
           | D(a) -> D(log10 a)
  -        | DD(ap, at, ai) -> DD(log10 ap, at / (ap * log10val), ai)
  +        | DF(ap, at, ai) -> DF(log10 ap, at / (ap * log10val), ai)
       static member Exp (a:D) =
           match a with
           | D(a) -> D(exp a)
  -        | DD(ap, at, ai) -> let expa = exp ap in DD(expa, at * expa, ai)
  +        | DF(ap, at, ai) -> let expa = exp ap in DF(expa, at * expa, ai)
       static member Sin (a:D) =
           match a with
           | D(a) -> D(sin a)
  -        | DD(ap, at, ai) -> DD(sin ap, at * cos ap, ai)
  +        | DF(ap, at, ai) -> DF(sin ap, at * cos ap, ai)
       static member Cos (a:D) =
           match a with
           | D(a) -> D(cos a)
  -        | DD(ap, at, ai) -> DD(cos ap, -at * sin ap, ai)
  +        | DF(ap, at, ai) -> DF(cos ap, -at * sin ap, ai)
       static member Tan (a:D) =
           match a with
           | D(a) -> 
               if cos a = 0. then invalidArgTan()
               D(tan a)
  -        | DD(ap, at, ai) ->
  +        | DF(ap, at, ai) ->
               let cosa = cos ap
               if (float cosa) = 0. then invalidArgTan()
  -            DD(tan ap, at / (cosa * cosa), ai)
  +            DF(tan ap, at / (cosa * cosa), ai)
       static member (~-) (a:D) =
           match a with
           | D(a) -> D(-a)
  -        | DD(ap, at, ai) -> DD(-ap, -at, ai)
  +        | DF(ap, at, ai) -> DF(-ap, -at, ai)
       static member Sqrt (a:D) =
           if (float a) <= 0. then invalidArgSqrt()
           match a with
           | D(a) -> D(sqrt a)
  -        | DD(ap, at, ai) -> let sqrta = sqrt ap in DD(sqrta, at / (2. * sqrta), ai)
  +        | DF(ap, at, ai) -> let sqrta = sqrt ap in DF(sqrta, at / (2. * sqrta), ai)
       static member Sinh (a:D) =
           match a with
           | D(a) -> D(sinh a)
  -        | DD(ap, at, ai) -> DD(sinh ap, at * cosh ap, ai)
  +        | DF(ap, at, ai) -> DF(sinh ap, at * cosh ap, ai)
       static member Cosh (a:D) =
           match a with
           | D(a) -> D(cosh a)
  -        | DD(ap, at, ai) -> DD(cosh ap, at * sinh ap, ai)
  +        | DF(ap, at, ai) -> DF(cosh ap, at * sinh ap, ai)
       static member Tanh (a:D) =
           match a with
           | D(a) -> D(tanh a)
  -        | DD(ap, at, ai) -> let cosha = cosh ap in DD(tanh ap, at / (cosha * cosha), ai)
  +        | DF(ap, at, ai) -> let cosha = cosh ap in DF(tanh ap, at / (cosha * cosha), ai)
       static member Asin (a:D) =
           if abs (float a) >= 1. then invalidArgAsin()
           match a with
           | D(a) -> D(asin a)
  -        | DD(ap, at, ai) -> DD(asin ap, at / sqrt (1. - ap * ap), ai)
  +        | DF(ap, at, ai) -> DF(asin ap, at / sqrt (1. - ap * ap), ai)
       static member Acos (a:D) =
           if abs (float a) >= 1. then invalidArgAcos()
           match a with
           | D(a) -> D(acos a)
  -        | DD(ap, at, ai) -> DD(acos ap, -at / sqrt (1. - ap * ap), ai)
  +        | DF(ap, at, ai) -> DF(acos ap, -at / sqrt (1. - ap * ap), ai)
       static member Atan (a:D) =
           match a with
           | D(a) -> D(atan a)
  -        | DD(ap, at, ai) -> DD(atan ap, at / (1. + ap * ap), ai)
  +        | DF(ap, at, ai) -> DF(atan ap, at / (1. + ap * ap), ai)
       static member Abs (a:D) =
           if (float a) = 0. then invalidArgAbs()
           match a with
           | D(a) -> D(abs a)
  -        | DD(ap, at, ai) -> DD(abs ap, at * float (sign (float ap)), ai)
  +        | DF(ap, at, ai) -> DF(abs ap, at * float (sign (float ap)), ai)
       static member Floor (a:D) =
           if isInteger (float a) then invalidArgFloor()
           match a with
           | D(a) -> D(floor a)
  -        | DD(ap, _, ai) -> DD(floor ap, D 0., ai)
  +        | DF(ap, _, ai) -> DF(floor ap, D 0., ai)
       static member Ceiling (a:D) =
           if isInteger (float a) then invalidArgCeil()
           match a with
           | D(a) -> D(ceil a)
  -        | DD(ap, _, ai) -> DD(ceil ap, D 0., ai)
  +        | DF(ap, _, ai) -> DF(ceil ap, D 0., ai)
       static member Round (a:D) =
           if isHalfway (float a) then invalidArgRound()
           match a with
           | D(a) -> D(round a)
  -        | DD(ap, _, ai) -> DD(round ap, D 0., ai)
  +        | DF(ap, _, ai) -> DF(round ap, D 0., ai)
   
   
   /// Tagger for generating incremental integers
  
positive.code:     /// Original value and gradient-vector product (directional derivative) of a vector-to-scalar function `f`, at point `x`, along vector `v`
      let inline gradv' f x v =
          let i = GlobalTagger.Next
          Array.map2 (dualIPT i) x v |> f |> tuple
  
      /// Gradient-vector product (directional derivative) of a vector-to-scalar function `f`, at point `x`, along vector `v`
      let inline gradv f x v =
  
negative.code: [<AutoOpen>]
  module DOps =
      /// Make D, with primal value `p`
      let inline makeDF p =
          match box p with
          | :? float as p -> D(p)
          | :? int as p -> D(float p)
          | :? D as p -> p
      /// Make D, with tag `i`, primal value `p`, and tangent value `t`
      let inline makeDFIPT i p t =
          match box p with
          | :? float as p ->
              match box t with
              | :? float as t -> DF(D p, D t, i)
              | :? D as t -> DF(D p, t, i)
          | :? D as p ->
              match box t with
              | :? float as t -> DF(p, D t, i)
              | :? D as t ->
                  match p, t with
                  | D(_), D(_) -> DF(p, t, i)
                  | D(_), DF(_,_,_) -> DF(p, t, i)
                  | DF(_,_,_), D(_) -> DF(p, t, i)
                  | DF(pp,_ ,pi), DF(tp,tt,ti) when pi < ti -> DF(DF(pp,D 0.,ti), DF(tp,tt,ti), i)
                  | DF(pp,pt,pi), DF(tp,tt,ti) when pi = ti -> DF(DF(pp,pt,pi), DF(tp,tt,pi), i)
                  | DF(pp,pt,pi), DF(tp,_ ,ti) when pi > ti -> DF(DF(pp,pt,pi), DF(tp,D 0.,pi), i)
      /// Make D, with primal value `p` and tangent value `t`. A new tag will be attached using the global tagger.
      let inline makeDFPT p t = makeDFIPT GlobalTagger.Next p t
      /// Make D, with primal tag `i` and primal value `p`, and tangent 1.
      let inline makeDFIP1 i p =
          match box p with
          | :? float as p -> DF(D p, D 1., i)
          | :? D as p ->
              match p with
              | D(_) -> DF(p, D 1., i)
              | DF(_, _, pi) -> DF(p, DF(D 1., D 0., pi), i)
      /// Make D, with primal value `p` and tangent 1. A new tag will be attached using the global tagger.
      let inline makeDFP1 p = makeDFIP1 GlobalTagger.Next p
      /// Get the primal value of `d`
      let inline primal (d:D) =
          match d with
          | D(_) -> d
          | DF(p,_,_) -> p
      /// Get the primal value of `d` with the given tag `i`
      let inline primalI i (d:D) =
          match d with
          | D(_) -> d
          | DF(dp,_,di) when i = di -> dp
          | DF(_,_,di) when i <> di -> d
      /// Get the tangent value of `d`
      let inline tangent (d:D) =
          match d with
          | D(_) -> D(0.)
          | DF(_,t,_) -> t
      /// Get the tangent value of `d` with the given tag `i`
      let inline tangentI i (d:D) =
          match d with
          | D(_) -> D(0.)
          | DF(_,dt,di) when i = di -> dt
          | DF(_,_,di) when i <> di -> D(0.)
      /// Get the primal and the first gradient component of `d`, as a tuple
      let inline tuple (d:D) =
          match d with
          | D(_) -> (d, D 0.)
          | DF(p,t,_) -> (p, t)
  
  
  [<AutoOpen>]
  module ForwardOps =
      /// Original value and first derivative of a scalar-to-scalar function `f`, at point `x`
      let inline diff' f x =
          x |> makeDFP1 |> f |> tuple
  
      /// First derivative of a scalar-to-scalar function `f`, at point `x`
      let inline diff f x =
          x |> makeDFP1 |> f |> tangent
  
      /// Second derivative of a scalar-to-scalar function `f`, at point `x`
      let inline diff2 f x =
  