# Calculate the Lagrange polynomial

I had to write a program to calculate the Lagrange polynomial of the maddening degree of function: $\log(x+1)+\cos(x-1)$

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

/* Funzione per costruire la successione dei nodi (xi,yi) dei punti di valutazione*/
void nodeSuccession(double* xNode, double* yNode, double* xVal){
int i;

printf("xNode [");
for(i = 0; i < GRADE + 1; i++){
xNode[i] = i; /* Array contenete le ascisse dei nodi */
printf("%.4f, ", xNode[i]);
yNode[i] = 0; /* Array contenete le ordinate dei nodi */
}
printf("\b\b]\n");

printf("yNode [");
for(i = 0; i < GRADE + 1; i++){
yNode[i] = (log(xNode[i] + 1)) + cos(xNode[i] - 1);
printf("%.4f, ", yNode[i]);
}
printf("\b\b]\n");

printf("xVal  [");
for(i = 0; i < GRADE; i++){
xVal[i] = (xNode[i] + xNode[i+1]) / 2;
printf("%.4f, ", xVal[i]);
}
printf("\b\b]\n");

}
/* Funzione per costruire il polinomio di lagrange e lo valuto nei punti */
double* polynomial(double *xVal, double *xNode, double *yNode){
int i, j, k;
double pr, *sum = malloc(GRADE * sizeof(double));

for(j = 0; j < GRADE; j++){
sum[j] = 0;
for(k = 0; k < GRADE + 1; k++){
pr = 1;
for(i = 0; i < GRADE + 1; i++){
if(k != i)
pr = pr * ((xVal[j] - xNode[i])/(xNode[k] - xNode[i]));
}
sum[j] = sum[j] + yNode[k] * pr;
}
}

return sum;
}

/* Funzione per la valutazione dell'errore di interpolazione */
double* error(double *xVal, double *sum){

int i;
double *err = malloc(GRADE * sizeof(double));

for(i = 0; i < GRADE; i++)
err[i] = fabs(((log(xVal[i] + 1)) + cos(xVal[i] - 1)) - sum[i]);

return err;
}

int main(void){
int i;

system("clear");
printf("\n===== PROGRAMMA PER IL CALCOLO DEL POLINOMIO DI LAGRANGE =====\n\n");

nodeSuccession(xNode, yNode, xVal);
poly = polynomial(xVal, xNode, yNode);

printf("\npoly  [");
for(i = 0; i < GRADE; i++)
printf("%.4f, ", poly[i]);
printf("\b\b]\n");

err = error(xVal, poly);
printf("err   [");
for(i = 0; i < GRADE; i++)
printf("%.4f, ", err[i]);
printf("\b\b]\n");

free(poly);
free(err);

return 0;
}

• im confused for why you are mallocing doubles when there is no need for it Sep 7, 2017 at 21:53

1. Consider passing in the array size rather than fixing it at 6 in the polynomial(), nodeSuccession() functions.

// polynomial(xVal, xNode, yNode)
polynomial(6, xVal, xNode, yNode)


Minor stuff

1. Two backspaces may not truly "back-space". Less problematic to not print unwanted text. Various solutions. Perhaps as below.

const char *separator = "";
printf("xNode [");
for (i = 0; i < GRADE + 1; i++) {
xNode[i] = i;
printf("%s%.4f", separator, xNode[i]);
yNode[i] = 0;
separator = ", ";
}
printf("\n");

2. The various calls to like code suggest that a helper print function should be written.

3. For printing double, I find %e more informative than %f.

4. Rather than allocate to the size of the type, allocate to the size of the de-referenced pointer. It easier to code correctly, review and maintain. Putting the sizeof part first insures any integer math is done with at least size_t width. Checking for a NULL allocation makes for robust code.

// sum = malloc(GRADE * sizeof(double));
sum = malloc(sizeof *sum * GRADE);
if (sum == NULL) TBD();

5. Use const with the pointers to insure wider application of the function and allow optimizations the compiler may not readily recognize.

// double* polynomial(double *xVal, double *xNode, double *yNode){
double* polynomial(const double *xVal, const double *xNode, const double *yNode){

// double* error(double *xVal, double *sum)
double* error(const double *xVal, const double *sum)

6. Help convey the double-ness of the variable.

// sum[j] = 0;  // This looks int-ish
sum[j] = 0.0;


As a general principle, I find it annoying when programs do this:

system("clear");
printf("\n===== PROGRAMMA PER IL CALCOLO DEL POLINOMIO DI LAGRANGE =====\n\n");


The second (i.e. print) is only a minor annoyance: I've just started the program, so why do I need telling what it is? It does mean that I need to filter out that message if I want to pipe the results to another program.

The first (i.e. clear) is much more serious. If I want a clear screen (and assuming that the output is going to a device where that actually means something), I can do that as a user. If I want to keep the previous results visible, the program has denied me that option. All assuming that the system has a working "clear" command - IIRC, there are (non-POSIX) systems that don't.

This version of the program doesn't accept arguments, but when it does, then the clear makes it much harder to compare different invocations, because the previous results are always obliterated.

I recommend writing only the actual output to standard output, and nothing to standard error unless the program has not performed its task (when it should exit with a non-zero status).

And please get into the habit of checking the return value of printf(). It's annoying for programs to report success when actually the file system that their output is connected to has filled up, and nothing was actually written.