How to find lowest fixed balance in decimals using bisection in Ruby - ruby

How do I find the LOWEST FIXED monthly payment in 2 dp to pay off the balance with compounded interest for 12 months using bisection in ruby?
Disclaimer: I am applying upperBound and unpaidBalance formula correctly.
Test case:
find_fixed_payment(320000, 0.2) should return 29157.09
But my current method returns the middle value of 29591.87 which is way more than enough as the fixed payment (need to reduce to the lowest).
Where did my code went wrong as I am not sure how to do bisection (im using binary search)?
def find_fixed_payment(balance,annualInterestRate)
lowerBound = balance/12
upperBound = (balance * (1 + annualInterestRate/12)**12) / 12.0
unpaidBalance = balance
while true
middle = (lowerBound + upperBound )/2
#use middle as the monthly payment at first
(1..12).each do |i|
unpaidBalance = (unpaidBalance - middle) +
annualInterestRate / 12 * (unpaidBalance - middle)
end
temp = unpaidBalance.floor
if temp < 0
middle -= 0.01
upperBound = middle
# should go to for loop to reduce unpaid balance
# with new middle but not happening, why?
else
middle += 0.01
lowerBound = middle
end
if temp == 0
return middle
end
if upperBound == lower+1
return -1
end
return middle.round(2)
end
end

You made a lot of errors, I'm assuming you were transcribing this method from a reading somewhere, and simply failed to understand the process it was describing.
Basically you initialize all your starting variables, then you need the create the loop. Once in the loop, each time through you're calculating, you'll need to reset the balance back to 320,000 or it becomes a bit of a moving target and we'll never get the answer you're looking for.
I used the times method on the integer 12 to simulate the 12 month cycle, in your attempt you used a range and called the each method.
Now, I'm not sure why you were trying to adjust the value of middle like that, but it was a moot point because once it looped back to the beginning of your while true loop, it just went back to the original middle value. In my version I changed the upper or lower bound appropriately. Think of it like a number guessing of 1-10, you're smart enough to know you just pick the middle every time until you get it, and you would start with a lower bound of 1 and upper of 10, then guess 5. If I told you higher, you now know that 5 is your lower and 10 is still your upper.
Note: I hope this helps, and welcome other users feel free to critique and refactor my code, I only started ruby recently.
def find_fixed_payment(balance,annualInterestRate)
monthlyInterestRate = annualInterestRate / 12
lowerBound = balance/12
upperBound = (balance * (1 + monthlyInterestRate)**12) / 12.0
unpaidBalance = balance
accuracy = 0.01
while unpaidBalance.abs > accuracy
balance = unpaidBalance
middle = (lowerBound + upperBound) / 2
12.times do
newUnpaidBalance = unpaidBalance - middle
monthInterest = monthlyInterestRate * newUnpaidBalance
unpaidBalance = newUnpaidBalance + monthInterest
end
if unpaidBalance < 0
upperBound = middle
unpaidBalance = balance
elsif unpaidBalance > accuracy
lowerBound = middle
unpaidBalance = balance
end
end
middle.round(2)
end
find_fixed_payment(320000, 0.2)

Related

Dynamic Programming and Probability

I've been staring at this problem for hours and I'm still as lost as I was at the beginning. It's been a while since I took discrete math or statistics so I tried watching some videos on youtube, but I couldn't find anything that would help me solve the problem in less than what seems to be exponential time. Any tips on how to approach the problem below would be very much appreciated!
A certain species of fern thrives in lush rainy regions, where it typically rains almost every day.
However, a drought is expected over the next n days, and a team of botanists is concerned about
the survival of the species through the drought. Specifically, the team is convinced of the following
hypothesis: the fern population will survive if and only if it rains on at least n/2 days during the
n-day drought. In other words, for the species to survive there must be at least as many rainy days
as non-rainy days.
Local weather experts predict that the probability that it rains on a day i ∈ {1, . . . , n} is
pi ∈ [0, 1], and that these n random events are independent. Assuming both the botanists and
weather experts are correct, show how to compute the probability that the ferns survive the drought.
Your algorithm should run in time O(n2).
Have an (n + 1)×n matrix such that C[i][j] denotes the probability that after ith day there will have been j rainy days (i runs from 1 to n, j runs from 0 to n). Initialize:
C[1][0] = 1 - p[1]
C[1][1] = p[1]
C[1][j] = 0 for j > 1
Now loop over the days and set the values of the matrix like this:
C[i][0] = (1 - p[i]) * C[i-1][0]
C[i][j] = (1 - p[i]) * C[i-1][j] + p[i] * C[i - 1][j - 1] for j > 0
Finally, sum the values from C[n][n/2] to C[n][n] to get the probability of fern survival.
Dynamic programming problems can be solved in a top down or bottom up fashion.
You've already had the bottom up version described. To do the top-down version, write a recursive function, then add a caching layer so you don't recompute any results that you already computed. In pseudo-code:
cache = {}
function whatever(args)
if args not in cache
compute result
cache[args] = result
return cache[args]
This process is called "memoization" and many languages have ways of automatically memoizing things.
Here is a Python implementation of this specific example:
def prob_survival(daily_probabilities):
days = len(daily_probabilities)
days_needed = days / 2
# An inner function to do the calculation.
cached_odds = {}
def prob_survival(day, rained):
if days_needed <= rained:
return 1.0
elif days <= day:
return 0.0
elif (day, rained) not in cached_odds:
p = daily_probabilities[day]
p_a = p * prob_survival(day+1, rained+1)
p_b = (1- p) * prob_survival(day+1, rained)
cached_odds[(day, rained)] = p_a + p_b
return cached_odds[(day, rained)]
return prob_survival(0, 0)
And then you would call it as follows:
print(prob_survival([0.2, 0.4, 0.6, 0.8])

Calculate cash flows given a target IRR

I apologize if the answer for this is somewhere already, I've been searching for a couple of hours now and I can't find what I'm looking for.
I'm building a simple financial calculator to calculate the cash flows given the target IRR. For example:
I have an asset worth $18,000,000 (which depreciates at $1,000,000/year)
I have a target IRR of 10% after 5 years
This means that the initial investment is $18,000,000, and in year 5, I will sell this asset for $13,000,000
To reach my target IRR of 10%, the annual cash flows have to be $2,618,875. Right now, I calculate this by hand in an Excel sheet through guess-and-check.
There's other variables and functionality, but they're not important for what I'm trying to do here. I've found plenty of libraries and functions that can calculate the IRR for a given number of cash flows, but nothing comes up when I try to get the cash flow for a given IRR.
At this point, I think the only solution is to basically run a loop to plug in the values, check to see if the IRR is higher or lower than the target IRR, and keep calculating the IRR until I get the cash flow that I want.
Is this the best way to approach this particular problem? Or is there a better way to tackle it that I'm missing? Help greatly appreciated!
Also, as an FYI, I'm building this in Ruby on Rails.
EDIT:
IRR Function:
NPV = -(I) + CF[1]/(1 + R)^1 + CF[2]/(1 + R)^2 + ... + CF[n]/(1 + R)^n
NPV = the Net Present Value (this value needs to be as close to 0 as possible)
I = Initial investment (in this example, $18,000,000)
CF = Cash Flow (this is the value I'm trying to calculate - it would end up being $2,618,875 if I calculated it by hand. In my financial calculator, all of the cash flows would be the same since I'm solving for them.)
R = Target rate of return (10%)
n = the year (so this example would end at 5)
I'm trying to calculate the Cash Flows to within a .005% margin of error, since the numbers we're working with are in the hundreds of millions.
Let
v0 = initial value
vn = value after n periods
n = number of periods
r = annual rate of return
y = required annual net income
The one period discount factor is:
j = 1/(1+r)
The present value of the investment is:
pv = - v0 + j*y + j^2*y + j^3*y +..+ j^n*y + j^n*vn
= - v0 + y*(j + j^2 + j^3 +..+ j^n) + j^n*vn
= - v0 + y*sn + j^n*vn
where
sn = j + j^2 + j^3 + j^4 +..+ j^n
We can calulate sn as follows:
sn = j + j^2 + j^3 + j^4 +..+ j^n
j*sn = j^2 + j^3 + j^4 +..+ j^n + j^(n+1)
sn -j*sn = j*(1 - j^n)
sn = j*(1 - j^n)/(1-j)
= (1 - j^n)/[(1+r)(r/(1+r)]
= (1 - j^n)/r
Set pv = 0 and solve for y:
y*sn = v0 - vn * j^n
y = (v0 - vn * j^n)/sn
= r * (v0 - vn * j^n)/(1 - j^n)
Our Ruby method:
def ann_ret(v0, vn, n, r)
j = 1/(1+r)
(r * (v0 - vn * j**n)/(1 - j**n)).round(2)
end
With annual compounding:
ann_ret(18000000, 13000000, 5, 0.1) # => 2618987.4
With semi-annual compounding:
2 * ann_ret(18000000, 13000000, 10, 0.05) # => 2595045.75
With daily compounding:
365 * ann_ret(18000000, 13000000, 5*365, 0.10/365) # => 2570881.20
These values differ slightly from the required annual return you calculate. You should be able to explain the difference by comparing present value formulae.
There's a module called Newton in Ruby... it uses the Newton Raphson method.
I've been using this module to implement the IRR function into this library:
https://github.com/Noverde/exonio
If you need the IRR, you can use like this:
Exonio.irr([-100, 39, 59, 55, 20]) # ==> 0.28095

(running forever) Finding a triangular # with over 500 factors

I am currently working on the peuler question. I think I have the correct code since I tested it with the one that was provided in the example. However, when I try to run it to find the first triangular number with over 500 factors, it stays running for over 15 minutes. But when I try and find the first triangular number with over 100 factors, it finds it in under a minute.
Please see below:
My question is how can I get this too calculate quicker? Because it seems to be stuck?
#Project 12 #http://projecteuler.net/problem=12
def triangle(x) #finds the (x)st triangular number
x=(1..x)
return x.inject(:+)
end
def factors(x) #calculates how many factors (x) has
factors =[]
range=(1..x)
range.each {|num|
if x%num==0
factors << num
end
}
return factors.length
end
def project12(x) #finds the first triangular number that has over (x) factors
i=1
until factors(triangle(i)) > x
i += 1
end
return triangle(i)
end
print project12(500)
So, in triangle(x), you do x-1 additions. You run through this at i and up to i in your code, so we have (i-1) + (1 + 2 + 3 + 4 + 5 + 6 + ... + i - 1) which approximates to i^2/2. Then, in factors your code runs essentially at x time. You do this for every triangle(i), so we have 1*triangle(1) + 2*triangle(2) + 3*triangle(3) + 4*triangle(4) + ... + i*triangle(i) = 1*0 + 2*1 + 3*2 + 4*3 + ... + i*(i-1), which is approximately i^3/3 - i/3.
What does this mean? It means that based on my sketch your program runs at approximately i^3/3 - i/3 + (i-1) iterations. This is cubic time and definitely does not scale.
If, for example we had to do this up until i = 50, this would run 41699 times through. Now, let us imagine doing it just one time more: 44255 times if i = 51. That's definitely not going to scale.

implementing a simple big bang big crunch (BB-BC) in matlab

i want to implement a simple BB-BC in MATLAB but there is some problem.
here is the code to generate initial population:
pop = zeros(N,m);
for j = 1:m
% formula used to generate random number between a and b
% a + (b-a) .* rand(N,1)
pop(:,j) = const(j,1) + (const(j,2) - const(j,1)) .* rand(N,1);
end
const is a matrix (mx2) which holds constraints for control variables. m is number of control variables. random initial population is generated.
here is the code to compute center of mass in each iteration
sum = zeros(1,m);
sum_f = 0;
for i = 1:N
f = fitness(new_pop(i,:));
%keyboard
sum = sum + (1 / f) * new_pop(i,:);
%keyboard
sum_f = sum_f + 1/f;
%keyboard
end
CM = sum / sum_f;
new_pop holds newly generated population at each iteration, and is initialized with pop.
CM is a 1xm matrix.
fitness is a function to give fitness value for each particle in generation. lower the fitness, better the particle.
here is the code to generate new population in each iteration:
for i=1:N
new_pop(i,:) = CM + rand(1) * alpha1 / (n_itr+1) .* ( const(:,2)' - const(:,1)');
end
alpha1 is 0.9.
the problem is that i run the code for 100 iterations, but fitness just decreases and becomes negative. it shouldnt happen at all, because all particles are in search space and CM should be there too, but it goes way beyond the limits.
for example, if this is the limits (m=4):
const = [1 10;
1 9;
0 5;
1 4];
then running yields this CM:
57.6955 -2.7598 15.3098 20.8473
which is beyond all limits.
i tried limiting CM in my code, but then it just goes and sticks at all top boundaries, which in this example give CM=
10 9 5 4
i am confused. there is something wrong in my implementation or i have understood something wrong in BB-BC?

Optimizing this "Boundarize" method for Numerics in Ruby

I'm extending Numerics with a method I call "Boundarize" for lack of better name; I'm sure there are actually real names for this. But its basic purpose is to reset a given point to be within a boundary.
That is, "wrapping" a point around the boundary; if the area is betweeon 0 and 100, if the point goes to -1:
-1.boundarize(0,100) # => 99
(going one too far to the negative "wraps" the point around to one from the max).
102.boundarize(0,100) # => 2
It's a very simple function to implement; when the number is below the minimum, simply add (max-min) until it's in the boundary. If the number is above the maximum, simply subtract (max-min) until it's in the boundary.
One thing I also need to account for is that, there are cases where I don't want to include the minimum in the range, and cases where I don't want to include the maximum in the range. This is specified as an argument.
However, I fear that my current implementation is horribly, terribly, grossly inefficient. And because every time something moves on the screen, it has to re-run this, this is one of the bottlenecks of my application. Anyone have any ideas?
module Boundarizer
def boundarize min=0,max=1,allow_min=true,allow_max=false
raise "Improper boundaries #{min}/#{max}" if min >= max
raise "Cannot have two closed endpoints" if not (allow_min or allow_max)
new_num = self
if allow_min
while new_num < min
new_num += (max-min)
end
else
while new_num <= min
new_num += (max-min)
end
end
if allow_max
while new_num > max
new_num -= (max-min)
end
else
while new_num >= max
new_num -= (max-min)
end
end
return new_num
end
end
class Numeric
include Boundarizer
end
0.boundarize(10,50) # => 40
10.boundarize(0,10) # => 0 (the maximum is by default not allowed)
0.boundarize(0,20,false) # => 20 (the minimum is not allowed)
It looks to me like all you need is modulo (% operator) with a couple of extra checks to handle allow_min and allow_max:
irb(main):002:0> -1 % 100
=> 99
irb(main):003:0> -101 % 100
=> 99
irb(main):004:0> 102 % 100
=> 2
your operation is pretty much the modulo operation see here.
Ruby provides the operator % for that.

Resources