顯示具有 Ruby 標籤的文章。 顯示所有文章
顯示具有 Ruby 標籤的文章。 顯示所有文章

2014年12月19日 星期五

[ RubyAlg ] MIT Linear Algebra, Spring 2005 - Lec7

source from here 
Solving Null Space A(x)=0 
Consider we have a matrix A
>> A = LA.newMtx3(3,4, [1,2,2,2,2,4,6,8,3,6,8,10])
=> #
>> puts A
1 2 2 2
2 4 6 8
3 6 8 10
=> nil

Then we do row elimination: 
>> B = A.rowElim(0,-2,1) # 將 row0 乘與 -2 並加到 row1
>> print("Elim Row1:\n#{B}\n")
Elim Row1:
1 2 2 2
0 0 2 4
3 6 8 10

>> B = B.rowElim(0,-3,2) # 將 row0 乘與 -3 並加到 row2
>> print("Elim Row2:\n#{B}\n")
Elim Row2:
1 2 2 2
0 0 2 4
0 0 2 4

>> B = B.rowElim(1,-1,2) # Row echelon form
>> print("Echelon From:\n#{B}\n")
Echelon From:
1 2 2 2
0 0 2 4
0 0 0 0

>> puts A.rref() Reduce row echelon form
1 2 0 -2.0
0 0.0 1 2.0
0 0.0 0 0.0
=> nil

由上可以知道 pivot 數目為 2 (x1, x3), 因此 free variable 數目等於 4-2=2 (x2, x4). 

Pivot Variables vs Free Variables 
既然是 free variables, 所以我們可以給值並求解 Ax=0. 考慮 x2=1; x4=0, 求 x1, x3: 
 

接著考慮 考慮 x2=0; x4=1, 求 x1, x3: 
 

所以我們可以知道 Ax=0 的 Null Space 為: 
 

Special Solution rref(A)=R 
事實上你會發現 Null Space 的參數與 rref 的矩陣有點相似: 
 

事實上這樣的相似並不是巧合, 而是有背後的原理. 假設我們將 matrix A 得到的 rref 的 col1 與 col2 進行調換, 可以得到: 
>> newREFF = A.rref.swapCol!(1,2) # swap col1 with col2 from reff
>> puts newREFF
1 0 2 -2.0
0 1 0.0 2.0
0 0 0.0 0.0
=> nil

而這樣的結果可以看成下面的示意圖: 
 

此時 x1, x2 為 pivot variables; x3, x4 為 free variables. 接下來解 Rx=0
 

此時可以這麼解 Rx=0
 

這時就可以知道為什麼 Null Space 會跟 rref 的矩陣這麼像了: 

2014年12月11日 星期四

[ Ruby Gossip ] Advance : 方法 - *_missing、*method_added 方法

Source From Here 
Preface 
如果傳遞訊息給物件,而物件最終沒有合適的方法可以回應訊息,則會呼叫 method_missing 方法,傳入代表方法的 Symbol 實例、呼叫方法時的引數與程式區塊。例如: 
 

*_missing、*method_added 方法 
在 BasicObject 中看過實際 method_missing 的應用。另一個常數應用,就是不以 is a 方式增加類別功能(也就是不使用繼承),而以 has a 方式動態為類別實例增加功能時,為了不逐一定義同名方法時,會使用如下方式
 

如果類別定義有 const_missing 方法,在指定的常數不在類別中定義時就會呼叫。例如: 
 

如果類別定義有 method_added 方法,之後若類別中定義了實例方法,就會呼叫該方法: 
 

如果實例上定義有 singleton_method_added 方法,之後若該實例定義了單例方法,就會呼叫該方法: 
 

從上例中可以看到,由於 singleton_method_added 本身也是單例方法,因而在實例上定義 singleton_method_added 後,馬上就會觸發。

2014年12月9日 星期二

[ Ruby Gossip ] Advance : 方法 - inherited、included、extended 方法

Source From Here
Preface
透過 inherited、included、extended 方法, 你可以動態為物件或是類別加入特性或方法. 可以把這三個方法是為引入模組或是繼承類別時的 callback 函數!

inherited、included、extended 方法
如果類別定義有 inherited 類別方法,被子類別繼承時,inherited 會被呼叫,並傳入子類別作為引數。例如:


注意 inherited 被執行的時機,是在子類別本體執行之前。一個應用的例子,在 抽象類別與介面 中談過,模擬了 Java 中抽象類別的概念。

如果模組中定義有 included 模組方法,在被其它類別含括時,included 方法會被呼叫,並傳入含括類別的模組作為引數。例如:


一個應用的例子,在 抽象類別與介面 中談過,用模組來模擬 Java 中 interface 的概念。另一個常見應用,是讓模組可以定義各類別共用的類別方法。例如:
  1. module M1  
  2.     def self.included(clz)  
  3.         def clz.execute  
  4.             puts "共用的 execute 類別方法"  
  5.         end  
  6.     end  
  7. end  
  8.   
  9. class Some  
  10.     include M1  
  11. end  
  12.   
  13. class Other  
  14.     include M1  
  15. end  
  16.   
  17. Some.execute    # 顯示 "共用的 execute 類別方法"  
  18. Other.execute   # 顯示 "共用的 execute 類別方法"  
如果模組定義有 extended 方法,其它實例使用 extended 方法擴充模組時,extended 方法會被呼叫,並傳入實例作為引數。例如:


就類別而言,開啟類別使用 included 來含括模組,與使用實例的 extended 來擴充模組,雖然作用是相同的,但會觸發的方法並不同,分別是 included 與 extended,你也可以同時定義兩個方法,讓 include 與 extend 時,都呼叫同一個方法:
  1. # encoding: utf-8  
  2. module M1  
  3.     def self.included(clz)  
  4.         self.set_execute_class_method(clz)  
  5.     end  
  6.   
  7.     def self.extended(obj)  
  8.         self.set_execute_class_method(obj)  
  9.     end  
  10.   
  11.     def self.set_execute_class_method(unt)  
  12.         def unt.execute  
  13.             puts "#{self}: 共用的 execute 方法"  
  14.         end  
  15.     end  
  16. end  
  17.   
  18. class Some; end  
  19. class Other; end  
  20. class SomeOther  
  21.     include M1  
  22. end  
  23.   
  24. s = Some.new  
  25. s.extend(M1)  
  26. s.execute           # 顯示 "??? 共用的 execute 方法"  
  27.   
  28. Some.extend(M1)  
  29. Other.extend(M1)  
  30.   
  31. Some.execute        # 顯示 "??? 共用的 execute 方法"  
  32. Other.execute       # 顯示 "??? 共用的 execute 方法"  
  33. SomeOther.execute   # 顯示 "??? 共用的 execute 方法"  


2014年12月3日 星期三

[ Ruby Gossip ] Advance : 可執行物件 - 取得 Method

Source From Here
Preface
Ruby 中,方法本身並不直接以物件方式存在,然而可以透過 method 方法取得 Method 實例。例如:


取得 Method
可以看到,取得的 Method 實例,self 綁定的物件是 s,可以取得 Method 實例的應用之一,就是當你的物件公開介面不一致,但又想以統一方式取得呼叫結果時。例如:
  1. class Some  
  2.     def initialize(value)  
  3.         @value = value  
  4.     end  
  5.     def doSome(value)  
  6.         @value - value  
  7.     end  
  8. end  
  9.   
  10. class Other  
  11.     def initialize(amount)  
  12.         @amount = amount  
  13.     end  
  14.     def doOther(amount)  
  15.         @amount - amount  
  16.     end  
  17. end  
  18.   
  19. def utility(p, mth)  
  20.     mth.call(p)  
  21. end  
  22.   
  23. s = Some.new(100)  
  24. o = Other.new(200)  
  25.   
  26. puts utility(10, s.method(:doSome))   # 90  
  27. puts utility(10, o.method(:doOther))  # 190  
Some 的 doSome 方法與 Other 的 doOther 方法,都是接受一個引數並傳回運算值,雖然方法介面不同,但 utility 方法仍可以進行呼叫運算。以 method 方法取得的 Method 實例,self 預設有綁定物件,可以使用 unbind 方法解除 self 的綁定(會取得 UnboundMethod 實例),使用 bind 方法再度綁定 self 的物件。例如:
  1. class Some  
  2.     def initialize(value)  
  3.         @value = value  
  4.     end  
  5.     def doSome(value)  
  6.         @value - value  
  7.     end  
  8. end  
  9.   
  10. s1 = Some.new(10)  
  11. s2 = Some.new(20)  
  12.   
  13. puts s1.doSome(5) # 5  
  14.   
  15. unbind_mth = s1.method(:doSome).unbind  
  16. puts unbind_mth.bind(s2).call(5) # 15  
method 可以取得實例上可呼叫的方法,包括單例方法,如果你想直接取得未綁定 self 的實例方法,也可以使用每個類別都有的 instance_method 方法(這個方法無法取得單例方法)。例如:
  1. class Some  
  2.     def initialize(value)  
  3.         @value = value  
  4.     end  
  5.     def doSome(value)  
  6.         @value - value  
  7.     end  
  8. end  
  9.   
  10. s1 = Some.new(10)  
  11. s2 = Some.new(20)  
  12.   
  13. unbind_mth = Some.instance_method(:doSome)  
  14. puts unbind_mth.bind(s1).call(5) # 5  
  15. puts unbind_mth.bind(s2).call(5) # 15  
bind 可以綁定的對象,必須是同一類別或子類別實例但無法綁定單例方法),它甚至可以作到從子類別實例呼叫父類別中已被重新定義的方法。例如:
  1. class Some  
  2.     def initialize(value)  
  3.         @value = value  
  4.     end  
  5.     def doSome(value)  
  6.         @value - value  
  7.     end  
  8. end  
  9.   
  10. class C_Some < Some  
  11.     def doSome(value)  
  12.         @value + value  
  13.     end  
  14. end  
  15.   
  16. s = Some.new(10)  
  17. c_s = C_Some.new(20)  
  18.   
  19. unbind_mth = Some.instance_method(:doSome)  
  20. puts unbind_mth.bind(s).call(5)   # 5  
  21. puts unbind_mth.bind(c_s).call(5) # 15,而不是 25,因為呼叫了父類別的 doSome  
  22. puts c_s.doSome(5)                # 25  
這感覺有點違反物件導向中多型的概念,一般來說,既然你已重新定義了方法,操作子類別實例的方法時應該就是被重新定義的方法,而不是父類別方法。不過這也開啟了另一個功能性,因為 Ruby 中無法限制某個類別無法被繼承或無法被重新定義,為了確認執行某方法時,該方法一定是沒被重新定義過的方法,就可以使用這種功能性。例如:
  1. class Some  
  2.     def initialize(value)  
  3.         @value = value  
  4.     end  
  5.     def doSome(value)  
  6.         @value - value  
  7.     end  
  8. end  
  9.   
  10. # 一定呼叫Some的doSome  
  11. def do_some(s, v)   
  12.     mth = Some.instance_method(:doSome).bind(s)  
  13.     mth.call(v)  
  14. end  
  15.   
  16. class C_Some < Some  
  17.     def doSome(value)  
  18.         @value + value  
  19.     end  
  20. end  
  21.   
  22. puts do_some(Some.new(10), 5)   # 5  
  23. puts do_some(C_Some.new(20), 5) # 15  
如果願意,你也可以呼叫 to_proc 將一個 Method 轉換為 lambda。例如:


一個應用的例子,可以在 建構、初始與消滅 中看到:
  1. class Some  
  2.     def initialize(value)  
  3.        @value = value  
  4.        ObjectSpace.define_finalizer(self,  
  5.                                     self.method(:finalize).to_proc)  
  6.     end  
  7.     def finalize(object_id)  
  8.         puts "Destroy #{object_id} Some(#{@value})...."  
  9.     end  
  10. end  
  11.   
  12. Some.new(10)  
  13. Some.new(20)  
  14. Some.new(30)  
  15.   
  16. ObjectSpace.garbage_collect   # 提示 GC  
執行結果如下:
Destroy 16096056 Some(30)....
Destroy 16096140 Some(20)....
Destroy 16096224 Some(10)....


[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...