1

I'm new in Julia and I'm trying to learn to manipulate calculus on it. How do I do if I calculate the gradient of a function with "ForwardDiff" like in the code below and see the function next? I know if I input some values it gives me the gradient value in that point but I just want to see the function (the gradient of f1).

julia> gradf1(x1, x2) = ForwardDiff.gradient(z -> f1(z[1], z[2]), [x1, x2])
gradf1 (generic function with 1 method)
  • You seem to have a wrong understanding of how AD works. There's nothing symbolic involved; no "expressions" to display are ever constructed. You just [evaluate the function on dual numbers](https://arxiv.org/abs/1607.07892). – phipsgabler Jun 20 '19 at 13:22
  • The gradient is a vector defined at a point on a curve. The function can define the curve, or a formula for calculating a gradient, but the gradient itself is a vector -- in the case above, an (x, y) vector. Are you asking to find f1 above? it should be defined in code you are not showing above. – Bill Jun 20 '19 at 13:29
  • -phg thanks. So there's any way to compute the gradient/hessian matrix and display on julia like it's done in matlab? – Bruno Miguel Gonçalves Jun 20 '19 at 13:38
  • Try using https://www.juliaobserver.com/packages/Calculus. Forward-diff does not do symbolic differentiation. – Oscar Smith Jun 20 '19 at 14:00
  • with [SymPy.jl](https://github.com/JuliaPy/SymPy.jl) you can [work with symbolic differentiation](http://mth229.github.io/symbolic.html#Limits) – Felipe Lema Jun 20 '19 at 14:09

1 Answers1

2

To elaborate on Felipe Lema's comment, here are some examples using SymPy.jl for various tasks:

@vars x y z
f(x,y,z) = x^2 * y * z
VF(x,y,z) = [x*y, y*z, z*x]

diff(f(x,y,z), x)  # ∂f/∂x

diff.(f(x,y,z), [x,y,z]) # ∇f, gradiant

diff.(VF(x,y,z), [x,y,z]) |> sum  # ∇⋅VF, divergence

J = VF(x,y,z).jacobian([x,y,z])
sum(diag(J))  # ∇⋅VF, divergence

Mx,Nx, Px, My,Ny,Py, Mz, Nz, Pz = J
[Py-Nz, Mz-Px, Nx-My] # ∇×VF

The divergence and gradient are also part of SymPy, but not exposed. Their use is more general, but cumbersome for this task. For example, this finds the curl:

import PyCall
PyCall.pyimport_conda("sympy.physics.vector",       "sympy")
RF = sympy.physics.vector.ReferenceFrame("R")

v1 = get(RF,0)*get(RF,1)*RF.x + get(RF,1)*get(RF,2)*RF.y + get(RF,2)*get(RF,0)*RF.z
sympy.physics.vector.curl(v1, RF)
jverzani
  • 5,600
  • 2
  • 21
  • 17