1
$\begingroup$

In a section of a personal PHP project, I would like to calculate the spending factor in a rule where we spend Nth time the previous payment done.

Here is an example of spending.

firstPaymentAmount=10
SpendingFactor=5
PaymentCount=4

payment1:    10
payment2:    50       (=  10 x 5)
payment3:   250       (=  50 x 5)
payment4:  1250       (= 250 x 5)

At the end, we're getting the sum of all payments made and we have :

10 + 50 + 250 + 1250 = 1560

I would like to know the formula that let me retrieve the spending factor (=5 here) by only knowing these parameters:

paymentCount  = 4
initalPayment = 10 
totalPaid     = 1560

By knowing the formula to calculate the spendingFactor, I will then be able to know the amount and details of each payment.

$\endgroup$
0
$\begingroup$

The payment forms a geometric progression: if you call the initial payment $a$ and the spending factor $k$, then the total payment looks like:

$$T = a + ka + k^2 a + k^3 a + \ldots + k^n a$$

There's a short formula for computing this total, which is:

$$T = \frac{a(1-k^n)}{1-k}$$

We can rearrange this formula to put the unknown spending factor $k$ on one side:

$$\frac{T}{a} = \frac{1-k^n}{1-k}$$

If we define $g(k) \equiv \frac{1-k^n}{1-k}$, then what we are really searching for is $g^{-1}\left(\frac{T}{a}\right)$. Because $g$ is always increasing when $k$ is positive, $g$ has a well-defined inverse. I don't see a closed-form function for computing it, but I imagine $g$ is nice enough that since you have a computer, you can find the inverse numerically.


We know that $k$ is positive because it is a spending factor. Moreover, we know that $k$ is less than $\frac{T}{a}$, because a spending rate of $\frac{T}{a}$ would give you the entire total in the second payment.

So we can use binary search:

Define left=0, right=T/a, estimate = (right-left)/2.

Start the loop:

  1. If you think the estimate is good enough (e.g. if you've done enough iterations), return the estimate.
  2. Otherwise, compute $$y = \frac{1-x^n}{1-x}$$ where $x$ is the current estimate.
  3. If the result y is equal to T/a, return it. If it is less than T/a, replace left = y. If it is greater than T/a, replace right = y.
  4. The new esimate is (right-left)/2, with the updated values of left and right.
$\endgroup$
  • $\begingroup$ So the way of find k (spending factor) is by iterating a binary search tree since there is no direct formula? Okay... I will focus on it. Thank you $\endgroup$ – Jean F. Dec 7 '17 at 20:35
0
$\begingroup$

This means you're solving

$$T = \sum_{k=0}^{n-1} I \cdot F^k$$

where $T$ = totalPaid, $n$ = paymentCount, $I$ = initialPayment, and $F$ = spendingFactor.

We know that $$\sum_{k=0}^{n-1} I \cdot F^k = I \cdot \frac{F^n - 1}{F - 1}$$

Hence we're solving $$T = I \cdot \frac{F^n - 1}{F - 1}$$ for $F$.

Here's the bad news: Unless $n<5$, there is no way to find a solution without resorting to numerical methods. (This is because there is no general solution in radicals that applies to all equations of a given degree greater than $4$. It's called the Abel-Ruffini theorem, and it was proved in 1824).

But if $n<5$, here are the first few solutions (the $n=4$ case is beyond unwieldy):

$$n=1: F \, \text{could have been anything}$$

$$n=2: F = \frac{T-I}{I} $$

$$n=3: F = \frac{-I + \sqrt{4 I T -3 I^2}}{2 I} $$

(Considering how complicated these get, I'm not even sure having that having solutions for $n \geq 5$ would be helpful!)

$\endgroup$
  • $\begingroup$ unfotunatelly , most of the time, n (paymentCount) is above 20. thank you for the information. $\endgroup$ – Jean F. Dec 7 '17 at 20:41
0
$\begingroup$

Based on your responses, I've made a PHP code which gets an approximation of the spending factor. It's a modified method.

Getting the exact spending factor is too CPU intensive. So, I'm calculating a near approximation first. This value will always be above the solution. I then decrease that number until I'm getting below the total paid amount.

Here is a PHP sample of what I've done.

$paymentCount   = 4;
$initialPayment = 10; 
$totalPaid      = 1560;

//----- precalculate the factor based on total payment for faster computation
//----- this predefined factor will always be above our final factor

$estimatedSpendingFactor = exp(log($totalPaid) / $paymentCount);

//----- find the estimated spending factor

do
{
    $estimatedSpendingFactor -= 0.0001;

    $y = $initialPayment * (pow($estimatedSpendingFactor, $paymentCount) - 1) 
                         / ($estimatedSpendingFactor-1);
}
while ($y > $totalPaid);

//-----

printf("The spending factor is %f\n", $estimatedSpendingFactor);

the output will be :

The spending factor is : 5.000000
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.