Commit f2e23f29 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder
Browse files

Change to multi-dimensional regression. (Too bad linear_solve does not

1999-09-23  Morten Welinder  <terra@diku.dk>

	* src/regression.c (linear_regression, exponential_regression):
 	Change to multi-dimensional regression.  (Too bad linear_solve
 	does not handle it yet.)  All callers changed.
parent dee361e3
1999-09-23 Morten Welinder <terra@diku.dk>
* src/regression.c (linear_regression, exponential_regression):
Change to multi-dimensional regression. (Too bad linear_solve
does not handle it yet.) All callers changed.
* src/widgets/widget-color-combo.c (color_clicked): Plug leak.
(color_combo_select_color): Plug leak.
(emit_change): Plug leak.
......
1999-09-23 Morten Welinder <terra@diku.dk>
* src/regression.c (linear_regression, exponential_regression):
Change to multi-dimensional regression. (Too bad linear_solve
does not handle it yet.) All callers changed.
* src/widgets/widget-color-combo.c (color_clicked): Plug leak.
(color_combo_select_color): Plug leak.
(emit_change): Plug leak.
......
......@@ -3865,13 +3865,14 @@ gnumeric_linest (FunctionEvalInfo *ei, Value *argv [])
} else
stat = TRUE;
if (linear_regression (xs, ys, nx, affine, linres)) {
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (linear_regression (&xs, dim, ys, nx, affine, linres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (stat) {
int y, x;
result = value_new_array (dim + 1, 5);
......@@ -3922,7 +3923,7 @@ gnumeric_trend (FunctionEvalInfo *ei, Value *argv [])
{
float_t *xs = NULL, *ys = NULL, *nxs = NULL;
Value *result = NULL;
int nx, ny, nnx, i;
int nx, ny, nnx, i, dim;
float_t linres[2];
ys = collect_floats_value (argv[0], &ei->pos,
......@@ -3961,7 +3962,9 @@ gnumeric_trend (FunctionEvalInfo *ei, Value *argv [])
goto out;
}
if (linear_regression (xs, ys, nx, 1, linres)) {
dim = 1;
if (linear_regression (&xs, dim, ys, nx, 1, linres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
......@@ -4057,13 +4060,14 @@ gnumeric_logest (FunctionEvalInfo *ei, Value *argv [])
} else
stat = TRUE;
if (exponential_regression (xs, ys, nx, affine, expres)) {
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (exponential_regression (&xs, dim, ys, nx, affine, expres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (stat) {
int y, x;
result = value_new_array (dim + 1, 5);
......@@ -4147,7 +4151,7 @@ gnumeric_forecast (FunctionEvalInfo *ei, Value *argv [])
{
float_t x, *xs = NULL, *ys = NULL;
Value *result = NULL;
int nx, ny;
int nx, ny, dim;
float_t linres[2];
x = value_get_as_float (argv[0]);
......@@ -4171,7 +4175,9 @@ gnumeric_forecast (FunctionEvalInfo *ei, Value *argv [])
goto out;
}
if (linear_regression (xs, ys, nx, 1, linres)) {
dim = 1;
if (linear_regression (&xs, dim, ys, nx, 1, linres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
......@@ -4213,8 +4219,9 @@ static int
range_intercept (const float_t *xs, const float_t *ys, int n, float_t *res)
{
float_t linres[2];
int dim = 1;
if (linear_regression (xs, ys, n, 1, linres))
if (linear_regression ((float_t **)&xs, dim, ys, n, 1, linres))
return 1;
*res = linres[0];
......@@ -4255,8 +4262,9 @@ static int
range_slope (const float_t *xs, const float_t *ys, int n, float_t *res)
{
float_t linres[2];
int dim = 1;
if (linear_regression (xs, ys, n, 1, linres))
if (linear_regression ((float_t **)&xs, dim, ys, n, 1, linres))
return 1;
*res = linres[1];
......
......@@ -3865,13 +3865,14 @@ gnumeric_linest (FunctionEvalInfo *ei, Value *argv [])
} else
stat = TRUE;
if (linear_regression (xs, ys, nx, affine, linres)) {
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (linear_regression (&xs, dim, ys, nx, affine, linres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (stat) {
int y, x;
result = value_new_array (dim + 1, 5);
......@@ -3922,7 +3923,7 @@ gnumeric_trend (FunctionEvalInfo *ei, Value *argv [])
{
float_t *xs = NULL, *ys = NULL, *nxs = NULL;
Value *result = NULL;
int nx, ny, nnx, i;
int nx, ny, nnx, i, dim;
float_t linres[2];
ys = collect_floats_value (argv[0], &ei->pos,
......@@ -3961,7 +3962,9 @@ gnumeric_trend (FunctionEvalInfo *ei, Value *argv [])
goto out;
}
if (linear_regression (xs, ys, nx, 1, linres)) {
dim = 1;
if (linear_regression (&xs, dim, ys, nx, 1, linres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
......@@ -4057,13 +4060,14 @@ gnumeric_logest (FunctionEvalInfo *ei, Value *argv [])
} else
stat = TRUE;
if (exponential_regression (xs, ys, nx, affine, expres)) {
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (exponential_regression (&xs, dim, ys, nx, affine, expres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
/* FIXME: we should handle multi-dimensional data, but we do not. */
dim = 1;
if (stat) {
int y, x;
result = value_new_array (dim + 1, 5);
......@@ -4147,7 +4151,7 @@ gnumeric_forecast (FunctionEvalInfo *ei, Value *argv [])
{
float_t x, *xs = NULL, *ys = NULL;
Value *result = NULL;
int nx, ny;
int nx, ny, dim;
float_t linres[2];
x = value_get_as_float (argv[0]);
......@@ -4171,7 +4175,9 @@ gnumeric_forecast (FunctionEvalInfo *ei, Value *argv [])
goto out;
}
if (linear_regression (xs, ys, nx, 1, linres)) {
dim = 1;
if (linear_regression (&xs, dim, ys, nx, 1, linres)) {
result = value_new_error (&ei->pos, gnumeric_err_NUM);
goto out;
}
......@@ -4213,8 +4219,9 @@ static int
range_intercept (const float_t *xs, const float_t *ys, int n, float_t *res)
{
float_t linres[2];
int dim = 1;
if (linear_regression (xs, ys, n, 1, linres))
if (linear_regression ((float_t **)&xs, dim, ys, n, 1, linres))
return 1;
*res = linres[0];
......@@ -4255,8 +4262,9 @@ static int
range_slope (const float_t *xs, const float_t *ys, int n, float_t *res)
{
float_t linres[2];
int dim = 1;
if (linear_regression (xs, ys, n, 1, linres))
if (linear_regression ((float_t **)&xs, dim, ys, n, 1, linres))
return 1;
*res = linres[1];
......
......@@ -48,7 +48,7 @@ linear_solve (float_t **A, float_t *b, int n,
/* ------------------------------------------------------------------------- */
static int
general_linear_regression (const float_t *const *xss, int xdim,
general_linear_regression (float_t **xss, int xdim,
const float_t *ys, int n,
float_t *res)
{
......@@ -117,35 +117,41 @@ general_linear_regression (const float_t *const *xss, int xdim,
/* Please refer to description in regression.h. */
int
linear_regression (const float_t *xs, const float_t *ys, int n,
linear_regression (float_t **xss, int dim,
const float_t *ys, int n,
int affine,
float_t *res)
{
if (affine) {
const float_t *xss[2];
int result;
xss[0] = NULL; /* Substitute for 1-vector. */
xss[1] = xs;
if (affine) {
float_t **xss2;
xss2 = g_new (float_t *, dim + 1);
xss2[0] = NULL; /* Substitute for 1-vector. */
memcpy (xss2 + 1, xss, dim * sizeof (float_t *));
return general_linear_regression (xss, 2, ys, n, res);
result = general_linear_regression (xss2, dim + 1, ys, n, res);
g_free (xss2);
} else {
res[0] = 0;
return general_linear_regression (&xs, 1, ys, n, res + 1);
result = general_linear_regression (xss, dim, ys, n, res + 1);
}
return result;
}
/* ------------------------------------------------------------------------- */
/* Please refer to description in regression.h. */
int
exponential_regression (const float_t *xs, const float_t *ys, int n,
exponential_regression (float_t **xss, int dim,
const float_t *ys, int n,
int affine,
float_t *res)
{
float_t *log_ys;
int result;
int i;
int dim = 1;
log_ys = g_new (float_t, n);
for (i = 0; i < n; i++)
......@@ -157,15 +163,16 @@ exponential_regression (const float_t *xs, const float_t *ys, int n,
}
if (affine) {
const float_t *xss[dim + 1];
xss[0] = NULL; /* Substitute for 1-vector. */
xss[1] = xs;
float_t **xss2;
xss2 = g_new (float_t *, dim + 1);
xss2[0] = NULL; /* Substitute for 1-vector. */
memcpy (xss2 + 1, xss, dim * sizeof (float_t *));
result = general_linear_regression (xss, dim + 1, log_ys, n, res);
result = general_linear_regression (xss2, dim + 1, log_ys, n, res);
g_free (xss2);
} else {
res[0] = 0;
result = general_linear_regression (&xs, dim, log_ys, n, res + 1);
result = general_linear_regression (xss, dim, log_ys, n, res + 1);
}
if (result == 0)
......
......@@ -5,40 +5,47 @@
/**
* linear_regression:
* @xs: x-vector. (Ie., independent data.)
* @xss: x-vectors. (Ie., independent data.)
* @dim: number of x-vectors.
* @ys: y-vector. (Dependent data.)
* @n: number of data points.
* @affine: if true, a non-zero constant is allowed.
* @res: output place for constant[0] and slope[1].
* @res: output place for constant[0] and slope1[1], slope2[2], ...
* There will be dim+1 results.
*
* This performs one-dimensional linear regressions on the input points.
* Fits to "y = ax + b".
* This performs multi-dimensional linear regressions on the input points.
* Fits to "y = b + a1 * x1 + ... ad * xd".
*
* Returns 0 for ok, non-zero otherwise. (Errors: less than two points,
* all points on a vertical line.)
*/
int linear_regression (const float_t *xs, const float_t *ys, int n,
int linear_regression (float_t **xss, int dim,
const float_t *ys, int n,
int affine,
float_t *res);
/**
* exponential_regression:
* @xs: x-vector. (Ie., independent data.)
* @xss: x-vectors. (Ie., independent data.)
* @dim: number of x-vectors.
* @ys: y-vector. (Dependent data.)
* @n: number of data points.
* @affine: if true, a non-one multiplier is allowed.
* @res: output place for constant[0] and root[1].
* @res: output place for constant[0] and root1[1], root2[2], ...
* There will be dim+1 results.
*
* This performs one-dimensional linear regressions on the input points.
* Fits to "y = b * m^x" or equivalently to "log y = log b + x * log m".
* Fits to "y = b * m1^x1 * ... * md^xd " or equivalently to
* "log y = log b + x1 * log m1 + ... + xd * log md".
*
* Returns 0 for ok, non-zero otherwise. (Errors: less than two points,
* all points on a vertical line, non-positive y data.)
*/
int exponential_regression (const float_t *xs, const float_t *ys, int n,
int exponential_regression (float_t **xss, int dim,
const float_t *ys, int n,
int affine,
float_t *res);
......
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