# Jacobian of a (multivariate) function

**URL:** <https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131>\
**Category:** New to Julia\
**Created:** [February 24, 2019, 2:57am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131 "2019-02-24T02:57:06Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [February 24, 2019, 2:57am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/1 "2019-02-24T02:57:07Z")

</div>

I am trying to replicate this using the ForwardDiff module

![33%20PM](https://global.discourse-cdn.com/julialang/original/3X/a/2/a2ed57c5b2c3457c394ace050d2b14e7f70bd526.png)

But this is what I got

```julia
julia> using ForwardDiff

julia> f(x,y)=[x^2+y^3-1,x^4 - y^4 + x*y]
f (generic function with 1 method)

julia> a = [1.0,1.0]
2-element Array{Float64,1}:
 1.0
 1.0

julia> ForwardDiff.jacobian(f, a)
ERROR: MethodError: no method matching f(::Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f),Float64},Float64,2},1})
Closest candidates are:
  f(::Any, ::Any) at REPL[2]:1

```

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [February 24, 2019, 3:30am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/2 "2019-02-24T03:30:32Z")

</div>

`ForwardDiff.jacobian` only works with functions that accept an array as an argument, this is pretty easy to fix:

```julia
julia> using ForwardDiff

julia> f(x,y)=[x^2+y^3-1,x^4 - y^4 + x*y]
f (generic function with 1 method)

julia> a = [1.0,1.0]
2-element Array{Float64,1}:
 1.0
 1.0

julia> ForwardDiff.jacobian(x ->f(x[1],x[2]), a)
2×2 Array{Float64,2}:
 2.0 3.0
 5.0 -3.0

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [February 24, 2019, 7:38am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/3 "2019-02-24T07:38:49Z")

</div>

Note by the way that you can make your code ~7x faster (on my machine) using StaticArrays:

```julia
using ForwardDiff
using StaticArrays

f(x,y) = @SVector [x^2+y^3-1,x^4 - y^4 + x*y]
a = @SVector [1.0,1.0]
ForwardDiff.jacobian(x ->f(x[1],x[2]), a)

```

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [February 24, 2019, 10:25am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/4 "2019-02-24T10:25:57Z")

</div>

> [@tkoolen](#):
>
> ForwardDiff.jacobian(x -\>f(x[1],x[2]), a)

Apparently this works as well, just use the THREE DOTS

```julia
ForwardDiff.jacobian(x -> f(x...), a)

```

God bless those who invented the THREE DOTS

---

<div class="post-metadata">

**Author:** ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)\
**Post date:** [February 24, 2019, 11:42am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/5 "2019-02-24T11:42:10Z")

</div>

> [@StevenSiew](#):
>
> God bless those who invented the THREE DOTS

God bless those who invented destructuring

```julia-auto
julia> using ForwardDiff
[Info: Recompiling stale cache file /home/pkofod/.julia/compiled/v1.0/ForwardDiff/k0ETY.ji for ForwardDiff [f6369f11-7733-5829-9624-2563aa707210]

julia> f((x,y))=[x^2+y^3-1,x^4 - y^4 + x*y]
f (generic function with 1 method)

julia> a = [1.0,1.0]
2-element Array{Float64,1}:
 1.0
 1.0

julia> ForwardDiff.jacobian(x ->f(x), a)
2×2 Array{Float64,2}:
 2.0 3.0
 5.0 -3.0

```

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [February 24, 2019, 1:35pm UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/6 "2019-02-24T13:35:30Z")

</div>

> [@pkofod](#):
>
> ForwardDiff.jacobian(

Why not just use this? “ForwardDiff.jacobian(f,a)”

```julia
julia> using ForwardDiff

julia> f((x,y)) = [x^2+y^3-1,x^4 - y^4 + x*y]
f (generic function with 1 method)

julia> a = [1.0,1.0]
2-element Array{Float64,1}:
 1.0
 1.0

julia> ForwardDiff.jacobian(f,a)
2×2 Array{Float64,2}:
 2.0 3.0
 5.0 -3.0

```

---

<div class="post-metadata">

**Author:** ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)\
**Post date:** [February 24, 2019, 2:44pm UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/7 "2019-02-24T14:44:01Z")

</div>

That was a mistake, yes!

---

<div class="post-metadata">

**Author:** ![glalonde](https://avatars.discourse-cdn.com/v4/letter/g/f07891/32.png) [@glalonde](https://discourse.julialang.org/u/glalonde)\
**Post date:** [February 26, 2019, 9:55pm UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/8 "2019-02-26T21:55:43Z")

</div>

Related question. What am I doing wrong here? It seems like the docs and everything says it should support `SVector` but it isn’t managing the conversion.

```julia
function BicycleDynamics(plant::Bicycle, x::SVector{5, T}, u::SVector{2, T}) where {T <: Real}
    # of the traction wheel
    turning_radius = plant.wheelbase / tan(x[4])
    translational_velocity = x[5]
    angular_velocity = x[5] / turning_radius
    return SVector(cos(x[3]), sin(x[3]), angular_velocity, u[1], u[2])
end
bike = MakeBike()
ad_adapter(x::SVector{7, T}) where {T <: Real} = BicycleDynamics(bike, x[1:5], x[6:7])
ad_point = SVector{7, Float64}(1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0)
ForwardDiff.jacobian(ad_adapter, ad_point)

```

Produces the error:

```julia
ERROR: LoadError: MethodError: no method matching BicycleDynamics(::Bicycle, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(ad_adapter),Float64},Float64,7},1}, ::Array{ForwardDiff.Dual{ForwardDiff.Tag{typeof(ad_adapter),Float64},Float64,7},1})

```

EDIT:  
Figured it out. Problem was slicing an `SVector` with constant indices doesn’t result in another `SVector`. So I need to convert manually

---

<div class="post-metadata">

**Author:** ![GregVernon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gregvernon/32/5611_2.png) [@GregVernon](https://discourse.julialang.org/u/GregVernon)\
**Post date:** [March 14, 2019, 3:45am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/9 "2019-03-14T03:45:53Z")

</div>

To expand on this, if what someone wants a callable function, `j`, that computes the Jacobian then this should work:

```julia
julia> f(x,y)=[x^2+y^3-1,x^4-y^4+x*y]
julia> j(x)=ForwardDiff.jacobian(x->f(x[1],x[2]), x)
julia> j([0.5;0.5])
2x2 Array{Float64,2}:
 1.0 0.75
 1.0 0.0

```

---

<div class="post-metadata">

**Author:** ![jchen975](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jchen975/32/8994_2.png) [@jchen975](https://discourse.julialang.org/u/jchen975)\
**Post date:** [May 8, 2020, 11:31pm UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/10 "2020-05-08T23:31:27Z")

</div>

Hi, thanks for your solutions. Related to this question: why would the following break?

```julia
using ForwardDiff
import ForwardDiff.jacobian

function f((x))
    F = zeros(3)
    F[1] = x[1]^2+x[3]
    F[2] = x[1]+x[2]
    F[3] = x[2]^2 + x[3]^2
    return F
end

x0 = [1,2,3]
J0 = jacobian(f, x0)

```

Here is the error message:  
`ERROR: LoadError: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f),Int64},Int64,3})`

It is easy to verify the solution is

\begin{bmatrix} 2 & 0 & 1 \\ 1 & 1 & 0 \\ 0 & 4 & 6 \end{bmatrix}

This is given correctly by your method, by instead writing `f` as `f((x)) = [x[1]^2+x[3], x[1]+x[2], x[2]^2 + x[3]^2]`

I’m writing it the first way since my real function is much more sophisticated and would be impossible to write as an anonymous function. I need to iterate over a list of things and do some calculations, and at the end of each loop write `F[i] = loop i result`

Hope you could help with this, thanks!

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 9, 2020, 1:19am UTC](https://discourse.julialang.org/t/jacobian-of-a-multivariate-function/21131/11 "2020-05-09T01:19:47Z")

</div>

1. You only need `function f(x)`

2. Defining `F` as `zeros(3)` restricts its entries to be `Float64`s, whereas to use `ForwardDiff`  
they need to be `Dual`s.

Change it to `F = similar(x)` or `F = zero.(x)`

to get something of the correct type:

```julia
function f(x)
    F = zero.(x)

    F[1] = x[1]^2 + x[3]
    F[2] = x[1] + x[2]
    F[3] = x[2]^2 + x[3]^2

    return F
end

```
