I am attempting to write a simple recursive function to evaluate Associated Legendre Polynomials in C. As of now, I only have it written up to L=4 and M=3. I am using the seventh recurrence formula from the following Wikipedia article:
https://en.wikipedia.org/wiki/Associated_Legendre_polynomials
Here is my code:
#include <stdio.h>
#include <math.h>
long double Legendre(int L, int M, double x){
if((M == 0) && (L == 0)){
return 1;
}
if((M == 0) && (L == 1)){
return x;
}
if((M == 0) && (L == 2)){
return (1/2) * ((3*x*x) - 1);
}
if((M == 0) && (L == 3)){
return (1/2) * ((5*pow(x,3)) - (3*x));
}
if((M == 0) && (L == 4)){
return (1/8) * (3 - (30*x*x) + (35*pow(x,4)));
}
else if(M > 0){
return (((L - M + 1)*x*Legendre(L,M-1,x))
- ((L + M - 1)*Legendre(L-1,M-1,x)))
/ sqrt(1-(x*x));
}
return 0;
}
int main(void){
int L = 4;
int M = 2;
double x = 0.6;
printf("%Lf\n",Legendre(L,M,x));
}
As per Mathematica, the Associated Legendre Polynomial with L=4, M=2, and x=0.6 should be 7.3. However, when I run the above program, I get the following result:
$ gcc Rodrigues.c -o Rodrigues
$ ./Rodrigues
0.000000
$
(My source file name is Rodrigues.c). The output should be around 7.3, not 0. The code also produces other non-zero (though still incorrect) values for different Ls and Ms. I am suspecting it is because I have somehow messed up the recursion (as you can tell, I am relatively new to programming). What am I missing? Thanks.
Related
any ideas why this is generating a floating point exception? Please ignore the bad coding. This is very rough and I am just trying to experiment different things on this assignment. Also, I trying to do this assignment with only the operations learned in class (I am awere there are others that would make this easier)
Thanks!
#include <stdio.h>
#include <cs50.h>
int main(void)
{ long c = get_long("What is your credit card number?\n");
long i = 10;
long j = 100;
long n = 0;
long m = 0;
long x = 2;
do
{ long a = (c % i - (c % i)/10)/(i/10);
n = a + n;
i = i*100;
}
while (c/i >= 0.1 || c/i == 0);
do
{ long b = (c%j - (c%j)/10)/(j/10);
m = b + m;
j = j*100;
}
while (c/j >= 0.1 || c/j == 0);
long sum = n + 2*m;
if (i > j)
{
x = i;
}
else
{
x = j;
}
if (sum % 10 == 0)
{ if((x == 10000000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == (34)))
{
printf("Amercan Express\n");
}
else if((x == 100000000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == (51)))
{
printf("MasterCard\n");
}
else if((x == 10000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == 4))
{
printf("Visa\n");
}
else if((x == 10000000000000000) && ((c % (x/100) - c % (x/1000))/(x/100000) == 4))
{
printf("Visa\n");
}
else
{
printf("Invlid\n");
}
}
else
{
printf("Invlid\n");
}
}'''
This is the part that is the problem:
while (c/i >= 0.1 || c/i == 0);
in your first do while loop.
Your data types are long and so you are saying that as long as c/i is greater than 0.1 or == 0 then keep going. Unfortunately this will go on forever as a long will always be >= 0.1 or <= 0 because it cant hold decimal places.If you play around with debug50 by using debug50 ./filename you can place a red dot and step through. What you will see is the first do while loop will keep running increasing the value of i every cycle. Eventually the value of i is bigger than the memory limit for a long and so the code creates unexpected results.If you step through you find that it eventually assigns 0 to i and so you suffer a divide by 0 error.
You can fix this by changing data types or altering that while loop.
I hope that helps. Id suggest stepping through that do while loop using debug50 in the cs50 ide to see whats going on.
I'd like to ask the following misunderstandings of C language, which I see I'm having.
I'm sorry if the code is not properly indented, I tried as much as I could but there are not so many guides on the internet.
The program asked given a starting number 'val' and a Even-Odd or Odd-Even alternating sequence (which stops whenever this rules is violated) to print the greater prime number with 'val'.
I tried with two functions and the main: one to control the GCD between two given numbers and the other to keep tracks of the greatest one, but I think I miss something in the code or in the conception of C function,
Because when compiled it returns me 0 or great number which I'm not entering.
One example to understand what I should do:
If my sequence was 10, 7, 8, 23 and my val was 3, I had to print 23, because it is the greatest integer prime with 3.
Here's the code :
#include <stdio.h>
int mcd(int a, int b)
{ // Gcd function
if (a == 0)
return b;
else
return mcd(b % a, b);
}
int valuta(int val, int h) // Valuing Max function
{
int temp = 0;
if (mcd(val, h) == 1 && h > temp)
temp = h;
return temp;
}
int main()
{
int val, d, x, y, z, t, contatore = 1;
scanf("%d", &val);
scanf("%d%d", &x, &y);
if (x > y && mcd(val, x) == 1)
{ // Two options
t = x;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
}
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1))
{ // Bad case
if (x > y && mcd(val, x) == 1)
{
t = x;
contatore = 0;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
contatore = 0;
}
}
else
{
while (contatore == 1)
{
scanf("%d", &z);
t = valuta(val, z);
if (x % 2 == 0 && z % 2 == 0)
{ // Even- Odd - Even
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 0)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
if (x % 2 == 1 && z % 2 == 1)
{ //Odd- Even- Odd
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 1)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
}
}
printf("%d\n", t);
return 0;
}
PS. Is there any way to reduce the number of lines of code or to reduce the effort in coding? I mean, a straightforward solution will be helpful.
Your valuta() function is flawed in that it needs to return the maximum qualifying value so far but has no knowledge of the previous maximum - temp is always zero. The following takes the previous maximum as an argument:
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) == 1 && h > previous ) ? h : previous ;
}
And is called from main() thus:
t = valuta( val, x, t ) ;
The test mcd(val, h) == 1 is flawed, because mcd() only ever returns the value of parameter b which is not modified in the recursion, so will never return 1, unless the argument b is 1. Since I have no real idea what mcd() is intended to do, I cannot tell you how to fix it. It appear to be a broken implementation of Euclid's greatest common divisor algorithm, which correctly implemented would be:
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
But I cannot see how that relates to:
"[...] he greatest integer prime with 3 [...]
The odd/even even/odd sequence handling can be drastically simplified to the extent that it is shorter and simpler than your method (as requested) - and so that it works!
The following is a clearer starting point, but may not be a solution since it is unclear what it is it is supposed to do.
#include <stdio.h>
#include <stdbool.h>
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) && h > previous ) ? h : previous ;
}
int main()
{
int val, x, t ;
printf( "Enter value:") ;
scanf("%d", &val);
typedef enum
{
EVEN = 0,
ODD = 1,
UNDEFINED
} eOddEven ;
eOddEven expect = UNDEFINED ;
bool sequence_valid = true ;
printf( "Enter sequence in odd/even or even/odd order (break sequence to exit):\n") ;
while( sequence_valid )
{
scanf("%d", &x);
if( expect == UNDEFINED )
{
// Sequence order determined by first value
expect = (x & 1) == 0 ? EVEN : ODD ;
}
else
{
// Switch expected odd/even
expect = (expect == ODD) ? EVEN : ODD ;
// Is new value in the expected sequence?
sequence_valid = (expect == ((x & 1) == 0 ? EVEN : ODD)) ;
}
// If the sequence is valid...
if( sequence_valid )
{
// Test if input is largest qualifying value
t = valuta( val, x, t ) ;
}
}
// Result
printf("Result: %d\n", t);
return 0;
}
beginner here trying to understand the source of the bug.
I have written this recursive function for finding the binomial coefficient between two numbers which is apparently correct in concept. However, for these two numbers, n =4 and k=2, I should be getting 6 as a result whereas I actually get 16. Any idea why is that happening?
#include<stdio.h>
int binomial(int n, int k)
{
if ((k = 0) || (k == n))
return 1;
if (k>n)
return 0;
return binomial(n - 1, k - 1) + binomial(n - 1, k);
}
int main()
{
int a, b, res;
a = 4;
b = 2;
res = binomial(a, b);
printf("The result is %d", res);
return 0;
}
This line looks wrong as it assigns 0 to k:
if ((k=0) || (k==n))
You probably mean:
if ((k==0) || (k==n))
This line
if ((k = 0) || (k == n))
should be
if ((k == 0) || (k == n))
^^
You were assigning zero to k.
As #Michael Walz points out, it's good practice to compile with -Wall to turn on all compilation warnings.
Is there any way to find nth root of the number without any external library in C? I'm working on a bare metal code so there is no OS. Also, no complete C is there.
You can write a program like this for nth root. This program is for square root.
int floorSqrt(int x)
{
// Base cases
if (x == 0 || x == 1)
return x;
// Staring from 1, try all numbers until
// i*i is greater than or equal to x.
int i = 1, result = 1;
while (result < x)
{
if (result == x)
return result;
i++;
result = i*i;
}
return i-1;
}
You can use the same approach for nth root.
Here there is a C implementation of the the nth root algorithm you can find in wikipedia. It needs an exponentiation algorithm, so I also include an implementation of a basic method for exponentiation by squaring that you can find also find in wikipedia.
double npower(double const base, int const n)
{
if (n < 0) return npower(1/base, -n)
else if (n == 0) return 1.0;
else if (n == 1) return base;
else if (n % 2) return base*npower(base*base, n/2);
else return npower(base*base, n/2);
}
double nroot(double const base, int const n)
{
if (n == 1) return base;
else if (n <= 0 || base < 0) return NAN;
else {
double delta, x = base/n;
do {
delta = (base/npower(x,n-1)-x)/n;
x += delta;
} while (fabs(delta) >= 1e-8);
return x;
}
}
Some comments on this:
The nth root algorithm in wikipedia leaves freedom for the initial guess. In this example I set it up to be base/n, but this was just a guess.
The macro NAN is usually defined in <math.h>, so you would need to define it to be suitable for your needs.
Both functions are implemented in a very rough and simple way, and their performance can be greatly improved with careful thought.
The tolerance in this example is set to 1e-8 and should be changed to something different. It should probably be proportional to the value of the base.
You can try the nth_root C function :
// return a number that, when multiplied by itself nth times, makes N.
unsigned nth_root(const unsigned n, const unsigned nth) {
unsigned a = n, b, c, r = nth ? n + (n > 1) : n == 1 ;
for (; a < r; b = a + (nth - 1) * r, a = b / nth)
for (r = a, a = n, c = nth - 1; c && (a /= r); --c);
return r;
}
Source
Function fun(n) is defined as such:
fun(n) = 1 (if n <=1)
fun(n) = fun(n/2) (if n is even)
fun(n) = 2*fun((n-1)/3) (if n> and n is odd)
I'm trying to write a recursive function to compute and return the result. I just started learning recursion, I got kind of lost while doing this function. Can someone correct me and explain to me? Thanks!
Here's what I did:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
int fun(int n);
int main()
{
int num;
printf("\nEnter a number: ");
scanf("%d", num);
printf("Result = %d\n", fun(num));
return 0;
}
int fun(int n)
{
if (n <= 1)
{
return 1;
}
else if (n % 2 == 0)
{
return fun(n / 2);
}
else if ((n > 1) && (n % 2 == 0))
{
return 2 * fun((n - 1) / 3);
}
}
Expected output:
Enter a number: 13
Result = 2
Enter a number: 34
Result = 4
Output I'm getting instead:
Enter a number: 13
Result = 1
Enter a number: 34
Result = 1
scanf takes a pointer to int as argument for %d, i.e.,
scanf("%d", &num);
Also, your function fun does not handle all cases and may fall off the bottom:
if (n <= 1)
{
return 1;
}
else if (n % 2 == 0)
{
return fun(n / 2);
}
else if ((n > 1) && (n % 2 == 0))
{
return 2 * fun((n - 1) / 3);
}
The last else if condition is never met, because the previous check for n % 2 == 0 already returns in that case. Also the n > 1 is pointless because the first n <= 1 returns in all other cases.
You can simply make it:
else
{
return 2 * fun((n - 1) / 3);
}
The culprit is the last else if condition. Change it to:
else if ((n % 2) != 0)
The condition that n is odd is written wrong here. You wrote the same thing as for when n is even.
Its probably better to explicitly make the cases disjoint so you always return and there's no warning, like this:
int fun(int n)
{
if(n <= 1)
return 1;
if(n % 2 == 0)
return fun(n/2);
//No need for a condition, we know the last one must be satisfied
return 2 * fun((n-1)/3);
}
or, add another "default" case that indicates there was some error.
I think last if should be:
else if ((n > 1) && (n % 2 != 0))
Notice the != instead of ==.
The third condition
else if ((n > 1) && (n % 2 == 0))
is wrong, but instead of fixing it just you else no else if - because all other conditions were checked already.