0

I've been stuck on this for a while now. I'm writing an algorithm in C to pull out the coefficients of a polynomial using Lagrange's interpolation method.

My code partially works, for instance if we do the first example here http://en.wikipedia.org/wiki/Lagrange_polynomial#Example_1 then the code can print out the first 2 coefficients (0 and 4.834848)

Similarly with example 3 on that article, it will print the 2 coefficients 6 and -11.

I need to be able to accurately get all the coefficients from any set of points. Please advise on the alterations required to the code.

Thanks in advance!

Updated with latest code, 7:57PM, GMT on August 5th. 9 coefficients now working, getting ugly looking. Will investigate iterative process for n degrees tomorrow!

#include<ncursesw/ncurses.h>
#include<math.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define MAX 200
float coeff[MAX], coefftwo[MAX], coeffthree[MAX], coefffour[MAX];
int count;
void main()
{
int n,i,j ;
char ch;
float x[MAX],y[MAX],fp2, coeff1, coeff2;
printf("\n\nn = ");
scanf("%i", &count);

    for(i=0; i < count; i++)
    {
        printf("\n\n The value of x%i= ", i);
        scanf("%f",&x[i]);
        printf("\n The value of f(x%i)= ", i);
        scanf("%f",&y[i]);
    }
    for(i=0;i<count;i++)
    {
        coeff1 = 1.0;
        coeff2 = 0.0;
        coeff3 = 0.0;
        coeff4 = 0.0;
        coeff5 = 0.0;
        coeff6 = 0.0;
        coeff7 = 0.0;
        coeff8 = 0.0;
        coeff9 = 0.0;
        for(j=0; j<count; j++)
        {
            if(i!=j) {
                coeff1 = coeff1 * (array[i]-array[j]);
                coeff2 -= array[j];
                for (int k=j; k < count; k++) {
                if ((j!=k) && (k!=i)) {
                coeff3 += array[j] * array[k];
                    for(int l=k; l < count; l++) {
                    if ((l!=j) && (l!=k) && (l!=i))     {
    coeff4 -= array[j] * array[k] * array[l];

    for (int m = l; m < count; m++) {
        if ((m!=l) && (m!=k) && (m!=j) && (m!=i)) {                 coeff5 += array[j] * array[k] * array[l] * array[m];
            for (int n = m; n < count; n++) {
            if ((n!=m) && (n!=l) && (n!=k) && (n!=j) && (n!=i)) {
            coeff6 -= array[j] * array[k] * array[l] * array[m] * array[n];
            for (int o = n; o < count; o++) {
            if ((o!=n) && (o!=m) && (o!=l) && (o!=k) && (o!=j) && (o!=i)) {
            coeff7 += array[j] * array[k] * array[l] * array[m] * array[n] * array[o];
            for (int p = o; p < count; p++) {
            if ((p!=o) && (p!=n) && (p!=m) && (p!=l) && (p!=k) && (p!=j) && (p!=i)) {
            coeff8 -= array[j] * array[k] * array[l] *array[m] *array[n] * array[o] * array[p];
            for (int q = p; q < count; q++) {
            if ((q!=p) && (q!=o) && (q!=n) && (q!=m) && (q!=l) && (q!=k) && (q!=j) && (q!=i)) {
            coeff9 += array[j] * array[k] * array[l] * array[m] * array[n] * array[o] * array[p] * array[q];
            }
            }
            }
            }
            }
            }
            }
            }
                    }               
        }
                    }
                }
            }
        }    
    }
}       
        coeff[i] = y[i] / coeff1;
        coefftwo[i] = y[i] * coeff2 / coeff1;   
        coeffthree[i] = y[i] * coeff3 / coeff1;
        coefffour[i] = y[i] * coeff4 / coeff1;
        coefffive[i] = y[i] * coeff5 / coeff1;
        coeffsix[i] = y[i] * coeff6 / coeff1;
        coeffseven[i] = y[i] * coeff7 / coeff1;
        coeffeight[i] = y[i] * coeff8 / coeff1;
        coeffnine[i] = y[i] * coeff9 / coeff1;
    }
float coefficientone = 0.0;
float coefficienttwo = 0.0;
float coefficientthree = 0.0;
float coefficientfour = 0.0;
float coefficientfive = 0.0;
float coefficientsix = 0.0;
float coefficientseven = 0.0;
float coefficienteight = 0.0;
float coefficientnine = 0.0;
for (int i = 0; i< count; i++){
        coefficientone = coefficientone + coeff[i];
        coefficienttwo = coefficienttwo + coefftwo[i];
        coefficientthree = coefficientthree + coeffthree[i];
        coefficientfour = coefficientfour + coefffour[i];
        coefficientfive = coefficientfive + coefffive[i];
        coefficientsix = coefficientsix + coeffsix[i];
        coefficientseven = coefficientseven + coeffseven[i];
        coefficienteight = coefficienteight + coeffeight[i];
        coefficientnine = coefficientnine + coeffnine[i];
}
printf("coefficient 1 = %f\n", coefficientone);
printf("coefficient 2 = %f\n", coefficienttwo);
printf("coefficient 3 = %f\n", coefficientthree);
printf("coefficient 4 = %f\n", coefficientfour);
printf("coefficient 5 = %f\n", coefficientfive);
printf("coefficient 6 = %f\n", coefficientsix);
printf("coefficient 7 = %f\n", coefficientseven);
printf("coefficient 8 = %f\n", coefficienteight);
printf("coefficient 9 = %f\n", coefficientnine);

}

JaboJG
  • 92
  • 1
  • 10
  • Can you give an example of it *failing?* – Beta Aug 04 '13 at 23:46
  • Of course - with the following inputs, count = 4, array[] = the "x" values from Example 1 on the Wikipedia article, y[] = the "f(x)" values; we get the following output, coefficient 1 = 0.000000, coefficient 2 = 4.834848, coefficient 3 = 4.834848, coefficient 4 = 10.576050. The first two coefficients are correct, the third and forth aren't (see the example for correct values) – JaboJG Aug 04 '13 at 23:55
  • What value does `count` start with? Your use suggests it starts with `1`, and in that case your array indexes may be off. Maybe your loops were intended to be up to `< count`. – Jongware Aug 05 '13 at 00:08
  • 2
    I can't reproduce your results, but the problem may be that I've had to make a lot of guesses about the code you *haven't* shown us. Also having variables named e.g. `coeff2`, `coefftwo` and `coefficienttwo` is very bad practice. – Beta Aug 05 '13 at 00:10
  • count is a poor name to use, it should be something more like indexes. It's defined by a keyboard input to tell the program how many points are going to be entered, as count = input - 1; Doing Example 1 it will go from 0 to 4, which is 5 points. I know it's daft looking, I'll clean it up. – JaboJG Aug 05 '13 at 00:16
  • Ok, I've posted an edit with code that will compile, and cleaned up `count` – JaboJG Aug 05 '13 at 00:31

1 Answers1

4

Your algebra is simply wrong, and that fact is hidden by poorly chosen variable names.

When you calculate the contribution of the ith basis polynomial (never mind y for now) what variable represents the coefficient of the x2 term? It's coeff3. And you don't calculate it correctly.

Take a simpler case. Suppose you want to work out (x+a)(x+b)(x+c)(x+d). The first term is x4, easy. The next is (a+b+c+d)x3, not too bad. The next is (ab + ac + ad + bc + bd + cd)x2, and now it's clear that a single loop won't do the job. It's worth taking the time to make sure you can write code that handles the simple problem correctly, before you try the more complex one. You need something like this:

for(unsigned int j=0 ; j<count ; ++j)
{
  ...
  coeff2 -= x[j];
  for(unsigned int k=j ; k<count ; ++k)
  {
    if(j!=k && k!=i)
      coeff3 += x[j] * x[k];
    ...
  }
}

That should be enough to get you started.

Beta
  • 96,650
  • 16
  • 149
  • 150
  • Ok, I've updated above after your help. What do I do at the coeffthree[] calculation? – JaboJG Aug 05 '13 at 09:45
  • *Is your algebra correct?* Why do you divide by `coeff2`? It should be `coeffthree[i] = y[i] * coeff3 / coeff1;`. – Beta Aug 05 '13 at 13:46
  • I coded `coeff3` as you said and I have `coeffthree[i] = y[i] * coeff3 / coeff1;` I've tried the following points {1, 3], {2, 9}, {3, 27} and that should give `coefficientthree` as 9 but in this code it gives 75. – JaboJG Aug 05 '13 at 14:03
  • 1
    @JaboJG: Yes, my code wasn't quite right. I'll correct it, but you'll have to start working out the algebra yourself or you'll have further problems. – Beta Aug 05 '13 at 17:06
  • Thanks @Beta, I'm making some progress now – JaboJG Aug 05 '13 at 17:31