From: Paolo Bonzini Date: 2008-02-11T01:39:58+09:00 Subject: Re: [QUIZ] Internal Rate of Return (#156) Mine is less concise, but it uses, guess what, Newton's method. # compute NPV given cash flows and IRR def npv (cf, irr) (0...cf.length).inject(0) { |npv, t| npv + (cf[t]/(1+irr)**t) } end # compute derivative of the NPV with respect to IRR # d(C_t * (1+IRR)**t)/dIRR = -t * C_t / (1+IRR)**(t-1) # def dnpv (cf, irr) (1...cf.length).inject(0) { |npv, t| npv - (t*cf[t]/ (1+irr)**(t-1)) } end # solve for IRR with newton's method: x_{n+1} = x_n - f(x) / f'(x) def irr (cf) irr = 0.5 it = 0 begin begin oirr = irr irr -= npv(cf, irr) / dnpv(cf, irr) it += 1 return nil if it > 50 end until (irr - oirr).abs < 0.0001 rescue ZeroDivisionError return nil end irr end puts irr([-100,30,35,40,45]) puts irr([-1.0,1.0]) puts irr([-1000.0,999.99]) puts irr([-1000.0,999.0]) puts irr([100,10,10,10]) puts irr([0.0]) puts irr([])