mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/cmath.rb: new.
* 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:
parent
be710a0391
commit
c08b5dfb81
7 changed files with 269 additions and 132 deletions
10
ChangeLog
10
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>
|
Sat Apr 5 05:50:57 2008 Eric Hodel <drbrain@segment7.net>
|
||||||
|
|
||||||
* lib/rdoc/parsers/parse_rb.rb: Fix uninitialized variable warnings.
|
* lib/rdoc/parsers/parse_rb.rb: Fix uninitialized variable warnings.
|
||||||
|
|
137
complex.c
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);
|
return rb_funcall2(rb_cComplex, id_convert, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
extern VALUE math_atan2(VALUE obj, VALUE x, VALUE y);
|
||||||
/* the following code is copied from math.c */
|
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 m_atan2_bang(x,y) math_atan2(Qnil,x,y)
|
||||||
|
#define m_cos_bang(x) math_cos(Qnil,x)
|
||||||
#define Need_Float(x) (x) = rb_Float(x)
|
#define m_cosh_bang(x) math_cosh(Qnil,x)
|
||||||
#define Need_Float2(x,y) do {\
|
#define m_exp_bang(x) math_exp(Qnil,x)
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
m_cos_bang(VALUE x)
|
m_log_bang(VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float(x);
|
return math_log(1, &x);
|
||||||
return DOUBLE2NUM(cos(RFLOAT_VALUE(x)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE m_cos_bang(VALUE);
|
#define m_sin_bang(x) math_sin(Qnil,x)
|
||||||
static VALUE m_cosh_bang(VALUE);
|
#define m_sinh_bang(x) math_sinh(Qnil,x)
|
||||||
static VALUE m_sin_bang(VALUE);
|
#define m_sqrt_bang(x) math_sqrt(Qnil,x)
|
||||||
static VALUE m_sinh_bang(VALUE);
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
m_cos(VALUE x)
|
m_cos(VALUE x)
|
||||||
|
@ -531,47 +513,6 @@ m_cos(VALUE x)
|
||||||
m_sinh_bang(dat->image)));
|
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
|
static VALUE
|
||||||
m_sin(VALUE x)
|
m_sin(VALUE x)
|
||||||
{
|
{
|
||||||
|
@ -587,33 +528,6 @@ m_sin(VALUE x)
|
||||||
m_sinh_bang(dat->image)));
|
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
|
static VALUE
|
||||||
m_sqrt(VALUE x)
|
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
|
static VALUE
|
||||||
nucomp_s_polar(VALUE klass, VALUE abs, VALUE arg)
|
nucomp_s_polar(VALUE klass, VALUE abs, VALUE arg)
|
||||||
{
|
{
|
||||||
|
|
223
lib/cmath.rb
Normal file
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
|
module Math
|
||||||
|
|
||||||
alias exp! exp
|
alias exp! exp
|
||||||
|
@ -219,3 +224,4 @@ module Math
|
||||||
module_function :atanh
|
module_function :atanh
|
||||||
|
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Fixnum
|
||||||
|
|
||||||
alias power! **
|
alias power! **
|
||||||
alias rpower **
|
alias rpower **
|
||||||
|
alias rdiv quo
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -13,5 +14,6 @@ class Bignum
|
||||||
|
|
||||||
alias power! **
|
alias power! **
|
||||||
alias rpower **
|
alias rpower **
|
||||||
|
alias rdiv quo
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
16
math.c
16
math.c
|
@ -50,7 +50,7 @@ domain_check(double x, char *msg)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_atan2(VALUE obj, VALUE y, VALUE x)
|
math_atan2(VALUE obj, VALUE y, VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float2(y, x);
|
Need_Float2(y, x);
|
||||||
|
@ -66,7 +66,7 @@ math_atan2(VALUE obj, VALUE y, VALUE x)
|
||||||
* -1..1.
|
* -1..1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_cos(VALUE obj, VALUE x)
|
math_cos(VALUE obj, VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float(x);
|
Need_Float(x);
|
||||||
|
@ -81,7 +81,7 @@ math_cos(VALUE obj, VALUE x)
|
||||||
* -1..1.
|
* -1..1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_sin(VALUE obj, VALUE x)
|
math_sin(VALUE obj, VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float(x);
|
Need_Float(x);
|
||||||
|
@ -172,7 +172,7 @@ cosh(double x)
|
||||||
* Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
|
* Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_cosh(VALUE obj, VALUE x)
|
math_cosh(VALUE obj, VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float(x);
|
Need_Float(x);
|
||||||
|
@ -196,7 +196,7 @@ sinh(double x)
|
||||||
* radians).
|
* radians).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_sinh(VALUE obj, VALUE x)
|
math_sinh(VALUE obj, VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float(x);
|
Need_Float(x);
|
||||||
|
@ -285,7 +285,7 @@ math_atanh(VALUE obj, VALUE x)
|
||||||
* Returns e**x.
|
* Returns e**x.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_exp(VALUE obj, VALUE x)
|
math_exp(VALUE obj, VALUE x)
|
||||||
{
|
{
|
||||||
Need_Float(x);
|
Need_Float(x);
|
||||||
|
@ -311,7 +311,7 @@ math_exp(VALUE obj, VALUE x)
|
||||||
* of logarithm.
|
* of logarithm.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_log(int argc, VALUE *argv)
|
math_log(int argc, VALUE *argv)
|
||||||
{
|
{
|
||||||
VALUE x, base;
|
VALUE x, base;
|
||||||
|
@ -388,7 +388,7 @@ math_log10(VALUE obj, VALUE x)
|
||||||
* Returns the non-negative square root of <i>numeric</i>.
|
* Returns the non-negative square root of <i>numeric</i>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
math_sqrt(VALUE obj, VALUE x)
|
math_sqrt(VALUE obj, VALUE x)
|
||||||
{
|
{
|
||||||
double d;
|
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
|
static VALUE
|
||||||
nurat_div(VALUE self, VALUE other)
|
nurat_div(VALUE self, VALUE other)
|
||||||
{
|
{
|
||||||
again:
|
|
||||||
switch (TYPE(other)) {
|
switch (TYPE(other)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
|
@ -1407,6 +1403,9 @@ string_to_r(VALUE self)
|
||||||
return rb_rational_new1(INT2FIX(0));
|
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
|
static VALUE
|
||||||
nurat_s_convert(int argc, VALUE *argv, VALUE klass)
|
nurat_s_convert(int argc, VALUE *argv, VALUE klass)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue