#include <stdio.h>
#include <stdlib.h>
#define N 6
double
* pointsToIntervalsN(
int
n,
const
double
* x,
double
* e)
{
if
(n < 2 || !x || e < x && e + n >= x)
return
NULL;
if
(e
|| (e
= (
double
*)
malloc
(
(n + 1) *
sizeof
(
double
)))) {
const
int
m = n & 1 ? n : 2;
const
int
j = m * n;
register
double
sum = 0.;
for
(
int
i = m / 2; i < j; i += m) {
sum = i * *x++ - sum;
}
sum /= j / 2;
for
(e[n] = sum; n--; e[n] = sum)
sum = 2 * *--x - sum;
}
return
e;
}
double
* pointsToIntervals0(
const
int
n,
const
double
* x,
double
* e)
{
if
(n < 2 || !x || e >= x && e < x + n)
return
NULL;
if
(e
|| (e
= (
double
*)
malloc
(
(n + 1) *
sizeof
(
double
)))) {
const
int
m = n & 1 ? n : 2;
const
int
j = m * n;
register
double
sum = 0.;
x += n;
for
(
int
i = m / 2; i < j;
i += m) {
sum = i * *--x - sum;
}
sum /= j / 2;
*e = sum;
for
(
int
i = 0; i < n;
e[++i] = sum)
sum = 2 * x[i] - sum;
}
return
e;
}
double
* pointsToIntervalsFix(
const
int
n,
const
double
* x,
double
e_base,
double
* e)
{
if
(n < 1 || !x)
return
NULL;
int
k = 0;
for
(
int
l = n; l > 1; l /= 2)
if
(e_base > x[k + l / 2])
k += (l + 1) / 2;
if
(e_base > x[k])
++k;
if
(e + k >= x && e < x + n)
return
NULL;
if
(e || (e = (
double
*)
malloc
(
(n + 1) *
sizeof
(
double
)))) {
e[k] = e_base;
for
(
int
i = k; i--; e[i] = e_base)
e_base = 2 * x[i] - e_base;
for
(e_base = e[k]; k < n;
e[++k] = e_base)
e_base = 2 * x[k] - e_base;
}
return
e;
}
int
main()
{
double
e_orig[N + 1]
= { 4, 37, 121, 200, 234, 300, 365 };
double
x[N], e_recN[N + 1], e_rec0[N + 1];
double
e_base = 235.4, e_fix[N + 1];
for
(
int
i = N; i--;
x[i] = (e_orig[i + 1] + e_orig[i]) / 2)
;
pointsToIntervalsN(N, x, e_recN);
pointsToIntervals0(N, x, e_rec0);
pointsToIntervalsFix(N, x, e_base, e_fix);
printf
(
"Example for n = %d:"
, N);
printf
(
"\nx "
);
for
(
int
i = 0; i < N; ++i)
printf
(
"% .3f"
, x[i]);
printf
(
"\ne_orig "
);
for
(
int
i = 0; i <= N; ++i)
printf
(
"% .3f"
, e_orig[i]);
printf
(
"\ne_recN "
);
for
(
int
i = 0; i <= N; ++i)
printf
(
"% .3f"
, e_recN[i]);
printf
(
"\ne_rec0 "
);
for
(
int
i = 0; i <= N; ++i)
printf
(
"% .3f"
, e_rec0[i]);
printf
(
"\ne_fix "
);
for
(
int
i = 0; i <= N; ++i)
printf
(
"% .3f"
, e_fix[i]);
return
0;
}