class HpSqrt

Constants

VERSION

Attributes

terms[R]

Public Class Methods

create(v) click to toggle source
# File lib/hpsqrt.rb, line 270
def self.create(v)
  if self===v
    v
  else
    number(v)
  end
end
inspect_mode() click to toggle source
# File lib/hpsqrt.rb, line 10
def self.inspect_mode
  @@inspect_mode
end
inspect_mode=(v) click to toggle source
# File lib/hpsqrt.rb, line 14
def self.inspect_mode=(v)
  @@inspect_mode = v
end
new(terms) click to toggle source
# File lib/hpsqrt.rb, line 21
def initialize(terms)
  @terms = terms.freeze
  @cache = {}
  freeze
end
number(v) click to toggle source
# File lib/hpsqrt.rb, line 278
def self.number(v)
  if v!=0
    new({Term.new(number: v) => 1})
  else
    zero
  end
end
sqrt(v) click to toggle source
# File lib/hpsqrt.rb, line 286
def self.sqrt(v)
  if self===v
    v = v.to_rc
  end
  if v!=0
    new({Term.new(sqrt: v) => 1})
  else
    zero
  end
end
zero() click to toggle source
# File lib/hpsqrt.rb, line 297
def self.zero
  new({})
end

Public Instance Methods

*(other) click to toggle source
# File lib/hpsqrt.rb, line 56
def *(other)
  other = self.class.create(other)

  terms = {}
  @terms.each {|t1, c1|
    other.terms.each {|t2, c2|
      t = t1 * t2
      c = c1 * c2

      terms[t] ||= 0
      terms[t] += c
    }
  }
  terms.delete_if {|t,c| c==0}

  self.class.new(terms)
end
**(other) click to toggle source
# File lib/hpsqrt.rb, line 90
def **(other)
  other = self.class.create(other)

  if other.integer?
    result = self.class.create(1)
    other_i = other.real.to_i
    other_i.abs.times {|i|
      result *= self
    }
    if other_i<0
      result = Rational(1, result)
    end
    result
  else
    self.class.number(self.to_rc ** other.to_rc)
  end
end
+(other) click to toggle source
# File lib/hpsqrt.rb, line 33
def +(other)
  other = self.class.create(other)

  terms = @terms.merge(other.terms) {|t, c1, c2|
    c1 + c2
  }
  terms.delete_if {|t,c| c==0}

  self.class.new(terms)
end
-(other) click to toggle source
# File lib/hpsqrt.rb, line 44
def -(other)
  other = self.class.create(other)

  other_terms = other.terms.map{|t,c| [t, -c]}.to_h
  terms = @terms.merge(other_terms) {|t, c1, c2|
    c1 + c2
  }
  terms.delete_if {|t,c| c==0}

  self.class.new(terms)
end
-@() click to toggle source
# File lib/hpsqrt.rb, line 28
def -@
  terms = @terms.map{|t,c| [t, -c]}.to_h
  self.class.new(terms)
end
/(other) click to toggle source
# File lib/hpsqrt.rb, line 74
def /(other)
  other = self.class.create(other)
  other_inv = Term.new(number: Rational(1, other.to_rc))

  terms = {}
  @terms.each {|t, c|
    t *= other_inv

    terms[t] ||= 0
    terms[t] += c
  }
  terms.delete_if {|t,c| c==0}

  self.class.new(terms)
end
<=>(other) click to toggle source
# File lib/hpsqrt.rb, line 122
def <=>(other)
  if !(Numeric===other)
    nil
  elsif self==other
    0
  elsif !self.imag.zero? || !other.imag.zero?
    nil
  else
    self.real <=> other.real
  end
end
==(other) click to toggle source
Calls superclass method
# File lib/hpsqrt.rb, line 112
def ==(other)
  if self.class==other
    self.to_rc==other.to_rc
  elsif Numeric===other
    self.to_rc==other
  else
    super.==(other)
  end
end
angle()
Alias for: arg
arg() click to toggle source
# File lib/hpsqrt.rb, line 142
def arg
  to_c.arg
end
Also aliased as: angle, phase
coerce(other) click to toggle source
# File lib/hpsqrt.rb, line 108
def coerce(other)
  [self.class.create(other), self]
end
complex?() click to toggle source
# File lib/hpsqrt.rb, line 258
def complex?
  !to_rc.imag.zero?
end
expr() click to toggle source
# File lib/hpsqrt.rb, line 196
def expr
  @cache[:expr] ||= begin
    value_to_s = -> (v) {
      if Complex===v && v.imag.zero?
        v = v.real
      end
      if Rational===v && v.denominator==1
        v = v.numerator
      end
      v = v.to_s
      if v !~ /^[\d\.]+$/
        v = "(%s)" % v
      end
      v
    }

    result = @terms.map {|t, c|
      n = t.number * c
      s = t.sqrt

      if s!=1
        if n==1
          "\u221A%s" % value_to_s[s]
        elsif 0<n.real
          "%s\u221A%s" % [value_to_s[n], value_to_s[s]]
        elsif n==-1
          "(-\u221A%s)" % value_to_s[s]
        else
          "(%s\u221A%s)" % [value_to_s[n], value_to_s[s]]
        end
      else
        value_to_s[n]
      end
    }

    if 0<result.length
      result.join(" + ")
    else
      "0"
    end
  end
end
float?() click to toggle source
# File lib/hpsqrt.rb, line 266
def float?
  to_rc.imag.zero? && to_rc.real.denominator!=1
end
imag() click to toggle source
# File lib/hpsqrt.rb, line 167
def imag
  to_c.imag
end
Also aliased as: imaginary
imaginary()
Alias for: imag
inspect() click to toggle source
# File lib/hpsqrt.rb, line 239
def inspect
  to_s
end
integer?() click to toggle source
# File lib/hpsqrt.rb, line 262
def integer?
  to_rc.imag.zero? && to_rc.real.denominator==1
end
phase()
Alias for: arg
polar() click to toggle source
# File lib/hpsqrt.rb, line 138
def polar
  to_c.polar
end
real() click to toggle source
# File lib/hpsqrt.rb, line 163
def real
  to_c.real
end
real?() click to toggle source
# File lib/hpsqrt.rb, line 254
def real?
  false
end
rect() click to toggle source
# File lib/hpsqrt.rb, line 134
def rect
  to_c.rect
end
to_c() click to toggle source
# File lib/hpsqrt.rb, line 159
def to_c
  @cache[:to_c] ||= Complex(to_rc.real.to_f, to_rc.imag.to_f)
end
to_f() click to toggle source
# File lib/hpsqrt.rb, line 180
def to_f
  if imag.zero?
    real.to_f
  else
    raise RangeError, "can't convert %s into Float" % to_c
  end
end
to_i() click to toggle source
# File lib/hpsqrt.rb, line 172
def to_i
  if imag.zero?
    real.to_i
  else
    raise RangeError, "can't convert %s into Integer" % to_c
  end
end
to_r() click to toggle source
# File lib/hpsqrt.rb, line 188
def to_r
  if to_rc.imag.zero?
    to_rc.real
  else
    raise RangeError, "can't convert %s into Rational" % to_rc
  end
end
to_rc() click to toggle source
# File lib/hpsqrt.rb, line 148
def to_rc
  @cache[:to_rc] ||= @terms.map {|t, c|
    nc = Complex(t.number.real.to_r, t.number.imag.to_r)

    sc = Math.sqrt(Complex(t.sqrt))
    sc = Complex(sc.real.to_r, sc.imag.to_r)

    nc * sc * c
  }.sum(Complex(0.to_r, 0.to_r))
end
to_s() click to toggle source
# File lib/hpsqrt.rb, line 243
def to_s
  case @@inspect_mode
  when INSPECT_MODE::VALUE
    to_c.to_s
  when INSPECT_MODE::EXPR
    expr
  else
    "#<%s:0x%016x value=(%s) expr=(%s)>" % [self.class.name, self.object_id, to_c, expr]
  end
end