Skip to content

Commit

Permalink
- Improved the support for +/- Infinity.
Browse files Browse the repository at this point in the history
- Better blending of Complex numbers with rational numbers.
- pow(-n, float) returns a Complex number
- Added comparison support for +/- Infinity
  • Loading branch information
trizen committed Dec 27, 2015
1 parent a7913ac commit 1a507bb
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 97 deletions.
72 changes: 61 additions & 11 deletions lib/Sidef/Types/Number/Complex.pm
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ package Sidef::Types::Number::Complex {
}

sub get_value {
my $re = $_[0]->re->get_value;
my $im = $_[0]->im->get_value;
my $re = $_[0]->re;
my $im = $_[0]->im;

$re = "$re";
$im = "$im";

return $re if $im eq '0';
my $sign = '+';
Expand All @@ -87,7 +90,9 @@ package Sidef::Types::Number::Complex {
}

sub dump {
Sidef::Types::String::String->new("Complex(" . $_[0]->re->get_value . ", " . $_[0]->im->get_value . ")");
my $re = $_[0]->re;
my $im = $_[0]->im;
Sidef::Types::String::String->new("Complex($re, $im)");
}

sub get_constant {
Expand All @@ -108,22 +113,54 @@ package Sidef::Types::Number::Complex {
};
}

#
## Complex constants
#

sub pi {
my $pi = Math::MPFR::Rmpfr_init2($PREC);
Math::MPFR::Rmpfr_const_pi($pi, $ROUND);
my $cpi = Math::MPC::Rmpc_init2($PREC);
Math::MPC::Rmpc_set_fr($cpi, $pi, $ROUND);
_new($cpi);
my $cplx_pi = Math::MPC::Rmpc_init2($PREC);
Math::MPC::Rmpc_set_fr($cplx_pi, $pi, $ROUND);
_new($cplx_pi);
}

sub e {
my $pi = Math::MPFR::Rmpfr_init2($PREC);
Math::MPFR::Rmpfr_const_pi($pi, $ROUND);
my $cpi = Math::MPC::Rmpc_init2($PREC);
Math::MPC::Rmpc_set_fr($cpi, $pi, $ROUND);
_new($cpi);
state $one_f = (Math::MPFR::Rmpfr_init_set_ui(1, $ROUND))[0];
my $e = Math::MPFR::Rmpfr_init2($PREC);
Math::MPFR::Rmpfr_exp($e, $one_f, $ROUND);
my $cplx_e = Math::MPC::Rmpc_init2($PREC);
Math::MPC::Rmpc_set_fr($cplx_e, $e, $ROUND);
_new($cplx_e);
}

sub i {
state $i = do {
my $r = Math::MPC::Rmpc_init2($PREC);
Math::MPC::Rmpc_set_ui_ui($r, 0, 1, $ROUND);
_new($r);
};
}

sub phi {
state $one_f = (Math::MPFR::Rmpfr_init_set_ui(1, $ROUND))[0];
state $two_f = (Math::MPFR::Rmpfr_init_set_ui(2, $ROUND))[0];
state $five_f = (Math::MPFR::Rmpfr_init_set_ui(5, $ROUND))[0];

my $phi = Math::MPFR::Rmpfr_init2($PREC);
Math::MPFR::Rmpfr_sqrt($phi, $five_f, $ROUND);
Math::MPFR::Rmpfr_add($phi, $phi, $one_f, $ROUND);
Math::MPFR::Rmpfr_div($phi, $phi, $two_f, $ROUND);

my $cplx_phi = Math::MPC::Rmpc_init2($PREC);
Math::MPC::Rmpc_set_fr($cplx_phi, $phi, $ROUND);
_new($cplx_phi);
}

#
## Complex specific functions
#

sub abs {
my $mpfr = Math::MPFR::Rmpfr_init2($PREC);
Math::MPC::Rmpc_abs($mpfr, ${$_[0]}, $ROUND);
Expand Down Expand Up @@ -607,6 +644,19 @@ package Sidef::Types::Number::Complex {
: $Sidef::Types::Number::Number::MONE;
}

sub floor {
$_[0]->abs->floor;
}

sub ceil {
$_[0]->abs->ceil;
}

sub roundf {
my ($x, $prec) = @_;
$x->abs->roundf($prec);
}

{
no strict 'refs';

Expand Down
195 changes: 156 additions & 39 deletions lib/Sidef/Types/Number/Inf.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package Sidef::Types::Number::Inf {
use parent qw(
Sidef::Object::Object
Sidef::Convert::Convert
Sidef::Types::Number::Number
);

use overload
Expand All @@ -19,27 +20,40 @@ package Sidef::Types::Number::Inf {
bless \$r, __PACKAGE__;
};

require Sidef::Types::Number::Number;

state $ZERO = $Sidef::Types::Number::Number::ZERO;
state $ONE = $Sidef::Types::Number::Number::ONE;
state $MONE = $Sidef::Types::Number::Number::MONE;
state $NAN = $Sidef::Types::Number::Number::NAN;

if (not defined $ZERO or not defined $ONE or not defined $MONE or not defined $NAN) {
if (not defined $ZERO or not defined $ONE or not defined $MONE) {
die "Fatal error: can't load the Inf class!";
}

sub new { $INF }

sub get_value { 'Inf' }

sub add {
my ($x, $y) = @_;
ref($y) eq 'Sidef::Types::Number::Ninf' ? $NAN : $x;
ref($y) eq 'Sidef::Types::Number::Ninf' ? nan() : $x;
}

sub sub {
my ($x, $y) = @_;
ref($y) eq __PACKAGE__ ? $NAN : $x;
ref($y) eq __PACKAGE__ ? nan() : $x;
}

sub mul {
my ($x, $y) = @_;
ref($y) eq __PACKAGE__ and return $x;
$y->is_neg ? $x->neg : $x;
}

sub div {
my ($x, $y) = @_;
if (ref($y) eq __PACKAGE__ or ref($y) eq 'Sidef::Types::Number::Ninf') {
return nan();
}
$y->is_neg ? $x->neg : $x;
}

sub is_pos {
Expand All @@ -50,29 +64,75 @@ package Sidef::Types::Number::Inf {
state $x = Sidef::Types::Bool::Bool->false;
}

sub neg {
sub nan {
state $x = Sidef::Types::Number::Nan->new;
}

*mod = \&nan;
*fmod = \&nan;

sub ninf {
state $x = Sidef::Types::Number::Ninf->new;
}

*neg = \&ninf;

sub min { $_[1] }
sub max { $_[0] }
sub inf { $_[0] }

*max = \&inf;
*abs = \&inf;
*sqrt = \&inf;
*cbrt = \&inf;
*root = \&inf;
*sqr = \&inf;
*log = \&inf;
*log2 = \&inf;
*log10 = \&inf;
*exp = \&inf;
*exp2 = \&inf;
*exp10 = \&inf;
*sinh = \&inf;
*asinh = \&inf;
*cosh = \&inf;
*acosh = \&inf;
*tan = \&inf;
*sec = \&inf;
*csc = \&inf;
*cot = \&inf;
*hypot = \&inf;
*gamma = \&inf;
*lgamma = \&inf;
*digamma = \&inf;
*eint = \&inf;
*li2 = \&inf;
*inc = \&inf;
*dec = \&inf;

sub zero { $ZERO }

*inv = \&zero;
*sin = \&zero;
*cos = \&zero;
*sech = \&zero;
*csch = \&zero;
*erfc = \&zero;

sub inv { $Sidef::Types::Number::Number::ZERO }
sub tanh { $ONE }

#
## sin(inf) = [-1, 1]
#
sub sin { $NAN }
*coth = \&tanh;
*zeta = \&tanh;
*erf = \&tanh;

#
## sinh(inf) = inf
## asin(inf) = -inf*i
#
sub sinh { $_[0] }
sub asin { state $x = Sidef::Types::Number::Complex->new(0, '-@inf@') }

#
## asin(inf) = -inf*i
## acos(inf) = inf*i
#
sub asin { state $x = Sidef::Types::Number::Complex->new(0, '-@inf@') }
sub acos { state $x = Sidef::Types::Number::Complex->new(0, '@inf@') }

#
## atan(inf) = pi/2
Expand All @@ -82,19 +142,16 @@ package Sidef::Types::Number::Inf {
}

#
## tanh(inf) = 1
#
sub tanh { $ONE }

#
## sqrt(inf) = inf
#
sub sqrt { $_[0] }

#
## inf^(1/3) = inf
## atanh(-inf) = -pi/2*i
#
sub cbrt { $_[0] }
sub atanh {
state $x = Sidef::Types::Number::Complex->new(
0,
Sidef::Types::Number::Number->pi->div(
Sidef::Types::Number::Number->new(-2)
)
);
}

sub times {
my ($x, $block) = @_;
Expand All @@ -111,24 +168,84 @@ package Sidef::Types::Number::Inf {

sub pow {
my ($x, $y) = @_;
$y->is_neg ? $ZERO : $y->is_zero ? nan() : $x;
}

ref($y) eq __PACKAGE__ and return $x;
ref($y) eq 'Sidef::Types::Number::Ninf' and return $ZERO;
#
## Comparisons
#

sub eq {
my ($x, $y) = @_;
if (ref($y) eq __PACKAGE__) {
state $z = Sidef::Types::Bool::Bool->true;
}
else {
state $z = Sidef::Types::Bool::Bool->false;
}
}

sub ne {
my ($x, $y) = @_;
if (ref($y) eq __PACKAGE__) {
state $z = Sidef::Types::Bool::Bool->false;
}
else {
state $z = Sidef::Types::Bool::Bool->true;
}
}

sub gt {
my ($x, $y) = @_;
if (ref($y) eq __PACKAGE__) {
state $z = Sidef::Types::Bool::Bool->false;
}
else {
state $z = Sidef::Types::Bool::Bool->true;
}
}

sub ge {
state $z = Sidef::Types::Bool::Bool->true;
}

Sidef::Types::Number::Number::_valid($y);
sub lt {
state $z = Sidef::Types::Bool::Bool->false;
}

my $sign = Math::GMPq::Rmpq_sgn($$y);
$sign < 0 ? $ZERO : $sign == 0 ? $NAN : $x;
sub le {
my ($x, $y) = @_;
if (ref($y) eq __PACKAGE__) {
state $z = Sidef::Types::Bool::Bool->true;
}
else {
state $z = Sidef::Types::Bool::Bool->false;
}
}

our $AUTOLOAD;
sub AUTOLOAD { $_[0] }
sub cmp {
my ($x, $y) = @_;
ref($y) eq __PACKAGE__ ? $ZERO : $ONE;
}

{
no strict 'refs';
*{__PACKAGE__ . '::' . '**'} = \&pow;
*{__PACKAGE__ . '::' . '+'} = \&add;
*{__PACKAGE__ . '::' . '-'} = \&sub;
*{__PACKAGE__ . '::' . '+'} = \&add;
*{__PACKAGE__ . '::' . '-'} = \&sub;
*{__PACKAGE__ . '::' . '*'} = \&mul;
*{__PACKAGE__ . '::' . '/'} = \&div;
*{__PACKAGE__ . '::' . '÷'} = \&div;
*{__PACKAGE__ . '::' . '%'} = \&mod;
*{__PACKAGE__ . '::' . '**'} = \&pow;
*{__PACKAGE__ . '::' . '++'} = \&inc;
*{__PACKAGE__ . '::' . '--'} = \&dec;
*{__PACKAGE__ . '::' . '=='} = \&eq;
*{__PACKAGE__ . '::' . '!='} = \&ne;
*{__PACKAGE__ . '::' . '>'} = \&gt;
*{__PACKAGE__ . '::' . '>='} = \&ge;
*{__PACKAGE__ . '::' . '<'} = \&lt;
*{__PACKAGE__ . '::' . '<='} = \&le;
*{__PACKAGE__ . '::' . '<=>'} = \&cmp;
}
}

Expand Down
Loading

0 comments on commit 1a507bb

Please sign in to comment.