views:

159

answers:

4
+1  Q: 

Non-linear counter

So I have a counter. It is supposed to calculate the current amount of something. To calculate this, I know the start date, and start amount, and the amount to increment the counter by each second. Easy peasy. The tricky part is that the growth is not quite linear. Every day, the increment amount increases by a set amount. I need to recreate this algorithmically - basically figure out the exact value at the current date based on the starting value, the amount incremented over time, and the amount the increment has increased over time.

My target language is Javascript, but pseudocode is fine too.

Based on AB's solution:

var now = new Date();

var startDate1 = new Date("January 1 2010");
var days1 = (now - startDate1) / 1000 / 60 / 60 / 24;
var startNumber1 = 9344747520;
var startIncrement1 = 463;
var dailyIncrementAdjustment1 = .506;
var currentIncrement = startIncrement1 + (dailyIncrementAdjustment1 * days1);

startNumber1 = startNumber1 + (days1 / 2) * (2 * startIncrement1 + (days1 - 1) * dailyIncrementAdjustment1);

Does that look reasonable to you guys?

A: 
use strict; use warnings;

my $start = 0;
my $stop = 100;
my $current = $start;

for my $day ( 1 ..  100 ) {
    $current += ($day / 10);
    last unless $current < $stop;
    printf "Day: %d\tLeft %.2f\n", $day, (1 - $current/$stop);
}

Output:

Day: 1  Left 1.00
Day: 2  Left 1.00
Day: 3  Left 0.99
Day: 4  Left 0.99
Day: 5  Left 0.98
...
Day: 42 Left 0.10
Day: 43 Left 0.05
Day: 44 Left 0.01
Sinan Ünür
+1  A: 

If I understand your question correctly, you have an initial value x_0, an initial increment per second of d_0 and an increment adjustment of e per day. That is, on day one the increment per second is d_0, on day two the increment per second is d_0 + e, etc.

Then, we note that the increment per second at time t is

d(t) = d_0 + floor(t / S) * e

where S is the number of seconds per day and t is the number of seconds that have elapsed since t = t_0. Then

x = x_0 + sum_{k < floor(t / S)} S * d(k) + S * (t / S - floor(t / S)) * d(t)

is the formula that you are seeking. From here, you can simplify this to

x = x_0 + S * floor(t / S) d_0 + S * e * (floor(t / S) - 1) * floor(t / S) / 2.
Jason
+2  A: 

It's a quadratic function. If t is the time passed, then it's the usual at2+bt+c, and you can figure out a,b,c by substituting the results for the first 3 seconds.

Or: use the formula for the arithmetic progression sum, where a1 is the initial increment, and d is the "set amount" you refer to. Just don't forget to add your "start amount" to what the formula gives you.

If x0 is the initial amount, d is the initial increment, and e is the "set amount" to increase the incerement, it comes to x0 + (t/2)*(2d + (t-1)*e)

AVB
Does the arithmetic progression solution only work for discreet increases? The way I worded my question implies that this is indeed what I was looking for, but if the increase occurs continuously throughout the day, and not in a discreet step each day, then something tells me that I'd need to use a different formula. A colleague suggested an integral of some kind, but my mathematical background is insufficient to make any initial judgment as to that solution's potential efficacy.Thank you for your assistance,Patrick
uncultured
@uncultured: You pretty much answered your own question. When you move from a discrete setting to continuous, sums are replaced by integrals, and differences by derivatives. The rest depends very much on the particulars of your case.
AVB
Thanks again. I think the arithmetic progression solution will be more than sufficient for my needs. These numbers are marketing, not scientific or mission critical, so creating a perfect analog to reality is overkill.
uncultured
A: 

Your question is slightly ambiguous, to my reading, when you state Every day, the increment amount increases by a set amount; I'm not sure if you mean that the increment is added, or is a multiplicative factor.

Take the second case first, and let a represent the starting amount, i represent the increment, and r represent the set amount by which the increment increases. Then your series progresses like this:

t=0   a
t=1   a+i
t=2   a+i+i(1+r)
t=3   a+i+i(1+r)+i(1+r)(1+r) == a+i(1+r)^0+i(1+r)^1+i(1+r)^2
t=4   a+i+i(1+r)+i(1+r)(1+r)+i(1+r)(1+r)(1+r) == a+i(1+r)^0+i(1+r)^1+i(1+r)^2+i(1+r)^3

As @James said in his answer, this looks like compound interest. Taking the second case, and retaining the same notation, I get

t0   a
t1   a+i == a+i+r*0
t2   a+i+i+r == a+2i+r
t3   a+i+i+i+r+r+r == a+3i+3r
t4   a+i+i+i+i+r+r+r+r+r+r == a+4i+6r

at which point it gets tedious ... As you will have noticed the factor by which r is multiplied is simply the sum of the first n-1 integers. Whatever this is it doesn't look quadratic to me.

But I often don't understand questions on SO, so this may be no use to OP at all.

High Performance Mark
I did misunderstand the question !
High Performance Mark