```julia
using Zygote
using Symbolics
```

## Symbolics Exercise


```julia
@variables x 
```




\begin{equation}
\left[
\begin{array}{c}
x \\
\end{array}
\right]
\end{equation}





```julia
y = 2x
```




\begin{equation}
2 x
\end{equation}





```julia
D = Differential(x)
```




    (::Differential) (generic function with 2 methods)




```julia
D(y)
```




\begin{equation}
\mathrm{\frac{d}{d x}}\left( 2 x \right)
\end{equation}





```julia
expand_derivatives(D(y))
```




\begin{equation}
2
\end{equation}





```julia
w_vec = [x, 2x, 3x, 4x]
```




\begin{equation}
\left[
\begin{array}{c}
x \\
2 x \\
3 x \\
4 x \\
\end{array}
\right]
\end{equation}





```julia
z(x) = 2x
```




    z (generic function with 1 method)




```julia
z(x)
```




\begin{equation}
2 x
\end{equation}




## AutoDiff by Symboic Representation


```julia
i(x) = x
f(x) = 2x
g(x) = 3x
h(x) = 4x
w_vec = [i, h, g, f]
```




    4-element Vector{Function}:
     i (generic function with 1 method)
     h (generic function with 1 method)
     g (generic function with 1 method)
     f (generic function with 1 method)




```julia
function forward_fn(w_vec, x, i::Int)
    y = w_vec[i](x)
    i == size(w_vec)[1] ? y : [y; forward_fn(w_vec,y,i+1)] 
end
```




    forward_fn (generic function with 1 method)




```julia
forward_fn(w_vec, x, 1)
```




\begin{equation}
\left[
\begin{array}{c}
x \\
4 x \\
12 x \\
24 x \\
\end{array}
\right]
\end{equation}




## Basic condition


```julia
i(x) = x
f(x) = 2x
g(x) = 3x
h(x) = 4x
x = 2.0
w_vec = [i, h, g, f]
```




    4-element Vector{Function}:
     i (generic function with 1 method)
     h (generic function with 1 method)
     g (generic function with 1 method)
     f (generic function with 2 methods)




```julia
function forward_fn(w_vec, x, i::Int)
    y = w_vec[i](x)
    i == size(w_vec)[1] ? y : [y; forward_fn(w_vec,y,i+1)] 
end

function reverse_autodiff(w_vec, x_vec, i::Int)
    i == 1 ? 1 :
        gradient(w_vec[i], x_vec[i-1])[1] * 
            reverse_autodiff(w_vec, x_vec, i-1)
end
```




    reverse_autodiff (generic function with 2 methods)




```julia
x_vec = forward_fn(w_vec, x, 1)
y_ad = x_vec[end]
dy_ad = reverse_autodiff(w_vec, x_vec, size(w_vec)[1])
println("AutoDiff: x:$x, y(x):$(y_ad), dy(x):$(dy_ad)")
```

    AutoDiff: x:2.0, y(x):48.0, dy(x):24.0



```julia
y(x) = f(g(h(x)))
dy(x) = gradient(y,x)[1]
println("Symbolic: x:$x, y(x):$(y(x)), dy(x):$(dy(x))")
```

    Symbolic: x:2.0, y(x):48.0, dy(x):24.0


## Full code


```julia
function test() 
    i(x) = x
    f(x) = sin(x)
    g(x) = 3x^2
    h(x) = exp(x)
    x = 2.0
    w_vec = [i, h, g, f]

    x_vec = forward_fn(w_vec, x, 1)
    y_ad = x_vec[end]
    dy_ad = reverse_autodiff(w_vec, x_vec, size(w_vec)[1])
    println("AutoDiff: x:$x, y(x):$(y_ad), dy(x):$(dy_ad)")
    
    y(x) = f(g(h(x)))
    dy(x) = gradient(y,x)[1]
    println("Symbolic: x:$x, y(x):$(y(x)), dy(x):$(dy(x))")
end

test()
```

    AutoDiff: x:2.0, y(x):0.4183537811437451, dy(x):297.54380877119667
    Symbolic: x:2.0, y(x):0.4183537811437451, dy(x):297.54380877119667



```julia

```

a2fea24f01ae9a31f2b0d12fc8876b1822e39753
ipynb
Jupyter Notebook
diffprog/julia_dp/repository/autodiff_chain_rule-symb-Copy1.ipynb
jskDr/keraspp_2021
dc46ebb4f4dea48612135136c9837da7c246534a
MIT
2021-09-21T15:35:04.000Z
2021-12-14T12:14:44.000Z
diffprog/julia_dp/repository/autodiff_chain_rule-symb-Copy1.ipynb
jskDr/keraspp_2021
dc46ebb4f4dea48612135136c9837da7c246534a
MIT
diffprog/julia_dp/repository/autodiff_chain_rule-symb-Copy1.ipynb
jskDr/keraspp_2021
dc46ebb4f4dea48612135136c9837da7c246534a
MIT
Qwen/Qwen-72B
1. YES
2. YES