summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--complex.c139
-rw-r--r--lib/cmath.rb223
-rw-r--r--lib/complex.rb6
-rw-r--r--lib/rational.rb2
-rw-r--r--math.c16
-rw-r--r--rational.c7
7 files changed, 270 insertions, 133 deletions
diff --git a/ChangeLog b/ChangeLog
index 1039aca736..f52247a972 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sat Apr 5 23:17:20 2008 Tadayoshi Funaba <tadf@dotrb.org>
+
+ * lib/cmath.rb: new.
+
+ * lib/complex.rb: depends lib/cmath.rb.
+
+ * lib/rational.rb: added rdiv.
+
+ * complex.c: removed some math functions.
+
Sat Apr 5 05:50:57 2008 Eric Hodel <drbrain@segment7.net>
* lib/rdoc/parsers/parse_rb.rb: Fix uninitialized variable warnings.
diff --git a/complex.c b/complex.c
index fdf4719551..fc42a04b84 100644
--- a/complex.c
+++ b/complex.c
@@ -474,47 +474,29 @@ nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
return rb_funcall2(rb_cComplex, id_convert, argc, argv);
}
-#if 1
-/* the following code is copied from math.c */
-
-#include <errno.h>
-
-#define Need_Float(x) (x) = rb_Float(x)
-#define Need_Float2(x,y) do {\
- Need_Float(x);\
- Need_Float(y);\
-} while (0)
-
-static void
-domain_check(double x, char *msg)
-{
- while(1) {
- if (errno) {
- rb_sys_fail(msg);
- }
- if (isnan(x)) {
-#if defined(EDOM)
- errno = EDOM;
-#elif defined(ERANGE)
- errno = ERANGE;
-#endif
- continue;
- }
- break;
- }
-}
+extern VALUE math_atan2(VALUE obj, VALUE x, VALUE y);
+extern VALUE math_cos(VALUE obj, VALUE x);
+extern VALUE math_cosh(VALUE obj, VALUE x);
+extern VALUE math_exp(VALUE obj, VALUE x);
+extern VALUE math_log(int argc, VALUE *argv);
+extern VALUE math_sin(VALUE obj, VALUE x);
+extern VALUE math_sinh(VALUE obj, VALUE x);
+extern VALUE math_sqrt(VALUE obj, VALUE x);
+
+#define m_atan2_bang(x,y) math_atan2(Qnil,x,y)
+#define m_cos_bang(x) math_cos(Qnil,x)
+#define m_cosh_bang(x) math_cosh(Qnil,x)
+#define m_exp_bang(x) math_exp(Qnil,x)
static VALUE
-m_cos_bang(VALUE x)
+m_log_bang(VALUE x)
{
- Need_Float(x);
- return DOUBLE2NUM(cos(RFLOAT_VALUE(x)));
+ return math_log(1, &x);
}
-static VALUE m_cos_bang(VALUE);
-static VALUE m_cosh_bang(VALUE);
-static VALUE m_sin_bang(VALUE);
-static VALUE m_sinh_bang(VALUE);
+#define m_sin_bang(x) math_sin(Qnil,x)
+#define m_sinh_bang(x) math_sinh(Qnil,x)
+#define m_sqrt_bang(x) math_sqrt(Qnil,x)
static VALUE
m_cos(VALUE x)
@@ -531,47 +513,6 @@ m_cos(VALUE x)
m_sinh_bang(dat->image)));
}
-#ifndef HAVE_COSH
-double
-cosh(double x)
-{
- return (exp(x) + exp(-x)) / 2;
-}
-#endif
-
-static VALUE
-m_cosh_bang(VALUE x)
-{
- Need_Float(x);
- return DOUBLE2NUM(cosh(RFLOAT_VALUE(x)));
-}
-
-static VALUE
-m_exp_bang(VALUE x)
-{
- Need_Float(x);
- return DOUBLE2NUM(exp(RFLOAT_VALUE(x)));
-}
-
-static VALUE
-m_log_bang(VALUE x)
-{
- double d;
-
- Need_Float(x);
- errno = 0;
- d = log(RFLOAT_VALUE(x));
- domain_check(d, "log");
- return DOUBLE2NUM(d);
-}
-
-static VALUE
-m_sin_bang(VALUE x)
-{
- Need_Float(x);
- return DOUBLE2NUM(sin(RFLOAT_VALUE(x)));
-}
-
static VALUE
m_sin(VALUE x)
{
@@ -587,33 +528,6 @@ m_sin(VALUE x)
m_sinh_bang(dat->image)));
}
-#ifndef HAVE_SINH
-double
-sinh(double x)
-{
- return (exp(x) - exp(-x)) / 2;
-}
-#endif
-
-static VALUE
-m_sinh_bang(VALUE x)
-{
- Need_Float(x);
- return DOUBLE2NUM(sinh(RFLOAT_VALUE(x)));
-}
-
-static VALUE
-m_sqrt_bang(VALUE x)
-{
- double d;
-
- Need_Float(x);
- errno = 0;
- d = sqrt(RFLOAT_VALUE(x));
- domain_check(d, "sqrt");
- return DOUBLE2NUM(d);
-}
-
static VALUE
m_sqrt(VALUE x)
{
@@ -637,23 +551,6 @@ m_sqrt(VALUE x)
}
static VALUE
-m_atan2_bang(VALUE y, VALUE x)
-{
- Need_Float2(y, x);
- return DOUBLE2NUM(atan2(RFLOAT_VALUE(y), RFLOAT_VALUE(x)));
-}
-
-#if 0
-static VALUE
-m_hypot(VALUE x, VALUE y)
-{
- Need_Float2(x, y);
- return DOUBLE2NUM(hypot(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
-}
-#endif
-#endif
-
-static VALUE
nucomp_s_polar(VALUE klass, VALUE abs, VALUE arg)
{
return f_complex_new2(klass,
diff --git a/lib/cmath.rb b/lib/cmath.rb
new file mode 100644
index 0000000000..158da4175d
--- /dev/null
+++ b/lib/cmath.rb
@@ -0,0 +1,223 @@
+module CMath
+
+ include Math
+
+ alias exp! exp
+ alias log! log
+ alias log10! log10
+ alias sqrt! sqrt
+
+ alias sin! sin
+ alias cos! cos
+ alias tan! tan
+
+ alias sinh! sinh
+ alias cosh! cosh
+ alias tanh! tanh
+
+ alias asin! asin
+ alias acos! acos
+ alias atan! atan
+ alias atan2! atan2
+
+ alias asinh! asinh
+ alias acosh! acosh
+ alias atanh! atanh
+
+ def exp(z)
+ if Complex.generic?(z)
+ exp!(z)
+ else
+ Complex(exp!(z.real) * cos!(z.image),
+ exp!(z.real) * sin!(z.image))
+ end
+ end
+
+ def log(*args)
+ z, b = args
+ if Complex.generic?(z) and z >= 0 and (b.nil? or b >= 0)
+ log!(*args)
+ else
+ r, theta = z.polar
+ a = Complex(log!(r.abs), theta)
+ if b
+ a /= log(b)
+ end
+ a
+ end
+ end
+
+ def log10(z)
+ if Complex.generic?(z)
+ log10!(z)
+ else
+ log(z) / log!(10)
+ end
+ end
+
+ def sqrt(z)
+ if Complex.generic?(z)
+ if z >= 0
+ sqrt!(z)
+ else
+ Complex(0,sqrt!(-z))
+ end
+ else
+ if z.image < 0
+ sqrt(z.conjugate).conjugate
+ else
+ r = z.abs
+ x = z.real
+ Complex(sqrt!((r + x) / 2), sqrt!((r - x) / 2))
+ end
+ end
+ end
+
+ def sin(z)
+ if Complex.generic?(z)
+ sin!(z)
+ else
+ Complex(sin!(z.real) * cosh!(z.image),
+ cos!(z.real) * sinh!(z.image))
+ end
+ end
+
+ def cos(z)
+ if Complex.generic?(z)
+ cos!(z)
+ else
+ Complex(cos!(z.real) * cosh!(z.image),
+ -sin!(z.real) * sinh!(z.image))
+ end
+ end
+
+ def tan(z)
+ if Complex.generic?(z)
+ tan!(z)
+ else
+ sin(z)/cos(z)
+ end
+ end
+
+ def sinh(z)
+ if Complex.generic?(z)
+ sinh!(z)
+ else
+ Complex(sinh!(z.real) * cos!(z.image),
+ cosh!(z.real) * sin!(z.image))
+ end
+ end
+
+ def cosh(z)
+ if Complex.generic?(z)
+ cosh!(z)
+ else
+ Complex(cosh!(z.real) * cos!(z.image),
+ sinh!(z.real) * sin!(z.image))
+ end
+ end
+
+ def tanh(z)
+ if Complex.generic?(z)
+ tanh!(z)
+ else
+ sinh(z) / cosh(z)
+ end
+ end
+
+ def asin(z)
+ if Complex.generic?(z) and z >= -1 and z <= 1
+ asin!(z)
+ else
+ -1.0.im * log(1.0.im * z + sqrt(1.0 - z * z))
+ end
+ end
+
+ def acos(z)
+ if Complex.generic?(z) and z >= -1 and z <= 1
+ acos!(z)
+ else
+ -1.0.im * log(z + 1.0.im * sqrt(1.0 - z * z))
+ end
+ end
+
+ def atan(z)
+ if Complex.generic?(z)
+ atan!(z)
+ else
+ 1.0.im * log((1.0.im + z) / (1.0.im - z)) / 2.0
+ end
+ end
+
+ def atan2(y,x)
+ if Complex.generic?(y) and Complex.generic?(x)
+ atan2!(y,x)
+ else
+ -1.0.im * log((x + 1.0.im * y) / sqrt(x * x + y * y))
+ end
+ end
+
+ def acosh(z)
+ if Complex.generic?(z) and z >= 1
+ acosh!(z)
+ else
+ log(z + sqrt(z * z - 1.0))
+ end
+ end
+
+ def asinh(z)
+ if Complex.generic?(z)
+ asinh!(z)
+ else
+ log(z + sqrt(1.0 + z * z))
+ end
+ end
+
+ def atanh(z)
+ if Complex.generic?(z) and z >= -1 and z <= 1
+ atanh!(z)
+ else
+ log((1.0 + z) / (1.0 - z)) / 2.0
+ end
+ end
+
+ module_function :exp!
+ module_function :exp
+ module_function :log!
+ module_function :log
+ module_function :log10!
+ module_function :log10
+ module_function :sqrt!
+ module_function :sqrt
+
+ module_function :sin!
+ module_function :sin
+ module_function :cos!
+ module_function :cos
+ module_function :tan!
+ module_function :tan
+
+ module_function :sinh!
+ module_function :sinh
+ module_function :cosh!
+ module_function :cosh
+ module_function :tanh!
+ module_function :tanh
+
+ module_function :asin!
+ module_function :asin
+ module_function :acos!
+ module_function :acos
+ module_function :atan!
+ module_function :atan
+ module_function :atan2!
+ module_function :atan2
+
+ module_function :asinh!
+ module_function :asinh
+ module_function :acosh!
+ module_function :acosh
+ module_function :atanh!
+ module_function :atanh
+
+end
diff --git a/lib/complex.rb b/lib/complex.rb
index 9d926023a7..a585e95d97 100644
--- a/lib/complex.rb
+++ b/lib/complex.rb
@@ -1,3 +1,8 @@
+require 'cmath'
+
+Math = CMath
+
+=begin
module Math
alias exp! exp
@@ -219,3 +224,4 @@ module Math
module_function :atanh
end
+=end
diff --git a/lib/rational.rb b/lib/rational.rb
index 87c5d3f111..24774c357b 100644
--- a/lib/rational.rb
+++ b/lib/rational.rb
@@ -4,6 +4,7 @@ class Fixnum
alias power! **
alias rpower **
+ alias rdiv quo
end
@@ -13,5 +14,6 @@ class Bignum
alias power! **
alias rpower **
+ alias rdiv quo
end
diff --git a/math.c b/math.c
index 1f78d98a55..815d9e72ff 100644
--- a/math.c
+++ b/math.c
@@ -50,7 +50,7 @@ domain_check(double x, char *msg)
*
*/
-static VALUE
+VALUE
math_atan2(VALUE obj, VALUE y, VALUE x)
{
Need_Float2(y, x);
@@ -66,7 +66,7 @@ math_atan2(VALUE obj, VALUE y, VALUE x)
* -1..1.
*/
-static VALUE
+VALUE
math_cos(VALUE obj, VALUE x)
{
Need_Float(x);
@@ -81,7 +81,7 @@ math_cos(VALUE obj, VALUE x)
* -1..1.
*/
-static VALUE
+VALUE
math_sin(VALUE obj, VALUE x)
{
Need_Float(x);
@@ -172,7 +172,7 @@ cosh(double x)
* Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
*/
-static VALUE
+VALUE
math_cosh(VALUE obj, VALUE x)
{
Need_Float(x);
@@ -196,7 +196,7 @@ sinh(double x)
* radians).
*/
-static VALUE
+VALUE
math_sinh(VALUE obj, VALUE x)
{
Need_Float(x);
@@ -285,7 +285,7 @@ math_atanh(VALUE obj, VALUE x)
* Returns e**x.
*/
-static VALUE
+VALUE
math_exp(VALUE obj, VALUE x)
{
Need_Float(x);
@@ -311,7 +311,7 @@ math_exp(VALUE obj, VALUE x)
* of logarithm.
*/
-static VALUE
+VALUE
math_log(int argc, VALUE *argv)
{
VALUE x, base;
@@ -388,7 +388,7 @@ math_log10(VALUE obj, VALUE x)
* Returns the non-negative square root of <i>numeric</i>.
*/
-static VALUE
+VALUE
math_sqrt(VALUE obj, VALUE x)
{
double d;
diff --git a/rational.c b/rational.c
index de5c7867c3..2cfe9288be 100644
--- a/rational.c
+++ b/rational.c
@@ -777,13 +777,9 @@ nurat_mul(VALUE self, VALUE other)
}
}
-#define id_to_r rb_intern("to_r")
-#define f_to_r(x) rb_funcall(x, id_to_r, 0)
-
static VALUE
nurat_div(VALUE self, VALUE other)
{
- again:
switch (TYPE(other)) {
case T_FIXNUM:
case T_BIGNUM:
@@ -1407,6 +1403,9 @@ string_to_r(VALUE self)
return rb_rational_new1(INT2FIX(0));
}
+#define id_to_r rb_intern("to_r")
+#define f_to_r(x) rb_funcall(x, id_to_r, 0)
+
static VALUE
nurat_s_convert(int argc, VALUE *argv, VALUE klass)
{