Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in factorial calculation #218

Open
hariuc opened this issue Mar 16, 2023 · 6 comments
Open

Bug in factorial calculation #218

hariuc opened this issue Mar 16, 2023 · 6 comments

Comments

@hariuc
Copy link

hariuc commented Mar 16, 2023

Factorial of a negative number does not exist
Factorial of a real number does not exist

@Preetiraj3697
Copy link

As mentioned earlier, the traditional definition of the factorial function is only valid for non-negative integers, so it does not make sense to compute the factorial of negative or real numbers in the same way. However, here is an implementation of the gamma function and the signed factorial that can handle negative and real numbers

@Preetiraj3697
Copy link

import 'dart:math';

double gamma(double x) {
  const double pi = 3.141592653589793;
  if (x < 0.5) {
    return pi / (sin(pi * x) * gamma(1 - x));
  }
  x -= 1;
  double a = 0.99999999999980993;
  const List<double> p = [
    676.5203681218851, -1259.1392167224028, 771.32342877765313,
    -176.61502916214059, 12.507343278686905, -0.13857109526572012,
    9.9843695780195716e-6, 1.5056327351493116e-7
  ];
  for (int i = 0; i < p.length; i++) {
    a += p[i] / (x + i + 1);
  }
  double t = x + p.length - 0.5;
  return sqrt(2 * pi) * pow(t, x + 0.5) * exp(-t) * a;
}

double factorial(num n) {
  if (n is int) {
    assert(n >= 0, "Factorial of a negative number does not exist");
  }
  return gamma(n + 1);
}

double signedFactorial(int n) {
  if (n % 2 == 0) {
    return factorial(n);
  } else {
    return -factorial(n);
  }
}

The gamma function uses the Lanczos approximation to compute the gamma function, which is a well-known way to compute the gamma function for real and complex numbers. The factorial function simply computes gamma(n+1), while the signedFactorial function computes the signed factorial using the definition mentioned earlier. Note that the factorial function also checks that n is non-negative if it is an integer.

@Preetiraj3697
Copy link

import 'dart:math';

double gamma(double x) {
  const double pi = 3.141592653589793;
  if (x < 0.5) {
    return pi / (sin(pi * x) * gamma(1 - x));
  }
  x -= 1;
  double a = 0.99999999999980993;
  const List<double> p = [
    676.5203681218851, -1259.1392167224028, 771.32342877765313,
    -176.61502916214059, 12.507343278686905, -0.13857109526572012,
    9.9843695780195716e-6, 1.5056327351493116e-7
  ];
  for (int i = 0; i < p.length; i++) {
    a += p[i] / (x + i + 1);
  }
  double t = x + p.length - 0.5;
  return sqrt(2 * pi) * pow(t, x + 0.5) * exp(-t) * a;
}

double factorial(num n) {
  if (n is int) {
    assert(n >= 0, "Factorial of a negative number does not exist");
  }
  return gamma(n + 1);
}

double signedFactorial(int n) {
  if (n % 2 == 0) {
    return factorial(n);
  } else {
    return -factorial(n);
  }
}

The gamma function uses the Lanczos approximation to compute the gamma function, which is a well-known way to compute the gamma function for real and complex numbers. The factorial function simply computes gamma(n+1), while the signedFactorial function computes the signed factorial using the definition mentioned earlier. Note that the factorial function also checks that n is non-negative if it is an integer.

if this solution is right please assign me and merge my code.

@akashgk
Copy link
Member

akashgk commented Apr 19, 2023

HI @Preetiraj3697

I would suggest you make a PR for the same. I think instead of fixing the existing factorial. why not create a new file for the Lanczos approximation

@Preetiraj3697
Copy link

Ok @akashgk I make a PR.

@Preetiraj3697
Copy link

HI @Preetiraj3697

I would suggest you make a PR for the same. I think instead of fixing the existing factorial. why not create a new file for the Lanczos approximation

@akashgk please merge my code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants