Commit 50fcdf4d authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

new files, contents taken from mathfunc.c among other places.

2001-07-27  Morten Welinder  <terra@diku.dk>

	* src/rangefunc.c, src/rangefunc.h: new files, contents taken from
 	mathfunc.c among other places.
parent 6b736b59
2001-07-27 Morten Welinder <terra@diku.dk>
* src/rangefunc.c, src/rangefunc.h: new files, contents taken from
mathfunc.c among other places.
2001-07-27 Andreas J. Guelzow <aguelzow@taliesin.ca>
* src/analysis-tools.c (correlation_tool) Rewrite to use standard
......
2001-07-27 Morten Welinder <terra@diku.dk>
* src/rangefunc.c, src/rangefunc.h: new files, contents taken from
mathfunc.c among other places.
2001-07-27 Andreas J. Guelzow <aguelzow@taliesin.ca>
* src/analysis-tools.c (correlation_tool) Rewrite to use standard
......
2001-07-27 Morten Welinder <terra@diku.dk>
* src/rangefunc.c, src/rangefunc.h: new files, contents taken from
mathfunc.c among other places.
2001-07-27 Andreas J. Guelzow <aguelzow@taliesin.ca>
* src/analysis-tools.c (correlation_tool) Rewrite to use standard
......
2001-07-27 Morten Welinder <terra@diku.dk>
* src/rangefunc.c, src/rangefunc.h: new files, contents taken from
mathfunc.c among other places.
2001-07-27 Andreas J. Guelzow <aguelzow@taliesin.ca>
* src/analysis-tools.c (correlation_tool) Rewrite to use standard
......
......@@ -151,6 +151,8 @@ GNUMERIC_BASE_SOURCES = \
print-cell.h \
print-info.c \
print-info.h \
rangefunc.c \
rangefunc.h \
ranges.c \
ranges.h \
regression.c \
......
......@@ -2,8 +2,8 @@
* analysis-tools.c:
*
* Authors:
* Jukka-Pekka Iivonen <iivonen@iki.fi>
* Andreas J. Guelzow <aguelzow@taliesin.ca>
* Jukka-Pekka Iivonen <iivonen@iki.fi>
* Andreas J. Guelzow <aguelzow@taliesin.ca>
*
* (C) Copyright 2000 by Jukka-Pekka Iivonen <iivonen@iki.fi>
*
......@@ -15,6 +15,7 @@
#include <string.h>
#include <math.h>
#include "mathfunc.h"
#include "rangefunc.h"
#include "numbers.h"
#include "gnumeric.h"
#include "gnumeric-util.h"
......@@ -591,52 +592,6 @@ set_italic (data_analysis_output_t *dao, int col1, int row1,
sheet_style_apply_range (dao->sheet, &range, mstyle);
}
/* This function exists also in fn-stat.c */
/* One copy ought to suffice. */
static void
cb_range_mode (gpointer key, gpointer value, gpointer user_data)
{
g_free (value);
}
static int
range_mode (const gnum_float *xs, int n, gnum_float *res)
{
GHashTable *h;
int i;
gnum_float mode = 0;
int dups = 0;
if (n <= 1) return 1;
h = g_hash_table_new ((GHashFunc)float_hash,
(GCompareFunc)float_equal);
for (i = 0; i < n; i++) {
int *pdups = g_hash_table_lookup (h, &xs[i]);
if (pdups)
(*pdups)++;
else {
pdups = g_new (int, 1);
*pdups = 1;
g_hash_table_insert (h, (gpointer)(&xs[i]), pdups);
}
if (*pdups > dups) {
dups = *pdups;
mode = xs[i];
}
}
g_hash_table_foreach (h, cb_range_mode, NULL);
g_hash_table_destroy (h);
if (dups <= 1)
return 1;
*res = mode;
return 0;
}
static int
get_labels_n_data (Sheet *sheet, GPtrArray *labels, GPtrArray *data,
Range *range, int columns_flag,
......@@ -755,7 +710,7 @@ correlation_tool (WorkbookControl *wbc, Sheet *sheet,
set_cell (dao, col + 1, row + 1, NULL);
} else {
the_col = g_ptr_array_index (data, col);
the_row = g_ptr_array_index (data,row);
the_row = g_ptr_array_index (data, row);
error = range_correl_pop
((gnum_float *)(the_col->data),
......@@ -830,7 +785,7 @@ covariance_tool (WorkbookControl *wbc, Sheet *sheet,
set_cell (dao, col + 1, row + 1, NULL);
} else {
the_col = g_ptr_array_index (data, col);
the_row = g_ptr_array_index (data,row);
the_row = g_ptr_array_index (data, row);
error = range_covar
((gnum_float *)(the_col->data),
......@@ -868,28 +823,6 @@ covariance_tool (WorkbookControl *wbc, Sheet *sheet,
*
**/
/* FIXME: */
/* The same function range_excel_median is also defined in fn-stat.c. */
/* These functions should probably be moved to math-func.c rather than */
/* having them in two spots. */
static int
range_excel_median (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
/* OK, so we ignore the constness here. Tough. */
qsort ((gnum_float *) xs, n, sizeof (xs[0]),
(void *) &float_compare);
if (n & 1)
*res = xs[n / 2];
else
*res = (xs[n / 2 - 1] + xs[n / 2]) / 2;
return 0;
} else
return 1;
}
static void
summary_statistics (WorkbookControl *wbc, GPtrArray *data, GPtrArray* labels,
......@@ -953,7 +886,7 @@ summary_statistics (WorkbookControl *wbc, GPtrArray *data, GPtrArray* labels,
}
/* Median */
error = range_excel_median (the_data, the_col_len, &x);
error = range_median_inter (the_data, the_col_len, &x);
if (error == 0) {
set_cell_float (dao, col + 1, 3, x);
} else {
......@@ -962,7 +895,7 @@ summary_statistics (WorkbookControl *wbc, GPtrArray *data, GPtrArray* labels,
/* Mode */
error = range_mode((gnum_float *)(the_col->data), the_col->len, &x);
error = range_mode (the_data, the_col_len, &x);
if (error == 0) {
set_cell_float (dao, col + 1, 4, x);
} else {
......
......@@ -126,412 +126,6 @@ gnumeric_fake_trunc (double x)
}
/* Arithmetic sum. */
int
range_sum (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += xs[i];
*res = sum;
return 0;
}
/* Arithmetic sum of squares. */
int
range_sumsq (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += xs[i] * xs[i];
*res = sum;
return 0;
}
/* Arithmetic average. */
int
range_average (const gnum_float *xs, int n, gnum_float *res)
{
if (n <= 0 || range_sum (xs, n, res))
return 1;
*res /= n;
return 0;
}
int
range_min (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float min = xs[0];
int i;
for (i = 1; i < n; i++)
if (xs[i] < min)
min = xs[i];
*res = min;
return 0;
} else
return 1;
}
int
range_max (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float max = xs[0];
int i;
for (i = 1; i < n; i++)
if (xs[i] > max)
max = xs[i];
*res = max;
return 0;
} else
return 1;
}
/* Average absolute deviation from mean. */
int
range_avedev (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float m, s = 0;
int i;
range_average (xs, n, &m);
for (i = 0; i < n; i++)
s += fabs (xs[i] - m);
*res = s / n;
return 0;
} else
return 1;
}
/* Sum of square deviations from mean. */
int
range_devsq (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float m, dx, q = 0;
if (n > 0) {
int i;
range_average (xs, n, &m);
for (i = 0; i < n; i++) {
dx = xs[i] - m;
q += dx * dx;
}
}
*res = q;
return 0;
}
/* Variance with weight N. */
int
range_var_pop (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float q;
range_devsq (xs, n, &q);
*res = q / n;
return 0;
} else
return 1;
}
/* Variance with weight N-1. */
int
range_var_est (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 1) {
gnum_float q;
range_devsq (xs, n, &q);
*res = q / (n - 1);
return 0;
} else
return 1;
}
/* Standard deviation with weight N. */
int
range_stddev_pop (const gnum_float *xs, int n, gnum_float *res)
{
if (range_var_pop (xs, n, res))
return 1;
else {
*res = sqrt (*res);
return 0;
}
}
/* Standard deviation with weight N-1. */
int
range_stddev_est (const gnum_float *xs, int n, gnum_float *res)
{
if (range_var_est (xs, n, res))
return 1;
else {
*res = sqrt (*res);
return 0;
}
}
/* Population skew. */
int
range_skew_pop (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float m, s, dxn, x3 = 0;
int i;
if (n < 1 || range_average (xs, n, &m) || range_stddev_pop (xs, n, &s))
return 1;
if (s == 0)
return 1;
for (i = 0; i < n; i++) {
dxn = (xs[i] - m) / s;
x3 += dxn * dxn *dxn;
}
*res = x3 / n;
return 0;
}
/* Maximum-likelyhood estimator for skew. */
int
range_skew_est (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float m, s, dxn, x3 = 0;
int i;
if (n < 3 || range_average (xs, n, &m) || range_stddev_est (xs, n, &s))
return 1;
if (s == 0)
return 1;
for (i = 0; i < n; i++) {
dxn = (xs[i] - m) / s;
x3 += dxn * dxn *dxn;
}
*res = ((x3 * n) / (n - 1)) / (n - 2);
return 0;
}
/* Population kurtosis (with offset 3). */
int
range_kurtosis_m3_pop (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float m, s, dxn, x4 = 0;
int i;
if (n < 1 || range_average (xs, n, &m) || range_stddev_pop (xs, n, &s))
return 1;
if (s == 0)
return 1;
for (i = 0; i < n; i++) {
dxn = (xs[i] - m) / s;
x4 += (dxn * dxn) * (dxn * dxn);
}
*res = x4 / n - 3;
return 0;
}
/* Unbiased, I hope, estimator for kurtosis (with offset 3). */
int
range_kurtosis_m3_est (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float m, s, dxn, x4 = 0;
gnum_float common_den, nth, three;
int i;
if (n < 4 || range_average (xs, n, &m) || range_stddev_est (xs, n, &s))
return 1;
if (s == 0)
return 1;
for (i = 0; i < n; i++) {
dxn = (xs[i] - m) / s;
x4 += (dxn * dxn) * (dxn * dxn);
}
common_den = (gnum_float)(n - 2) * (n - 3);
nth = (gnum_float)n * (n + 1) / ((n - 1) * common_den);
three = 3.0 * (n - 1) * (n - 1) / common_den;
*res = x4 * nth - three;
return 0;
}
/* Harmonic mean of positive numbers. */
int
range_harmonic_mean (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float invsum = 0;
int i;
for (i = 0; i < n; i++) {
if (xs[i] <= 0)
return 1;
invsum += 1 / xs[i];
}
*res = n / invsum;
return 0;
} else
return 1;
}
/* Geometric mean of positive numbers. */
int
range_geometric_mean (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float product = 1;
int i;
/* FIXME: we should work harder at avoiding
overflow here. */
for (i = 0; i < n; i++) {
if (xs[i] <= 0)
return 1;
product *= xs[i];
}
*res = pow (product, 1.0 / n);
return 0;
} else
return 1;
}
/* Product. */
int
range_product (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float product = 1;
int i;
/* FIXME: we should work harder at avoiding overflow here. */
for (i = 0; i < n; i++) {
product *= xs[i];
}
*res = product;
return 0;
}
int
range_multinomial (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float result = 1;
int sum = 0;
int i;
for (i = 0; i < n; i++) {
gnum_float x = xs[i];
int xi;
if (x < 0)
return 1;
xi = (int)x;
if (sum == 0 || xi == 0)
; /* Nothing. */
else if (xi < 20) {
int j;
int f = sum + xi;
result *= f--;
for (j = 2; j <= xi; j++)
result = result * f-- / j;
} else {
/* Same as above, only faster. */
result *= combin (sum + xi, xi);
}
sum += xi;
}
*res = result;
return 0;
}
int
range_covar (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res)
{
gnum_float ux, uy, s = 0;
int i;
if (n <= 0 || range_average (xs, n, &ux) || range_average (ys, n, &uy))
return 1;
for (i = 0; i < n; i++)
s += (xs[i] - ux) * (ys[i] - uy);
*res = s / n;
return 0;
}
int
range_correl_pop (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res)
{
gnum_float sx, sy, vxy;
if (range_stddev_pop (xs, n, &sx) || sx == 0 ||
range_stddev_pop (ys, n, &sy) || sy == 0 ||
range_covar (xs, ys, n, &vxy))
return 1;
*res = vxy / (sx * sy);
return 0;
}
int
range_correl_est (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res)
{
gnum_float sx, sy, vxy;
if (range_stddev_est (xs, n, &sx) || sx == 0 ||
range_stddev_est (ys, n, &sy) || sy == 0 ||
range_covar (xs, ys, n, &vxy))
return 1;
*res = vxy / (sx * sy);
return 0;
}
int
range_rsq_pop (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res)
{
if (range_correl_pop (xs, ys, n, res))
return 1;
*res *= *res;
return 0;
}
int
range_rsq_est (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res)
{
if (range_correl_est (xs, ys, n, res))
return 1;
*res *= *res;
return 0;
}
double
pweibull (double x, double shape, double scale)
{
......
......@@ -38,36 +38,6 @@ double gnumeric_fake_ceil (double x);
double gnumeric_fake_round (double x);
double gnumeric_fake_trunc (double x);
int range_sum (const gnum_float *xs, int n, gnum_float *res);
int range_product (const gnum_float *xs, int n, gnum_float *res);
int range_multinomial (const gnum_float *xs, int n, gnum_float *res);
int range_sumsq (const gnum_float *xs, int n, gnum_float *res);
int range_avedev (const gnum_float *xs, int n, gnum_float *res);
int range_average (const gnum_float *xs, int n, gnum_float *res);
int range_harmonic_mean (const gnum_float *xs, int n, gnum_float *res);
int range_geometric_mean (const gnum_float *xs, int n, gnum_float *res);
int range_min (const gnum_float *xs, int n, gnum_float *res);
int range_max (const gnum_float *xs, int n, gnum_float *res);
int range_devsq (const gnum_float *xs, int n, gnum_float *res);
int range_var_pop (const gnum_float *xs, int n, gnum_float *res);
int range_var_est (const gnum_float *xs, int n, gnum_float *res);
int range_stddev_pop (const gnum_float *xs, int n, gnum_float *res);
int range_stddev_est (const gnum_float *xs, int n, gnum_float *res);
int range_skew_pop (const gnum_float *xs, int n, gnum_float *res);
int range_skew_est (const gnum_float *xs, int n, gnum_float *res);
int range_kurtosis_m3_pop (const gnum_float *xs, int n, gnum_float *res);
int range_kurtosis_m3_est (const gnum_float *xs, int n, gnum_float *res);
int range_covar (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res);
int range_correl_pop (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res);
int range_correl_est (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res);
int range_rsq_pop (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res);
int range_rsq_est (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res);
/* ------------------------------------------------------------------------- */
double bessel_i (double x, double alpha, double expo);
......@@ -137,15 +107,15 @@ double random_normal (void);
/* Matrix functions. */
gnum_float mdeterm (gnum_float *A, int dim);
int minverse(gnum_float *A, int dim, gnum_float *res);
void mmult (gnum_float *A, gnum_float *B, int cols_a, int rows_a, int cols_b,
gnum_float *product);
int minverse (gnum_float *A, int dim, gnum_float *res);
void mmult (gnum_float *A, gnum_float *B, int cols_a, int rows_a, int cols_b,
gnum_float *product);
/* ------------------------------------------------------------------------- */
/* Misc. */
gnum_float gpow10 (int n);
int gcd (int a, int b);
int gcd (int a, int b);
gnum_float combin (int n, int k);
gnum_float fact (int n);
......
/*
* rangefunc.c: Functions on ranges (data sets).
*
* Authors:
* Morten Welinder <terra@diku.dk>
* Andreas J. Guelzow <aguelzow@taliesin.ca>
*/
#include <config.h>
#include "rangefunc.h"
#include "mathfunc.h"
#include <math.h>
#include <stdlib.h>
#include <glib.h>
/* Arithmetic sum. */
int
range_sum (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += xs[i];
*res = sum;
return 0;
}
/* Arithmetic sum of squares. */
int
range_sumsq (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float sum = 0;
int i;
for (i = 0; i < n; i++)
sum += xs[i] * xs[i];
*res = sum;
return 0;
}
/* Arithmetic average. */
int
range_average (const gnum_float *xs, int n, gnum_float *res)
{
if (n <= 0 || range_sum (xs, n, res))
return 1;
*res /= n;
return 0;
}
int
range_min (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float min = xs[0];
int i;
for (i = 1; i < n; i++)
if (xs[i] < min)
min = xs[i];
*res = min;
return 0;
} else
return 1;
}
int
range_max (const gnum_float *xs, int n, gnum_float *res)
{
if (n > 0) {
gnum_float max = xs[0];
int i;
for (i = 1; i < n; i++)
if (xs[i] > max)
max = xs[i];
*res = max;
return 0;
} else
return 1;
}
/* Average absolute deviation from mean. */
int
range_avedev (const gnum_float *xs, int n, gnum_float *res)
{