You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.8 KiB

25 years ago
  1. // Compute the Legendre polynomials.
  2. #include <cl_number.h>
  3. #include <cl_integer.h>
  4. #include <cl_rational.h>
  5. #include <cl_univpoly.h>
  6. #include <cl_modinteger.h>
  7. #include <cl_univpoly_rational.h>
  8. #include <cl_univpoly_modint.h>
  9. #include <cl_io.h>
  10. #include <stdlib.h>
  11. // Computes the n-th Legendre polynomial in R[x], using the formula
  12. // P_n(x) = 1/(2^n n!) * (d/dx)^n (x^2-1)^n. (Assume n >= 0.)
  13. const cl_UP_RA legendre (const cl_rational_ring& R, int n)
  14. {
  15. cl_univpoly_rational_ring PR = cl_find_univpoly_ring(R);
  16. cl_UP_RA b = PR->create(2);
  17. b.set_coeff(2,1);
  18. b.set_coeff(1,0);
  19. b.set_coeff(0,-1);
  20. b.finalize(); // b is now x^2-1
  21. cl_UP_RA p = (n==0 ? PR->one() : expt_pos(b,n));
  22. for (int i = 0; i < n; i++)
  23. p = deriv(p);
  24. cl_RA factor = recip(factorial(n)*ash(1,n));
  25. for (int j = degree(p); j >= 0; j--)
  26. p.set_coeff(j, coeff(p,j) * factor);
  27. p.finalize();
  28. return p;
  29. }
  30. const cl_UP_MI legendre (const cl_modint_ring& R, int n)
  31. {
  32. cl_univpoly_modint_ring PR = cl_find_univpoly_ring(R);
  33. cl_UP_MI b = PR->create(2);
  34. b.set_coeff(2,R->canonhom(1));
  35. b.set_coeff(1,R->canonhom(0));
  36. b.set_coeff(0,R->canonhom(-1));
  37. b.finalize(); // b is now x^2-1
  38. cl_UP_MI p = (n==0 ? PR->one() : expt_pos(b,n));
  39. for (int i = 0; i < n; i++)
  40. p = deriv(p);
  41. cl_MI factor = recip(R->canonhom(factorial(n)*ash(1,n)));
  42. for (int j = degree(p); j >= 0; j--)
  43. p.set_coeff(j, coeff(p,j) * factor);
  44. p.finalize();
  45. return p;
  46. }
  47. int main (int argc, char* argv[])
  48. {
  49. if (!(argc == 2 || argc == 3)) {
  50. fprint(cl_stderr, "Usage: legendre n [m]\n");
  51. exit(1);
  52. }
  53. int n = atoi(argv[1]);
  54. if (!(n >= 0)) {
  55. fprint(cl_stderr, "Usage: legendre n [m] with n >= 0\n");
  56. exit(1);
  57. }
  58. if (argc == 2) {
  59. cl_UP p = legendre(cl_RA_ring,n);
  60. fprint(cl_stdout, p);
  61. } else {
  62. cl_I m = argv[2];
  63. cl_UP p = legendre(cl_find_modint_ring(m),n);
  64. fprint(cl_stdout, p);
  65. }
  66. fprint(cl_stdout, "\n");
  67. }