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

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM