How would you solve this equation for "A"?

146 Views Asked by At

While working on some formulas, I was trying to solve for each variable. The first set of formulas deal with interest that gets calculated once per year and are fairly simple to come up with:

n = lambda iy, pv, fv: math.log(fv / pv) / math.log(iy + 1)
iy = lambda n, pv, fv: (fv / pv) ** (1 / n) - 1
pv = lambda n, iy, fv: fv / (iy + 1) ** n
fv = lambda n, iy, pv: pv * (iy + 1) ** n

The second set of formulas add a fifth variable called A that denotes how many times per year the interest gets calculated. Twelve would be a reason number for interest calculated once per month:

n = lambda iy, pv, fv, a: math.log(fv / pv) / (math.log(iy / a + 1) * a)
iy = lambda n, pv, fv, a: ((fv / pv) ** (1 / (n * a)) - 1) * a
pv = lambda n, iy, fv, a: fv / (iy / a + 1) ** (n * a)
fv = lambda n, iy, pv, a: pv * (iy / a + 1) ** (n * a)

While trying to solve for A, I came up with the following formula but do not know how to solve it:

A * log(IY / A + 1) = log(FV / PV) / N

My problem is that I am not sure how to get the values out of the logon the left side. What is A?

The process for getting the current formula was as follows:

FV = PV * (IY / A + 1) ** (N * A)
FV / PV = (IY / A + 1) ** (N * A)
N * A = log(FV / PV) / log(IY / A + 1)
A * log(IY / A + 1) = log(FV / PV) / N

Addendum 1:

After some more work with the formula, the following was developed, but the results do not appear to be helpful. While solving for the other A, the first that was practically extracted got buried:

log(IY / A + 1) = log(FV / PV) / (N * A)
IY / A + 1 = e ** (log(FV / PV) / (N * A))
IY / A = e ** (log(FV / PV) / (N * A)) - 1
A = IY / (e ** (log(FV / PV) / (N * A)) - 1)

Addendum 2:

Reading through Claude Leibovici's answer led me further down the path of trying to solve for A in the forumulas up above. From the first attempt to solve, the result became much simpler indeed:

log(IY / A + 1) = log(FV / PV) / (IY * N) * (IY / A)
b = -log(FV / PV) / (IY * N)
IY / A = W(b * e ** b) / b - 1
A = IY / (W(b * e ** b) / b - 1)
A = IY / (W(b * e ** b) / b - b / b)
A = IY / ((W(b * e ** b) - b) / b)
A = (IY * b) / (W(b * e ** b) - b)

From this formula, some code may be written in an attempt to duplicate the method needed to solve for A. Unfortunately, the resulting answer is a large, negative number but should be twelve:

#! /usr/bin/env python3
import math


def main():
    var_n = 35      # thirty-five year investment
    var_iy = .04    # four percent interest per year
    var_pv = 30000  # thirty thousand dollar investment
    var_a = 12      # compounded twelve times per year
    var_fv = round(fv(var_n, var_iy, var_pv, var_a), 2)
    print('Future Value        =', var_fv)
    var_a = a(var_n, var_iy, var_pv, var_fv)
    print('Compounded Per Year =', var_a)


fv = lambda n, iy, pv, a: pv * (iy / a + 1) ** (n * a)


def a(n, iy, pv, fv):
    b = -math.log(fv / pv) / (iy * n)
    return (iy * b) / (lambert_w(b * math.exp(b)) - b)


def lambert_w(z, tolerance=1e-8):
    a = z
    while True:
        b = math.exp(a)
        c = a * b
        d = a - (c - z) / (c + b)
        if abs(a - d) <= tolerance:
            return a
        a = d


if __name__ == '__main__':
    main()

Question: Can someone identify my mistake and help to correct the formulas shown above?

1

There are 1 best solutions below

1
On

The equation being $$A \log\left(\frac{IY} A+1\right) =\frac 1 N \log\left(\frac{FV}{PV}\right)$$ let us define $$x =\frac{IY} A \qquad \text {and}\qquad b=\frac{\log \left(\frac{\text{FV}}{\text{PV}}\right)}{\text{IY} \times N}$$ wich makes the equation to be $$\log(1+x)=b x$$ for which Lambert function is obviously a good candidate.

In term of Lambert function, the solution then simply write

$$x=-1-\frac{W\left(-b e^{-b}\right)}{b}$$

This function is available in many softwares and you could find many subroutines (code source) in a lot of places on the Internet. In the worst case, the link provides series expansion for an evaluation of $W(z)$. If you want to code it, I suggest the iterative Halley method as proposed by Corless (look at the end of the Wikipedia page).

Otherwise, numerical solutions are quite easy considering that we look for the zero of $$f(x)=\log(1+x)-b x\qquad\text{with}\qquad f'(x)=\frac{1}{x+1}-b \qquad\text{and}\qquad f''(x)=-\frac{1}{(x+1)^2}$$ The first derivative cancels at $$x_*=\frac{1-b}{b}\implies f(x_*)=b-1-\log(b)\implies f''(x_*)<0$$

Since $x=0$ is a trivial solution, you will need to start iterating using $x_0>x_*$ (if $b>0$) or $x_0<x_*$ (if $b<0$) in order to ensure convergence to the non trivial solution (by Darboux, there will be an overshoot of the solution if you choose as a starting point $x_0$ such that $f(x_0)>0$ but it will be the unique one).

Using Newton method, the iterates will be given by

$$x_{n+1}=\frac{(x_n+1) \log (x_n+1)-x_n}{b x_n+(b-1)}$$

For illustration purposes, let us use $b=0.05$; the maximum being at $x=19$, let us start iterating at $x_0=38$. Newton method will generate the following iterates $$\left( \begin{array}{cc} n & x_n \\ 0 & 38 \\ 1 & 110.399 \\ 2 & 90.7313 \\ 3 & 90.2786 \\ 4 & 90.2783 \end{array} \right)$$