Julia元编程初探——以简单符号求导为例

Posted mocuishle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Julia元编程初探——以简单符号求导为例相关的知识,希望对你有一定的参考价值。

Julia语言具有强大的元编程机制,本文用Julia实现《SICP》中文第二版中第 99 页中的实例:符号求导,体验一下Julia元编程。

运行结果如下:

julia> include("deriv.jl")  # 加载代码
multiplicand (generic function with 1 method)

julia> deriv(:(x + 3), :x)  # 求表达式 x + 3 关于 x 的导数
1

julia> deriv(:(x * y), :x)  #对表达式 x * y进行求导
:y

julia> deriv(:((x * y) * (x + 3)), :x)  #对表达式 (x * y) * (x + 3)进行求导
:(x * y + y * (x + 3))

 

代码如下(deriv.jl):

 

 1 function deriv(expr, var)
 2     if isa(expr, Number)
 3         return 0
 4     elseif isa(expr, Symbol)
 5         if is_same_variable(expr, var)
 6             return 1
 7         else
 8             return 0
 9         end
10     elseif is_sum(expr)
11         make_sum(deriv(addend(expr), var),
12                  deriv(augend(expr), var))
13     elseif is_product(expr)
14         make_sum(make_product(multiplier(expr),
15                               deriv(multiplicand(expr), var)),
16                  make_product(deriv(multiplier(expr), var),
17                                multiplicand(expr)))
18     else
19         println("unknown expression type -- DERIV", expr)
20     end
21 end
22 
23 
24 function is_variable(n)
25     return typeof(n) == Symbol
26 end
27 
28 function is_same_variable(v1, v2)
29     return isa(v1, Symbol) && isa(v2, Symbol) && (v1 == v2)
30 end
31 
32 
33 # function make_sum(a1, a2)
34 #     return Expr(:call, :+, a1, a2)
35 # end
36 
37 # function make_product(m1, m2)
38 #     return Expr(:call, :*, m1, m2)
39 # end
40 
41 function make_sum(a1, a2)
42     if is_eq_number(a1, 0)
43         return a2
44     elseif is_eq_number(a2, 0)
45         return a1
46     elseif isa(a1, Number) && isa(a2, Number)
47         return a1 + a2
48     else
49         return Expr(:call, :+, a1, a2)
50     end
51 end
52 
53 function make_product(m1, m2)
54     if is_eq_number(m1, 0) || is_eq_number(m2, 0)
55         return 0
56     elseif is_eq_number(m1, 1)
57         return m2
58     elseif is_eq_number(m2, 1)
59         return m1
60     elseif isa(m1, Number) && isa(m2, Number)
61         return m1 * m2
62     else
63         return Expr(:call, :*, m1, m2)
64     end
65 end
66 
67 function is_eq_number(expr, num)
68     return isa(expr, Number) && (expr == num)
69 end
70 
71 function is_sum(x)
72     return isa(x, Expr) && x.args[1] == :+
73 end
74 
75 function addend(s)
76     return s.args[2]
77 end
78 
79 function augend(s)
80     return s.args[3]
81 end
82 
83 function is_product(x)
84     return isa(x, Expr) && x.args[1] == :*
85 end
86 
87 function multiplier(p)
88     return p.args[2]
89 end
90 
91 function multiplicand(p)
92     return p.args[3]
93 end

 

以上是关于Julia元编程初探——以简单符号求导为例的主要内容,如果未能解决你的问题,请参考以下文章

以洞穴寻宝为例的记忆算法初探

机器学习基础对 softmax 和 cross-entropy 求导

Python类元编程初探

Kotlin 元编程之 KotlinPoet

装饰器初探

装饰器初探