Lacking in mathematical functions


#1

Do you want more mathematical functions in Ruby?
I do! Here is a list of mathematical functions
Ruby does not have. Please add your favorites.

This issue was discussed in Japanese in
[ruby-list:44246], [ruby-list:45859] and
[ruby-dev:37947].

C99 has, Ruby does not:
cbrt cube root function.
expm1 exp(x)-1.
lgamma log(|Gamma(x)|). How should we
treat “extern int signgam” in <math.h>?
tgamma Gamma(x)
cproj project into Riemann Sphere

Other special functions:
Bessel functions (Gnuplot has Bessel functions.)
Beta function
Zeta function

Bug in sqrt(Complex):
Math::sqrt(Complex(-4.0,-0.0)) => (0.0+2.0i)
Math::sqrt(Complex(-4.0, 0.0)) => (0.0+2.0i)
It can be fixed easily with signbit or copysign.

Sign (treatment of -0.0, especially):
signbit test sign. Already implemented in complex.c.
x.negative? and x.positive? may be a good idea.
copysign copy sign of a number

Here is my quick hack of copysign:
— numeric.c (revision 23350)
+++ numeric.c (working copy)
@@ -439,6 +439,46 @@

/*

  • call-seq:
    • num.copysign(other)   => num
      
    • Copy the sign of other to num
  • */

+static VALUE
+num_copysign(VALUE x, VALUE y)
+{

  • double fy;
  • switch (TYPE(y)) {
  •  case T_FIXNUM:
    
  •   fy = (double)FIX2LONG(y);
    
  •   break;
    
  •  case T_BIGNUM:
    
  •   fy = rb_big2dbl(y);
    
  •   break;
    
  •  case T_FLOAT:
    
  •   fy = RFLOAT_VALUE(y);
    
  •   break;
    
  •  default:
    
  •   return rb_num_coerce_bin(x, y, 'copysign');
    
  • }
  • switch (TYPE(x)) {
  •  case T_FLOAT:
    
  •   return DBL2NUM(copysign(RFLOAT_VALUE(x), fy));
    
  •   break;
    
  •  default:
    
  •   if (copysign(1.0,fy)<0.0) {
    
  • return rb_funcall(rb_funcall(x, rb_intern(“abs”), 0),
    rb_intern("-@"), 0);
  • } else {
  • return rb_funcall(x, rb_intern(“abs”), 0);
  • }
  • }
    +}

+/*

    • call-seq:
    • num.zero?    => true or false
      
    • Returns true if num has a zero value.
      @@ -3184,6 +3224,8 @@
      rb_define_method(rb_cNumeric, “magnitude”, num_abs, 0);
      rb_define_method(rb_cNumeric, “to_int”, num_to_int, 0);
  • rb_define_method(rb_cNumeric, “copysign”, num_copysign, 1);

  • rb_define_method(rb_cNumeric, “real?”, num_real_p, 0);
    rb_define_method(rb_cNumeric, “integer?”, num_int_p, 0);
    rb_define_method(rb_cNumeric, “zero?”, num_zero_p, 0);

Ciao, ciao,