goffice r2271 - in trunk: . goffice/math
- From: jbrefort svn gnome org
- To: svn-commits-list gnome org
- Subject: goffice r2271 - in trunk: . goffice/math
- Date: Mon, 10 Nov 2008 15:11:10 +0000 (UTC)
Author: jbrefort
Date: Mon Nov 10 15:11:10 2008
New Revision: 2271
URL: http://svn.gnome.org/viewvc/goffice?rev=2271&view=rev
Log:
2008-11-10 Jean Brefort <jean brefort normalesup org>
* goffice/math/go-cspline.c: (go_cspline_init): fixed evaluation for
cubic and clamped limits.
Modified:
trunk/ChangeLog
trunk/goffice/math/go-cspline.c
Modified: trunk/goffice/math/go-cspline.c
==============================================================================
--- trunk/goffice/math/go-cspline.c (original)
+++ trunk/goffice/math/go-cspline.c Mon Nov 10 15:11:10 2008
@@ -48,26 +48,35 @@
#endif
-/*
-Creates a spline structure, and computes the coefficients associated with the
-polynoms.
-Arguments are:
-x: the given abscissas, theymust be given in increasing order
-y: the given ordinates
-n: the number of valid (x, y) pairs
-limits: how the limits must be treated, four values are allowed:
- GO_CSPLINE_NATURAL: first and least second derivatives are 0.
- GO_CSPLINE_PARABOLIC: the curve will be a parabole arc outside of the limits.
- GO_CSPLINE_CUBIC: the curve will be cubic outside of the limits.
- GO_CSPLINE_CLAMPED: the first and last derivatives are imposed.
-c0, cn: the first and last derivatives when using clamped splines, not used in the
-other limit types.
-*/
+/**
+ * go_cspline_init:
+ * @x: the x values
+ * @y: the y values
+ * @n: the number of x and y values
+ * @limits: how the limits must be treated, four values are allowed:
+ * GO_CSPLINE_NATURAL: first and least second derivatives are 0.
+ * GO_CSPLINE_PARABOLIC: the curve will be a parabole arc outside of the limits.
+ * GO_CSPLINE_CUBIC: the curve will be cubic outside of the limits.
+ * GO_CSPLINE_CLAMPED: the first and last derivatives are imposed.
+ * @c0: the first derivative when using clamped splines, not used in the
+ * other limit types.
+ * @cn: the first derivative when using clamped splines, not used in the
+ * other limit types.
+ *
+ * Creates a spline structure, and computes the coefficients associated with the
+ * polynoms. The ith polynome (between x[i-1] and x[i] is:
+ * y(x) = y[i-1] + (c[i-1] + (b[i-1] + a[i] * (x - x[i-1])) * (x - x[i-1])) * (x - x[i-1])
+ * where a[i-1], b[i-1], c[i-1], x[i-1] and y[i-1] are the corresponding
+ * members of the new structure.
+ *
+ * Returns: a newly created struct GOCSpline instance which should be
+ * destroyed by a call to go_bezier_spline_destroy.
+ */
struct SUFFIX(GOCSpline) *
SUFFIX(go_cspline_init) (DOUBLE const *x, DOUBLE const *y, int n,
unsigned limits, DOUBLE c0, DOUBLE cn)
{
- DOUBLE *d1, *d2, *d3, *d4, *s, *h;
+ DOUBLE *d1, *d2, *d3, *d4, h;
struct SUFFIX(GOCSpline) *sp;
double dx1 = 0., dy1 = 0., dx2 = 0., dy2 = 0., dxn1 = 0., dxn2 = 0.;
int nm1, nm2, i, j, first, last;
@@ -83,21 +92,18 @@
sp->a = (DOUBLE*) g_new0 (DOUBLE, nm1);
sp->b = (DOUBLE*) g_new (DOUBLE, nm1);
sp->c = (DOUBLE*) g_new (DOUBLE, nm1);
- i = n + 1;
- d1 = (DOUBLE*) g_new0 (DOUBLE, i);
- d2 = (DOUBLE*) g_new0 (DOUBLE, i);
- d3 = (DOUBLE*) g_new0 (DOUBLE, i);
- d4 = (DOUBLE*) g_new0 (DOUBLE, i);
- s = (DOUBLE*) g_new0 (DOUBLE, i);
- h = (DOUBLE*) g_new0 (DOUBLE, i);
+ d1 = (DOUBLE*) g_new0 (DOUBLE, n);
+ d2 = (DOUBLE*) g_new0 (DOUBLE, n);
+ d3 = (DOUBLE*) g_new0 (DOUBLE, n);
+ d4 = (DOUBLE*) g_new0 (DOUBLE, n);
/* --- COMPUTE FOR N-2 ROWS --- */
nm2 = n - 2;
dx1 = x[1] - x[0];
- dy1 = (y[1] - y[0]) / dx1 * 6.0;
+ dy1 = (y[1] - y[0]) / dx1 * 3.0;
for ( i = 1; i <= nm2; ++i ) {
dx2 = x[i + 1] - x[i];
- dy2 = (y[i + 1] - y[i]) / dx2 * 6.0;
+ dy2 = (y[i + 1] - y[i]) / dx2 * 3.0;
d1[i] = dx1;
d2[i] = 2.0 * (dx1 + dx2);
d3[i] = dx2;
@@ -129,18 +135,16 @@
case GO_CSPLINE_CLAMPED : /* Derivative end conditions */
dx1 = x[1] - x[0];
dy1 = (y[1] - y[0]) / dx1;
- s[0] = c0;
- s[nm1] = cn;
- d1[0] = 2.0 * dx1;
- d2[0] = dx1;
- d3[0] = 0.0;
- d4[0] = (dy1 - s[1]) * 6;
+ d1[0] = 0.0;
+ d2[0] = 2.0 * dx1;
+ d3[0] = dx1;
+ d4[0] = (dy1 - c0) * 3.0;
dx1 = x[nm1] - x[nm2];
dy1 = (y[nm1] - y[nm2]) / dx1;
d1[nm1] = dx1;
d2[nm1] = 2.0 * dx1;
d3[nm1] = 0.0;
- d4[nm1] = (s[n] - dy1) * 6.0;
+ d4[nm1] = (cn - dy1) * 3.0;
first = 1; last = n-1;
break;
}
@@ -157,23 +161,19 @@
for (j = last - 1; j >= first - 1; --j )
d4[j] = (d4[j] - d3[j] * d4[j + 1]) / d2[j];
- /* --- NOW PUT THE VALUES INTO THE S VECTOR --- */
- for ( i = first - 1; i <= last; ++i )
- s[i] = d4[i];
-
/* --- TAKE CARE OF SPECIAL END CONDITIONS FOR S VECTOR --- */
switch (limits) {
case GO_CSPLINE_NATURAL :
- s[0] = 0.0;
- s[nm1] = 0.0;
+ d4[0] = 0.0;
+ d4[nm1] = 0.0;
break;
case GO_CSPLINE_PARABOLIC :
- s[0] = s[1];
- s[nm1] = s[nm2];
+ d4[0] = d4[1];
+ d4[nm1] = d4[nm2];
break;
case GO_CSPLINE_CUBIC :
- s[0] = ((dx1 + dx2) * s[1] - dx1 * s[2]) / dx2;
- s[nm1] = ((dx2 + dxn1) * s[nm2] - dxn1 * s[nm2 - 1]) / dx2;
+ d4[0] = ((dx1 + dx2) * d4[1] - dx1 * d4[2]) / dx2;
+ d4[nm1] = ((dxn2 + dxn1) * d4[nm2] - dxn1 * d4[nm2 - 1]) / dxn2;
break;
case GO_CSPLINE_CLAMPED : /* already taken care of */;
break;
@@ -181,25 +181,26 @@
/* --- GENERATE THE COEFFICIENTS OF THE POLYNOMIALS --- */
for ( i = 0; i < nm1; ++i ) {
- h[i] = x[i+1] - x[i];
- sp->a[i] = (s[i + 1] - s[i]) / (6.0 * h[i]);
- sp->b[i] = s[i] / 2.0;
- sp->c[i] = ((y[i + 1] - y[i]) / h[i]) -
- ((2.0* h[i] * s[i] + h[i] * s[i + 1]) / 6.0);
+ h = x[i+1] - x[i];
+ sp->a[i] = (d4[i + 1] - d4[i]) / (3.0 * h);
+ sp->b[i] = d4[i];
+ sp->c[i] = ((y[i + 1] - y[i]) / h) -
+ ((2.0 * d4[i] + d4[i + 1]) * h / 3.0);
}
g_free (d1);
g_free (d2);
g_free (d3);
g_free (d4);
- g_free (s);
- g_free (h);
return sp;
}
-/*
- Frees the spline structure when done.
-*/
+/**
+ * go_cspline_destroy:
+ * @sp: a spline structure returned by go_cspline_init.
+ *
+ * Frees the spline structure when done.
+ */
void SUFFIX(go_cspline_destroy) (struct SUFFIX(GOCSpline) *sp)
{
g_return_if_fail (sp);
@@ -209,10 +210,14 @@
g_free (sp);
}
-/*
-Returns the interpolated value for x.
-sp must be a spine structure as returned by SUFFIX(go_cspline_init)
-*/
+/**
+ * go_cspline_get_value:
+ * @sp: a spline structure returned by go_cspline_init.
+ *
+ * sp must be a valid spline structure as returned by go_cspline_init.
+ *
+ * Returns: the interpolated value for x, or 0 if an error occurred.
+ */
DOUBLE SUFFIX(go_cspline_get_value) (struct SUFFIX(GOCSpline) *sp, DOUBLE x)
{
DOUBLE dx;
@@ -242,10 +247,14 @@
return sp->y[j] + dx * (sp->c[j] + dx * (sp->b[j] + dx * sp->a[j]));
}
-/*
-Returns the interpolated derivative at x.
-sp must be a spine structure as returned by SUFFIX(go_cspline_init)
-*/
+/**
+ * go_cspline_get_deriv:
+ * @sp: a spline structure returned by go_cspline_init.
+ *
+ * sp must be a valid spline structure as returned by go_cspline_init.
+ *
+ * Returns: the interpolated derivative at x, or 0 if an error occurred.
+ */
DOUBLE SUFFIX(go_cspline_get_deriv) (struct SUFFIX(GOCSpline) *sp, DOUBLE x)
{
DOUBLE dx;
@@ -275,11 +284,19 @@
return sp->c[j] + dx * (2 * sp->b[j] + dx * 3 * sp->a[j]);
}
-/*
-Returns an array of the n interpolated values at the n values stored in x.
-The x values must be in increasing order.
-sp must be a spine structure as returned by SUFFIX(go_cspline_init)
-*/
+/**
+ * go_cspline_get_values:
+ * @sp: a spline structure returned by go_cspline_init.
+ * @x: a vector a values at which interpolation is requested.
+ * @n: the number of interpolation requested.
+ *
+ * sp must be a valid spline structure as returned by go_cspline_init.
+ * The x values must be sorted in increasing order.
+ *
+ * Returns: a newly allocated array of interpolated values which should
+ * be destroyed by a call to g_free when not anymore needed, or NULL if
+ * an error occurred.
+ */
DOUBLE *SUFFIX(go_cspline_get_values) (struct SUFFIX(GOCSpline) *sp, DOUBLE const *x, int n)
{
DOUBLE *res, dx;
@@ -301,11 +318,19 @@
return res;
}
-/*
-Returns an array of the n interpolated derivatives at the n values stored in x.
-The x values must be in increasing order.
-sp must be a spine structure as returned by SUFFIX(go_cspline_init)
-*/
+/**
+ * go_cspline_get_derivs:
+ * @sp: a spline structure returned by go_cspline_init.
+ * @x: a vector a values at which interpolation is requested.
+ * @n: the number of interpolation requested.
+ *
+ * sp must be a valid spline structure as returned by go_cspline_init.
+ * The x values must be sorted in increasing order.
+ *
+ * Returns: a newly allocated array of the n interpolated derivatives which
+ * should be destroyed by a call to g_free when not anymore needed, or NULL if
+ * an error occurred.
+ */
DOUBLE *SUFFIX(go_cspline_get_derivs) (struct SUFFIX(GOCSpline) *sp, DOUBLE const *x, int n)
{
DOUBLE *res, dx;
@@ -327,12 +352,19 @@
return res;
}
-/*
-Returns an array of the n-1 integrals on the intervals between two consecutive
-values stored in x.
-The x values must be in increasing order.
-sp must be a spine structure as returned by SUFFIX(go_cspline_init)
-*/
+/**
+ * go_cspline_get_integrals:
+ * @sp: a spline structure returned by go_cspline_init.
+ * @x: a vector a values at which interpolation is requested.
+ * @n: the number of interpolation requested.
+ *
+ * sp must be a valid spline structure as returned by go_cspline_init.
+ * The x values must be sorted in increasing order.
+ *
+ * Returns: a newly allocated array of the n-1 integrals on the intervals
+ * between two consecutive values stored in x. which should be destroyed by
+ * a call to g_free when not anymore needed, or NULL if an error occurred.
+ */
DOUBLE *SUFFIX(go_cspline_get_integrals) (struct SUFFIX(GOCSpline) *sp, DOUBLE const *x, int n)
{
DOUBLE *res, start, end, sum;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]