2011-07-30 39 views
2

我想在Ruby中使用bigdecimal/newton模塊來實現XIRR。我已經編寫了一個腳本,通過遵循this example進行嘗試。XIRR實現的bigdecimal/newton錯誤

當我(在Mac OS X 10.6的Ruby 1.9.2)運行代碼,我得到以下錯誤:

/opt/local/lib/ruby1.9/1.9.1/bigdecimal/ludcmp.rb:84:in `div': wrong number of arguments(2 for 1) (ArgumentError) 
    from /opt/local/lib/ruby1.9/1.9.1/bigdecimal/ludcmp.rb:84:in `block in lusolve' 
    from /opt/local/lib/ruby1.9/1.9.1/bigdecimal/ludcmp.rb:78:in `downto' 
    from /opt/local/lib/ruby1.9/1.9.1/bigdecimal/ludcmp.rb:78:in `lusolve' 
    from /opt/local/lib/ruby1.9/1.9.1/bigdecimal/newton.rb:60:in `nlsolve' 
    from gistfile1.rb:52:in `<main>' 

這是因爲在我的程序中的錯誤,或者在 BigDecimal的東西圖書館?

#!/opt/local/bin/ruby1.9 
require 'bigdecimal' 
require 'bigdecimal/newton' 
require 'time' 
include Newton 

transactions = [ 
    {amount:BigDecimal::new("-1000"), date:Time.parse("2011-01-01")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-02-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-03-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-04-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-05-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-06-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-07-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-08-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-09-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-10-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-11-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2011-12-11")}, 
    {amount:BigDecimal::new("100"), date:Time.parse("2012-01-11")}, 
] 

class Function 
    values ={ eps: "1.0e-16", one: "1.0", two: "2.0", ten: "10.0", zero: "0.0" } 

    values.each do |key, value| 
    define_method key do 
     BigDecimal::new value 
    end 
    end 

    def initialize(transactions) 
    @transactions = transactions 
    end 

    def values(x) 
    start = @transactions[0][:date] 
    value = [] 

    value << @transactions.reduce(0) do |sum, t| 
     pwr = (t[:date] - start)/365 
     r = t[:amount]/(1.0 + x[0]) ** pwr 
     sum + r 
    end 

    value 
    end 
end 

f = Function.new(transactions) 
x = [f.zero] 
n = nlsolve(f,x) 
puts x 

任何調試協助將不勝感激。

謝謝!

回答

0

問題是,您在計算中將BigDecimal與「正常」數字混合在一起。 嘗試通過它來取代values

values = { 
    eps: BigDecimal.new("1.0e-16"), 
    one: BigDecimal.new("1.0"), 
    two: BigDecimal.new("2.0"), 
    ten: BigDecimal.new("10.0"), 
    zero: BigDecimal.new("0.0") 
} 

value << @transactions.reduce(0) do |sum, t| 
    pwr = (t[:date] - start)/BigDecimal.new("365.0") 
    r = t[:amount]/(BigDecimal.new("1.0") + x[0]) ** pwr 
    sum + r 
end 
+0

感謝def values(x)塊!然而,我也需要'require'bigdecimal/math''並將'r = t [:amount] /(BigDecimal.new(「1.0」)+ x [0])** pwr'改爲'r = t [:amount]/BigMath.exp(pwr * BigMath.log(BigDecimal.new(「1.0」)+ x [0],15),15)' – wk2752