Commit 6fb55943 authored by Morten Welinder's avatar Morten Welinder

Fixup IRR same as RATE.

parent a9807ec1
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -46,7 +46,7 @@ Morten:
* Fixed many bogusities in xbase plugin.
* Cleanup limits in numtheory. Added BITXOR.
* Fixed RATE, SLD, and SYD.
* Improved RATE's root searching.
* Improved RATE's and IRR's root searching.
Pablo De Napoli:
* New NT_MU function in numtheory.
......
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -4,6 +4,7 @@
* src/functions/fn-financial.c (gnumeric_rate): Respect the sign
of the guess. Work much harder at getting an answer.
(gnumeric_irr): Mirror the RATE improvements.
* src/goal-seek.c (goal_seek_point): New function.
......
......@@ -1739,22 +1739,44 @@ gnumeric_irr (FunctionEvalInfo *ei, Value **argv)
Value *result = NULL;
gnumeric_irr_t p;
float_t rate0;
int n;
goal_seek_initialise (&data);
rate0 = argv[1] ? value_get_as_float (argv[1]) : 0.1;
p.values = collect_floats_value (argv[0], ei->pos,
COLLECT_IGNORE_STRINGS |
COLLECT_IGNORE_BLANKS,
&n, &result);
&p.n, &result);
if (result != NULL) {
g_free (p.values);
return result;
}
p.n = n;
goal_seek_initialise (&data);
/* Respect the sign of the guess. */
if (rate0 >= 0) {
data.xmin = 0;
data.xmax = MIN (data.xmax,
pow (DBL_MAX / 1e10, 1.0 / (p.n + 1)) - 1);
} else {
data.xmin = MAX (data.xmin,
-pow (DBL_MAX / 1e10, 1.0 / (p.n + 1)) + 1);
data.xmax = 0;
}
status = goal_seek_newton (&irr_npv, &irr_npv_df, &data, &p, rate0);
if (status != GOAL_SEEK_OK) {
int factor;
/* Lay a net of test points around the guess. */
for (factor = 2; factor < 100; factor *= 2) {
goal_seek_point (&irr_npv, &data, &p, rate0 * factor);
goal_seek_point (&irr_npv, &data, &p, rate0 / factor);
}
/* Pray we got both sides of the root. */
status = goal_seek_bisection (&irr_npv, &data, &p);
}
g_free (p.values);
if (status == GOAL_SEEK_OK)
......
......@@ -1739,22 +1739,44 @@ gnumeric_irr (FunctionEvalInfo *ei, Value **argv)
Value *result = NULL;
gnumeric_irr_t p;
float_t rate0;
int n;
goal_seek_initialise (&data);
rate0 = argv[1] ? value_get_as_float (argv[1]) : 0.1;
p.values = collect_floats_value (argv[0], ei->pos,
COLLECT_IGNORE_STRINGS |
COLLECT_IGNORE_BLANKS,
&n, &result);
&p.n, &result);
if (result != NULL) {
g_free (p.values);
return result;
}
p.n = n;
goal_seek_initialise (&data);
/* Respect the sign of the guess. */
if (rate0 >= 0) {
data.xmin = 0;
data.xmax = MIN (data.xmax,
pow (DBL_MAX / 1e10, 1.0 / (p.n + 1)) - 1);
} else {
data.xmin = MAX (data.xmin,
-pow (DBL_MAX / 1e10, 1.0 / (p.n + 1)) + 1);
data.xmax = 0;
}
status = goal_seek_newton (&irr_npv, &irr_npv_df, &data, &p, rate0);
if (status != GOAL_SEEK_OK) {
int factor;
/* Lay a net of test points around the guess. */
for (factor = 2; factor < 100; factor *= 2) {
goal_seek_point (&irr_npv, &data, &p, rate0 * factor);
goal_seek_point (&irr_npv, &data, &p, rate0 / factor);
}
/* Pray we got both sides of the root. */
status = goal_seek_bisection (&irr_npv, &data, &p);
}
g_free (p.values);
if (status == GOAL_SEEK_OK)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment