-
-
Save svdamani/1015c5c4b673c3297309 to your computer and use it in GitHub Desktop.
/** Numerical Analysis 9th ed - Burden, Faires (Ch. 3 Natural Cubic Spline, Pg. 149) */ | |
#include <stdio.h> | |
int main() { | |
/** Step 0 */ | |
int n, i, j; | |
scanf("%d", &n); | |
n--; | |
float x[n + 1], a[n + 1], h[n], A[n], l[n + 1], | |
u[n + 1], z[n + 1], c[n + 1], b[n], d[n]; | |
for (i = 0; i < n + 1; ++i) scanf("%f", &x[i]); | |
for (i = 0; i < n + 1; ++i) scanf("%f", &a[i]); | |
/** Step 1 */ | |
for (i = 0; i <= n - 1; ++i) h[i] = x[i + 1] - x[i]; | |
/** Step 2 */ | |
for (i = 1; i <= n - 1; ++i) | |
A[i] = 3 * (a[i + 1] - a[i]) / h[i] - 3 * (a[i] - a[i - 1]) / h[i - 1]; | |
/** Step 3 */ | |
l[0] = 1; | |
u[0] = 0; | |
z[0] = 0; | |
/** Step 4 */ | |
for (i = 1; i <= n - 1; ++i) { | |
l[i] = 2 * (x[i + 1] - x[i - 1]) - h[i - 1] * u[i - 1]; | |
u[i] = h[i] / l[i]; | |
z[i] = (A[i] - h[i - 1] * z[i - 1]) / l[i]; | |
} | |
/** Step 5 */ | |
l[n] = 1; | |
z[n] = 0; | |
c[n] = 0; | |
/** Step 6 */ | |
for (j = n - 1; j >= 0; --j) { | |
c[j] = z[j] - u[j] * c[j + 1]; | |
b[j] = (a[j + 1] - a[j]) / h[j] - h[j] * (c[j + 1] + 2 * c[j]) / 3; | |
d[j] = (c[j + 1] - c[j]) / (3 * h[j]); | |
} | |
/** Step 7 */ | |
printf("%2s %8s %8s %8s %8s\n", "i", "ai", "bi", "ci", "di"); | |
for (i = 0; i < n; ++i) | |
printf("%2d %8.2f %8.2f %8.2f %8.2f\n", i, a[i], b[i], c[i], d[i]); | |
return 0; | |
} |
Thanks a lot for the code,
I modified it so that it can interpolate an array of 'n' values to an array of 'x' values.
#include <stdio.h>
#define CURRENT_NUMBER_OF_POINTS 40
#define NUMBER_INTERPOLATED_POINTS 2000
int main() {
/** Step 0 */
int n=CURRENT_NUMBER_OF_POINTS, i, j;
n--;
float x[n + 1], a[n + 1], h[n], A[n], l[n + 1],
u[n + 1], z[n + 1], c[n + 1], b[n], d[n];
printf("enter values of points\n");
for (i = 0; i < n + 1; ++i) scanf("%f", &a[i]);
for (i = 0; i < n + 1; ++i) x[i]=i;
/** Step 1 */
for (i = 0; i <= n - 1; ++i) h[i] = x[i + 1] - x[i];
/** Step 2 */
for (i = 1; i <= n - 1; ++i)
A[i] = 3 * (a[i + 1] - a[i]) / h[i] - 3 * (a[i] - a[i - 1]) / h[i - 1];
/** Step 3 */
l[0] = 1;
u[0] = 0;
z[0] = 0;
/** Step 4 */
for (i = 1; i <= n - 1; ++i) {
l[i] = 2 * (x[i + 1] - x[i-1]) - h[i - 1] * u[i - 1];
u[i] = h[i] / l[i];
z[i] = (A[i] - h[i - 1] * z[i - 1]) / l[i];
}
/** Step 5 */
l[n] = 1;
z[n] = 0;
c[n] = 0;
/** Step 6 */
for (j = n - 1; j >= 0; --j) {
c[j] = z[j] - u[j] * c[j + 1];
b[j] = (a[j + 1] - a[j]) / h[j] - h[j] * (c[j + 1] + 2 * c[j]) / 3;
d[j] = (c[j + 1] - c[j]) / (3 * h[j]);
}
/** Step 7 */
float interpolated_x[NUMBER_INTERPOLATED_POINTS];
/* Evaluate cubic spline equation at interpolated x values*/
for (i = 0; i < NUMBER_INTERPOLATED_POINTS; ++i) {
float x_val = (float)i * n / (float)(NUMBER_INTERPOLATED_POINTS - 1);
int j = (int)x_val;
float dx = x_val - j;
interpolated_x[i] = a[j] + b[j]dx + c[j]dxdx + d[j]dxdxdx;
}
for (int i = 0; i < NUMBER_INTERPOLATED_POINTS; i++) {
printf( "%d == %f \n", i,interpolated_x[i]);
}
return 0;
}
Hey so im making a hyper specific library for matlab, to use in a project, is it fine if i use this? and if i do then how should i credit you?
after testing it a bunch, if you want to use the values in a polynomial to find out querry points, a , b , c and d are in the reverse order,
i compared it to here : https://www.bragitoff.com/2018/02/cubic-spline-piecewise-interpolation-c-program/?unapproved=60552&moderation-hash=d514da745560ff352ee385453b9346e1#comment-60552
Hey so im making a hyper specific library for matlab, to use in a project, is it fine if i use this? and if i do then how should i credit you?
@Pin09091 yes of course. Feel free to use it, mention link to the gist of my name. I'm glad this code is useful for you
Thanks @ivanfe639 and @ekalkan, corrected the code in 28th line and updated the book link.