0

I often smooth values by blending percentages and inverse percentages with the below:

current_value = (current_value * 0.95f) + (goal_value * 0.05f)

I'm running into a situation where I would like to perform this action n times, and n is a floating point value.

What would be the proper way of performing the above, say 12.5 times for example?

Kalen
  • 3,106
  • 8
  • 29
  • 42
  • Clearly `n` must become an integer. You can get there by rounding or truncation of the fraction. Is your question perhaps better suited for MathOverflow? – Carey Gregory Dec 01 '13 at 06:18
  • A simple first pass would be to run it 12 times and 13 times then do a weighted average of the two (in this case half of each) – RichardPlunkett Dec 01 '13 at 08:01

2 Answers2

1

One way of doing this would be to handle the integer amount, and then approximate the remaining amount. For example (I assume valid inputs, you would want to check for those):

void Smooth(float& current, float goal, float times, float factor){
    // Handle the integer steps;
    int numberIterations = (int)times;
    for (int i = 0; i < numberIterations; ++i){
        current = (factor * current) + (goal * (1 - factor));
    }

    // Aproximate the rest of the step
    float remainingIteration = times - numberIterations;
    float adjusted_factor = factor + ((1 - factor) * (1 - remainingIteration));
    current = (adjusted_factor * current) + (goal * (1 - adjusted_factor));
}

Running for the following values I get:

current=1 goal=2 factor=0.95

12.0 times - 1.45964

12.5 times - 1.47315

13.0 times - 1.48666

Aesylwinn
  • 11
  • 2
0

I appreciate the help! I have been trying several things related to compound interest, and I believe I may have solved this with the following. My ultimate goal in mind (which was actually unstated here) was to actually do this with very little iterative processing. powf() may be the most time consuming piece here.

float blend_n(float c, float g, float f, float n)
{
    if (g != 0.0f)
        return c + ((g - c) / g) * (g - g * powf(1.0f - f, n));
    else
        return c * powf(1.0 - f, n);
}

It's late here, and my redbull is wearing off so there may be some parts that could be factored out.

Usage would be setting c to the return value of blend_n ...

Thanks again!

[EDIT] I should explain here that c is the (current) value, g is the (goal) value, f is the (factor), and n is the (number of steps) [/EDIT]

[EDIT2] An exception has to be made for goal values of 0, as it will result in a NaN (Not a Number) ... Change done to the code above [/EDIT2]

Kalen
  • 3,106
  • 8
  • 29
  • 42