--Boundary-00=_HT0rHOMwZW30Cy7
Content-Type: Multipart/Mixed;
boundary="Boundary-00=_HT0rHOMwZW30Cy7"
--Boundary-00=_HT0rHOMwZW30Cy7
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Here's a second solution from me:
http://pastie.caboo.se/150029
Well, maybe its a half-solution, since it defers the real work to an external
program. A while ago I wrote some code for communicating with a Maxima
process [1]. This solution uses it to directly solve the NVP equation (for
both real and complex IRRs). Note that there is a bug in version 0.0.4 of my
library that incorrectly returns only the first line of a multi-line result,
so it doesn't always work. I've had it fixed in a newer version for a while,
but never released it. I'll try to get it up within the next few days.
[1] http://www.jessemerriman.com/project/ltf
--Boundary-00=_HT0rHOMwZW30Cy7
Content-Type: application/x-ruby;
name="irr_maxima.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="irr_maxima.rb"
#!/usr/bin/env ruby
# Ruby Quiz 156: Internal Rate of Return
# Jesse Merriman, Maxima version
require 'ltf'
include LTF
class Array
def map_with_index
mapped = []
each_with_index { |x, i| mapped << yield(x, i) }
mapped
end
end
if __FILE__ == $0
cash_flows = ARGV[0..-2]
accuracy = ARGV[-1].to_i
eq = '0 = ' +
cash_flows.map_with_index { |x, i| "#{x}/(1+irr)^#{i}" }.join(' + ')
max = Maxima.new "fpprec: #{accuracy};"
max.puts "res: solve([#{eq}], [irr]);"
sols = []
num_sols = max.puts('length(res);').to_i
num_sols.times { |i| sols << max.puts("bfloat(res[#{i+1}]);") }
real_sols, complex_sols = [], []
sols.each do |s|
if /%i/.match(s)
complex_sols << s
else
real_sols << s
end
end
puts 'Real solutions:'
puts ' ' + real_sols.join("\n ")
puts 'Complex solutions:'
puts ' ' + complex_sols.join("\n ")
max.quit
end
--Boundary-00=_HT0rHOMwZW30Cy7--
--Boundary-00=_HT0rHOMwZW30Cy7--