Error writing recursive function for Bonnet's recursion formula in C

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
7 replies · 6K views
PrakashPhy
Messages
35
Reaction score
0
Bonnet’s recursion formula for Legendre polynomials is
P(n,x)=1 for n=0
P(n,x)=x for n=1 and
P(n,x)= (2n-1)/n*x*P(n-1,x)-(n-1)/n*P(n-2,x)

I tried to write recursive function in C to calculate the value of polynomial for a given n and x
Code:
float legpol(int n, float x)
    {
        if(n==0)
            return 1;
        else if(n==1)
            return x;
        else
            return(2*n-1)/n*x*legpol(n-1,x)-(n-1)/n*legpol(n-2,x);
    }
But this doesn't give the correct result. What's wrong with the function??

Thanks in advance
 
Physics news on Phys.org
Can you give a sample of the output vs. what the correct answer should be?
 
The actual legendre's polynomials are
for n = 0 1
for n= 1 x
for n = 2
82722ebdf5cc1c9deb3475a7ec25bd3d.png

for n= 3
b8e8e3c74d685b1d03f1d11dd2b0a78d.png

for n =4
1b43b5affe459365b174311803a08ad6.png

and so onif n= 2 and x= .1 the output must be -0.485 but my recursive function gives 0.01 which is wrong
 
The problem is, I believe, that your formula is using int division in a couple of places, and they give you incorrect function values. Inexperienced C and C++ programmers often don't realize that there are two kinds of division - integer and floating point.

Your code has this line:
Code:
return(2*n-1)/n*x*legpol(n-1,x)-(n-1)/n*legpol(n-2,x);

If n == 3, for example, the (2*n - 1)/n expression evaluates to 5/3 == 1. The other int term is multiplied by 2/3 == 0.

An easy fix is to change the line above to
Code:
return(2*n-1.0)/n*x*legpol(n-1,x)-(n-1.0)/n*legpol(n-2,x);

This change causes the numerators of both fractions to be promoted to double before the division actually occurs, forcing floating point division to be performed, rather than integer division.
 
Thank you! This change worked fine.

I tried to figure out the error and checked the value of 'n' after each function call and thought there might have been changes in the value of 'n' within the recursive function call. So i tried to preserve the value of 'n' by creating another variable 'b' just to use it in nested function call. I modified the above function like this::
Code:
float legpol(int n, float x)
    {
        int b;
        if(n==0)
            return 1;
        else if(n==1)
            return x;
        else
        {
             b=n;
             return(2*b-1)/b*x*legpol(b-1,x)-(b-1)/b*legpol(b-2,x);
         }
     }

Amazingly it worked. In this case why shouldn't i write (2*b-1.0) ??
 
I don't know why your revision should work. For some int divisions you get the answer you would expect, such as 6/3 or 10/2. It might be that what got evaluated was something like this.

In any case, I would get rid of the b variable and use code that forces floating point division, such as 2nd example in my previous post.
 
I'm sorry for the second revision i posted. I had actually typed
Code:
float b;
in the third line of my function not
Code:
 int b
.

I now know what the problem was. Thank you very much for the solution. It really helped me.
 
PrakashPhy said:
I'm sorry for the second revision i posted. I had actually typed
Code:
float b;
in the third line of my function not
Code:
 int b
.

I now know what the problem was. Thank you very much for the solution. It really helped me.
Yes, that would have made a difference, by causing floating point division to be performed instead of integer division.