~ubuntu-branches/ubuntu/quantal/gnumeric/quantal

« back to all changes in this revision

Viewing changes to plugins/fn-financial/functions.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-06-07 11:10:47 UTC
  • mfrom: (1.1.19 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090607111047-l3rtbzfjxvmi1kx0
Tags: 1.9.8-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Promoted gnumeric-doc to Recommends in gnumeric package for help to be
    installed automatically
  - gnumeric-gtk is a transitional package
  - gnumeric conflicts with gnumeric-gtk << 1.8.3-3ubuntu1
  - call initltool-update in po*
  - remove psiconv support (psiconv is in universe):
    o debian/control: remove B-D on libpsiconv-dev
    o debian/rules: don't pass --with-psiconv to ./configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#include <tools/goal-seek.h>
31
31
#include <collect.h>
32
32
#include <value.h>
33
 
#include <str.h>
34
33
#include <mathfunc.h>
35
34
#include <gnm-format.h>
36
35
#include <workbook.h>
1497
1496
           "@DESCRIPTION="
1498
1497
           "RATE calculates the rate of an investment.\n"
1499
1498
           "\n"
1500
 
           "* If @pmt is ommitted it defaults to 0\n"
 
1499
           "* If @pmt is omitted it defaults to 0\n"
1501
1500
           "* If @nper <= 0, RATE returns #NUM! error.\n"
1502
1501
           "* If @type != 0 and @type != 1, RATE returns #VALUE! error.\n"
1503
1502
           "\n"
1935
1934
};
1936
1935
 
1937
1936
typedef struct {
1938
 
        int     n;
1939
 
        gnm_float *values;
1940
 
        gnm_float *dates;
 
1937
        int n;
 
1938
        const gnm_float *values;
 
1939
        const gnm_float *dates;
1941
1940
} gnumeric_xirr_t;
1942
1941
 
1943
1942
static GoalSeekStatus
1944
1943
xirr_npv (gnm_float rate, gnm_float *y, void *user_data)
1945
1944
{
1946
 
        gnumeric_xirr_t *p = user_data;
1947
 
        gnm_float *values, *dates, sum;
1948
 
        int i, n;
1949
 
 
1950
 
        values = p->values;
1951
 
        dates = p->dates;
1952
 
        n = p->n;
1953
 
 
1954
 
        sum = 0;
1955
 
        for (i = 0; i < n; i++) {
1956
 
                gnm_float d = dates[i] - dates[0];
 
1945
        const gnumeric_xirr_t *p = user_data;
 
1946
        gnm_float sum = 0;
 
1947
        int i;
 
1948
 
 
1949
        for (i = 0; i < p->n; i++) {
 
1950
                gnm_float d = p->dates[i] - p->dates[0];
1957
1951
 
1958
1952
                if (d < 0)
1959
1953
                        return GOAL_SEEK_ERROR;
1960
 
                sum += values[i] / pow1p (rate, d / 365.0);
 
1954
                sum += p->values[i] / pow1p (rate, d / 365.0);
1961
1955
        }
1962
1956
 
1963
1957
        *y = sum;
1964
1958
        return GOAL_SEEK_OK;
1965
1959
}
1966
1960
 
1967
 
static GnmValue *
1968
 
gnumeric_xirr (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
1961
static int
 
1962
gnm_range_xirr (gnm_float const *xs, const gnm_float *ys,
 
1963
                int n, gnm_float *res, gpointer user)
1969
1964
{
1970
 
        GoalSeekData    data;
1971
 
        GoalSeekStatus  status;
1972
 
        GnmValue           *result = NULL;
1973
1965
        gnumeric_xirr_t p;
1974
 
        gnm_float      rate0;
1975
 
        int             n, d_n;
 
1966
        gnm_float rate0 = *(gnm_float *)user;
 
1967
        GoalSeekData data;
 
1968
        GoalSeekStatus status;
 
1969
 
 
1970
        p.dates = ys;
 
1971
        p.values = xs;
 
1972
        p.n = n;
1976
1973
 
1977
1974
        goal_seek_initialize (&data);
1978
1975
        data.xmin = -1;
1979
1976
        data.xmax = MIN (1000, data.xmax);
1980
1977
 
1981
 
        rate0 = argv[2] ? value_get_as_float (argv[2]) : 0.1;
1982
 
 
1983
 
        p.values = collect_floats_value (argv[0], ei->pos,
1984
 
                                         COLLECT_COERCE_STRINGS,
1985
 
                                         &n, &result);
1986
 
        p.dates = NULL;
1987
 
 
1988
 
        if (result != NULL)
1989
 
                goto out;
1990
 
 
1991
 
        p.dates = collect_floats_value (argv[1], ei->pos,
1992
 
                                        COLLECT_COERCE_STRINGS,
1993
 
                                        &d_n, &result);
1994
 
        if (result != NULL)
1995
 
                goto out;
1996
 
 
1997
 
        p.n = n;
1998
1978
        status = goal_seek_newton (&xirr_npv, NULL, &data, &p, rate0);
1999
1979
        if (status != GOAL_SEEK_OK) {
2000
1980
                int i;
 
1981
 
 
1982
                /* This is likely to be on the left side of the root. */
 
1983
                (void)goal_seek_point (&xirr_npv, &data, &p, -1);
 
1984
 
2001
1985
                for (i = 1; i <= 1024; i += i) {
2002
1986
                        (void)goal_seek_point (&xirr_npv, &data, &p, -1 + 10.0 / (i + 9));
2003
1987
                        (void)goal_seek_point (&xirr_npv, &data, &p, i);
2007
1991
                }
2008
1992
        }
2009
1993
 
2010
 
        if (status == GOAL_SEEK_OK)
2011
 
                result = value_new_float (data.root);
2012
 
        else
2013
 
                result = value_new_error_NUM (ei->pos);
2014
 
 
2015
 
 out:
2016
 
        g_free (p.values);
2017
 
        g_free (p.dates);
2018
 
 
2019
 
        return result;
 
1994
        if (status == GOAL_SEEK_OK) {
 
1995
                *res = data.root;
 
1996
                return 0;
 
1997
        }
 
1998
 
 
1999
        return 1;
 
2000
}
 
2001
 
 
2002
 
 
2003
static GnmValue *
 
2004
gnumeric_xirr (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
2005
{
 
2006
        gnm_float rate0 = argv[2] ? value_get_as_float (argv[2]) : 0.1;
 
2007
 
 
2008
        return float_range_function2d (argv[0], argv[1],
 
2009
                                       ei,
 
2010
                                       gnm_range_xirr,
 
2011
                                       COLLECT_IGNORE_BLANKS |
 
2012
                                       COLLECT_COERCE_STRINGS,
 
2013
                                       GNM_ERROR_VALUE,
 
2014
                                       &rate0);
2020
2015
}
2021
2016
 
2022
2017
/***************************************************************************/