* lib/complex.rb: depends lib/cmath.rb.

	* lib/rational.rb: added rdiv.

	* complex.c: removed some math functions.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15906 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tadf 2008-04-05 14:25:40 +00:00
Родитель be710a0391
Коммит c08b5dfb81
7 изменённых файлов: 269 добавлений и 132 удалений

Просмотреть файл

@ -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.

137
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 */
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);
#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;
}
}
#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)
{
@ -636,23 +550,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)
{

223
lib/cmath.rb Normal file
Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

16
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;

Просмотреть файл

@ -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)
{