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