calculating r using nth root

73 views Asked by At

I am trying to calculate r at a specific time, or f(t_max). I am using a scale from 0 to 255. So I am trying to calculate the correct rate value for exponential growth at t_max = 255, with an initial value or 500, and a max value of 3500.

Exponential growth: f(x) = a(1+r)^x

Want to solve for r:

3500 = 500(1+r)^255

3500/500 = (1+r)^255

7 = (1+r)^255

255 n_root(7) = (1+r)

1.00766 - 1 = r

I found this post and was able to get it to work by creating my own functions, but I was wondering if there was already a function that could calculate it without reinventing the wheel?

Find nth Root of a number in C++

How google calculator expresses this math: enter image description here

This works, but is there a better way?

/*Built from stackoverflow post: Find nth Root of a number in C++ */

Exponential_Growth.h:

/*Built from stackoverflow post:
https://stackoverflow.com/questions/21141447/find-nth-root-of-a-number-in-c?newreg=3a7ef9dc2a444e01b0a25ac3cc4a83d1
*/

#include <iostream>
#include <math.h>

using namespace std;
double exp(double, double);
double n_root_(double, double);

double exp(double a, double b){
    double t(1);
    for(int i = 0;i<b;++i)
        t *= a;
    return t;
}
double n_root_(double num, double n_){
    double x;
    double A(num);
    double dx;
    double eps(10e-6);
    double n(n_);
    x = A * 0.5;
    dx = (A/exp(x,n-1)-x)/n;
    while(dx >= eps || dx <= -eps){
        x = x + dx;
        dx = (A/exp(x,n-1)-x)/n;
    }
   return x;
}

double find_rate(double initial_value, double final_value, double t_max){
    double root_value_ratio = (final_value /  initial_value);
    return ((n_root_(root_value_ratio, t_max) -  1));
}


double exponential_growth_value_at_t(double initial_value, double final_value, double t){
    double r  = find_rate(initial_value, final_value, t);
    double egvat = (initial_value * pow((1 + r),  t));
    return egvat;
}

Useage:

//Per my previous stated values
double initial_value = 500;
double final_value = 3500;
double t_max = 255
t = 128;

fr = find_rate(initial_value, final_value, t_max);

fr = 0.00766021063

egvt = exponential_growth_value_at_t(initial_value, final_value, 128);


fr = 0.00766021063 egvt = 1327.9327

Growth at t = 128: 1327.9327

This works, but not as accurate as posted by @starsplusplus

double exponential_growth_value_at_t(double initial_value, double final_value, double t, double t_max){
    double r  = (log(final_value /  initial_value) / t_max);
    double egvat = (initial_value * pow((1 + r),  t));
    return egvat;
}

I did read all of the search results regarding nth roots to solve for r, but did not see anything that answers this question. I did good in algebra and calc, but not a mathematician.

Thank you for your help, /retnel

1

There are 1 answers

0
Martin Brown On

There is a trick for getting an accurate answer when x becomes large since otherwise you end up subtracting 1 from something that is only very slightly larger than one itself and catastrophic cancellation ensues.

Fortunately most math libraries usually have something along the lines of expm1 which computes the accurate value of exp(x)-1 for small x without any of the cancellation error.

Picking up the algebra from

  7 = (1+r)^255

  ln 7 = 255 ln(1+r)
  exp( (ln 7)/255 )  = 1+r

  r= exp( (ln 7)/255 ) - 1

  r = expm1((ln 7)/255 )

This answer should be good to full machine precision.