Class: Interval::Simple
- Includes:
- Enumerable
- Defined in:
- lib/interval.rb
Overview
Implements simple intervals. A simple interval is an interval with a single component, i.e., a connected set of real numbers (extended with plus and minus infinity.)
Constant Summary
Constants inherited from Interval
E, NewtonOptions, PI
Instance Attribute Summary collapse
-
#inf ⇒ Object
readonly
Returns the value of attribute inf.
-
#sup ⇒ Object
readonly
Returns the value of attribute sup.
Instance Method Summary collapse
-
#**(n) ⇒ Object
Implements Interval’s power operator.
-
#-@ ⇒ Object
Unitary minus.
-
#==(other) ⇒ Object
Two simple intervals are equal if they have same inf and sup.
-
#add(other) ⇒ Object
Used to implement Interval’s plus operator (+).
-
#atan ⇒ Object
Implements Interval#atan.
-
#components ⇒ Object
Return an array with one element, itself.
-
#construction ⇒ Object
Overrides Interval#construction.
-
#cos ⇒ Object
Implements Interval#cos.
-
#cosh ⇒ Object
Implements Interval#cosh.
-
#degenerate? ⇒ Boolean
Implements Interval#degenerate?.
-
#dsub(other) ⇒ Object
Dependent subtraction, i.e., the inverse of the addition.
-
#each {|_self| ... } ⇒ Object
Implements Enumerable#each.
-
#exp ⇒ Object
Implements Interval#exp.
-
#extrema ⇒ Object
Returns the array with inf and sup.
-
#include?(x) ⇒ Boolean
Implements Interval#include?.
-
#initialize(a, b = a) ⇒ Simple
constructor
Constructs a simple interval, with given lower and upper bounds.
-
#intersect(other) ⇒ Object
Implements Interval’s & operator.
-
#inverse ⇒ Object
Implements Interval#inverse.
-
#log ⇒ Object
Implements Interval#log.
-
#midpoint ⇒ Object
The point in the middle of the interval.
-
#multiply(other) ⇒ Object
Used to implement Interval’s multiplicative operator (*).
-
#number ⇒ Object
If the interval is degenerate, return its only element, else raise an exception.
-
#sharp? ⇒ Boolean
Implements Interval#sharp?.
-
#simple? ⇒ Boolean
Implements Interval#simple?, returning true.
-
#sin ⇒ Object
Implements Interval#sin.
-
#sinh ⇒ Object
Implements Interval#sinh.
-
#tan ⇒ Object
Implement Interval#tan.
-
#width ⇒ Object
The interval’s width is sup - inf.
Methods inherited from Interval
#&, #*, #+, #-, #/, [], #coerce, #empty?, eval, #hull, #inspect, #newton, #op, sum, #to_interval, #to_s, union, #|
Constructor Details
#initialize(a, b = a) ⇒ Simple
476 477 478 479 480 481 482 483 484 485 |
# File 'lib/interval.rb', line 476 def initialize (a, b = a) raise ArgumentError, "Extrema must be numeric: #{[a,b].uniq.inspect}" unless Numeric === a && Numeric === b if (a.respond_to?(:nan?) && a.nan? ) || (b.respond_to?(:nan?) && b.nan?) @inf, @sup = -Infinity, Infinity else @inf, @sup = a, b end freeze end |
Instance Attribute Details
#inf ⇒ Object (readonly)
Returns the value of attribute inf.
455 456 457 |
# File 'lib/interval.rb', line 455 def inf @inf end |
#sup ⇒ Object (readonly)
Returns the value of attribute sup.
456 457 458 |
# File 'lib/interval.rb', line 456 def sup @sup end |
Instance Method Details
#**(n) ⇒ Object
Implements Interval’s power operator.
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
# File 'lib/interval.rb', line 601 def ** (n) # :nodoc: if n < 0 (self ** -n).inverse elsif inf > 0 self.class.new( FPU::down { FPU.power(inf, n) }, FPU::up { FPU.power(sup, n) }) elsif sup < 0 if (-1) ** n > 0 (-self)**n else - (-self)**n end elsif (-1) ** n > 0 self.class.new(0, FPU::up {[FPU.power(inf, n), FPU.power(sup, n)]}.max ) else self.class.new( FPU::down { FPU.power(inf, n) }, FPU::up { FPU.power(sup, n) }) end end |
#-@ ⇒ Object
Unitary minus.
555 556 557 |
# File 'lib/interval.rb', line 555 def -@ # :nodoc: self.class.new(-sup,-inf) end |
#==(other) ⇒ Object
Two simple intervals are equal if they have same inf and sup.
498 499 500 |
# File 'lib/interval.rb', line 498 def == (other) self.class == other.class && inf == other.inf && sup == other.sup end |
#add(other) ⇒ Object
Used to implement Interval’s plus operator (+).
548 549 550 551 552 |
# File 'lib/interval.rb', line 548 def add (other) self.class.new( FPU.down {inf + other.inf}, FPU.up {sup + other.sup}) end |
#atan ⇒ Object
Implements Interval#atan
652 653 654 |
# File 'lib/interval.rb', line 652 def atan #:nodoc: self.class.new(FPU.atan_down(inf), FPU.atan_up(sup)) end |
#components ⇒ Object
Return an array with one element, itself.
467 468 469 |
# File 'lib/interval.rb', line 467 def components [self] end |
#construction ⇒ Object
Overrides Interval#construction
488 489 490 |
# File 'lib/interval.rb', line 488 def construction # :nodoc: extrema.uniq end |
#cos ⇒ Object
Implements Interval#cos
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
# File 'lib/interval.rb', line 684 def cos #:nodoc: return Interval[-1,1] if inf.abs == Infinity || sup.abs == Infinity p = inf.divmod(Math::PI).first.to_i self.class.new( if include?((2*((p-1).div(2))+3) * Math::PI) -1 else [FPU.cos_down(inf), FPU.cos_down(sup)].min end, if include?((2*(p.div(2))+2) * Math::PI) +1 else [FPU.cos_up(inf), FPU.cos_up(sup)].max end) end |
#cosh ⇒ Object
Implements Interval#cosh
673 674 675 676 677 678 679 680 681 |
# File 'lib/interval.rb', line 673 def cosh #:nodoc: if inf >=0 self.class.new(FPU.cosh_down(inf), FPU.cosh_up(sup)) elsif sup <= 0 self.class.new(FPU.cosh_down(sup), FPU.cosh_up(inf)) else self.class.new(0,FPU.cosh_up([-inf,sup].max)) end end |
#degenerate? ⇒ Boolean
Implements Interval#degenerate?
642 643 644 |
# File 'lib/interval.rb', line 642 def degenerate? # :nodoc: inf == sup end |
#dsub(other) ⇒ Object
565 566 567 568 569 |
# File 'lib/interval.rb', line 565 def dsub(other) self.class.new( FPU.down{inf - other.inf}, FPU.up {sup - other.sup}) end |
#each {|_self| ... } ⇒ Object
Implements Enumerable#each
461 462 463 464 |
# File 'lib/interval.rb', line 461 def each yield(self) self end |
#exp ⇒ Object
Implements Interval#exp
647 648 649 |
# File 'lib/interval.rb', line 647 def exp #:nodoc: self.class.new(FPU.exp_down(inf), FPU.exp_up(sup)) end |
#extrema ⇒ Object
Returns the array with inf and sup.
Interval[1,2].extrema # => [1, 2]
511 512 513 |
# File 'lib/interval.rb', line 511 def extrema [inf,sup] end |
#include?(x) ⇒ Boolean
Implements Interval#include?.
503 504 505 |
# File 'lib/interval.rb', line 503 def include?(x) # :nodoc: inf <= x && x <= sup end |
#intersect(other) ⇒ Object
Implements Interval’s & operator.
624 625 626 |
# File 'lib/interval.rb', line 624 def intersect (other) self.class.new([inf,other.inf].max, [sup,other.sup].min) end |
#inverse ⇒ Object
Implements Interval#inverse.
588 589 590 591 592 593 594 595 596 597 598 |
# File 'lib/interval.rb', line 588 def inverse # :nodoc: if include?(0) then Interval[ [-Infinity, FPU::up { inf == 0 ? -Infinity : inf**-1 }], [FPU::down { sup == 0 ? Infinity : sup**-1 }, Infinity]] else self.class.new( FPU::down { sup ** -1 }, FPU::up { inf ** -1 }) end end |
#log ⇒ Object
Implements Interval#log
662 663 664 665 666 667 668 669 670 |
# File 'lib/interval.rb', line 662 def log #:nodoc: if inf >= 0 self.class.new(FPU.log_down(inf), FPU.log_up(sup)) elsif sup >= 0 self.class.new(-Infinity, FPU.log_up(sup)) else Interval[] end end |
#midpoint ⇒ Object
The point in the middle of the interval.
Interval[1,3].midpoint # => 2.0
528 529 530 |
# File 'lib/interval.rb', line 528 def midpoint (inf + sup) * 2 **-1 end |
#multiply(other) ⇒ Object
Used to implement Interval’s multiplicative operator (*).
572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/interval.rb', line 572 def multiply (other) self.class.new( FPU.down { [inf * other.inf, inf * other.sup, sup * other.inf, sup * other.sup]}.min, FPU.up { [inf * other.inf, inf * other.sup, sup * other.inf, sup * other.sup]}.max) # min and max fail if any of the products is a NaN, which can only # be generated by 0 * Infinity. In this case, the result is the # whole R-star. rescue ArgumentError self.class.new(-Infinity, Infinity) end |
#number ⇒ Object
539 540 541 542 543 544 545 |
# File 'lib/interval.rb', line 539 def number if inf == sup inf else raise Exception::Nondegenerate, self end end |
#sharp? ⇒ Boolean
Implements Interval#sharp?
629 630 631 632 633 634 635 636 637 638 639 |
# File 'lib/interval.rb', line 629 def sharp? # :nodoc: w = width if w == 0 true elsif w.kind_of?(Float) && (inf >= 0 || sup <= 0) s1, s2 = extrema.map{|x| x.abs}.sort s1 + s1.to_f.ulp == s2 else false end end |
#simple? ⇒ Boolean
Implements Interval#simple?, returning true.
493 494 495 |
# File 'lib/interval.rb', line 493 def simple? # :nodoc: true end |
#sin ⇒ Object
Implements Interval#sin
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 |
# File 'lib/interval.rb', line 701 def sin #:nodoc: return Interval[-1,1] if inf.abs == Infinity || sup.abs == Infinity q = inf.divmod(Math::PI/2).first.to_i p = (q-1).div(2) self.class.new( if include?((2*((p-1).div(2))+3.5) * Math::PI) -1 else [FPU.sin_down(inf), FPU.sin_down(sup)].min end, if include?((2*(p.div(2))+2.5) * Math::PI) +1 else [FPU.sin_up(inf), FPU.sin_up(sup)].max end) end |
#sinh ⇒ Object
Implements Interval#sinh
657 658 659 |
# File 'lib/interval.rb', line 657 def sinh #:nodoc: self.class.new(FPU.sinh_down(inf), FPU.sinh_up(sup)) end |
#tan ⇒ Object
Implement Interval#tan
719 720 721 722 723 724 725 726 727 728 729 |
# File 'lib/interval.rb', line 719 def tan #:nodoc: q = inf.divmod(Math::PI/2).first.to_i p = (q-1).div(2) if include?(Math::PI * (p+2.5)) self.class.new(-Infinity,Infinity) elsif include?(Math::PI * (p+1.5)) Interval[[-Infinity,FPU.tan_up(sup)],[FPU.tan_down(inf),Infinity]] else self.class.new(FPU.tan_down(inf),FPU.tan_up(sup)) end end |