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

Click For Summary

Discussion Overview

The discussion centers around the implementation of Bonnet's recursion formula for Legendre polynomials in C, specifically focusing on a recursive function intended to calculate the polynomial values for given inputs of n and x. Participants explore issues related to incorrect outputs and the nuances of integer versus floating-point division in C programming.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant presents a recursive function for calculating Legendre polynomials but notes it produces incorrect results.
  • Another participant requests a comparison of the function's output against the expected results to clarify the issue.
  • A participant identifies potential problems with integer division in the original function, suggesting that it leads to incorrect values.
  • A proposed solution involves modifying the division to ensure floating-point arithmetic by using decimal points in the numerator.
  • One participant reports that after implementing the suggested change, the function works correctly.
  • Another participant questions the necessity of introducing a new variable to preserve the value of n, suggesting that the original solution should suffice with proper floating-point division.
  • A participant acknowledges a misunderstanding regarding variable types, indicating that using a float instead of an int for the variable made a difference in the calculations.

Areas of Agreement / Disagreement

Participants express differing views on the necessity of introducing a new variable for preserving the value of n, with some advocating for the original solution while others support the modification. The discussion does not reach a consensus on the best approach to ensure correct calculations.

Contextual Notes

Participants note that the issue of integer versus floating-point division is critical in C programming, and the discussion highlights the importance of understanding how data types affect arithmetic operations.

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
 
Technology 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.
 

Similar threads

  • · Replies 11 ·
Replies
11
Views
1K
  • · Replies 16 ·
Replies
16
Views
3K
  • · Replies 7 ·
Replies
7
Views
871
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 39 ·
2
Replies
39
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 15 ·
Replies
15
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K