Class: BigComplex

Inherits:
Object
  • Object
show all
Defined in:
lib/bigcomplex.rb

Overview

Author:

Instance Method Summary collapse

Constructor Details

#initialize(real_part = BigDecimal("0.0"), imag_part = BigDecimal("0.0")) ⇒ BigComplex

Creates a new BigComplex object.

Parameters:

  • real_part,imag_part (Fixnum, Bignum, String, Float, BigDecimal, BigComplex)

Raises:

  • TypeError If input is not one of the acceptable class types (acceptable_class_type?(type) == false)



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bigcomplex.rb', line 19

def initialize(real_part=BigDecimal("0.0"), imag_part=BigDecimal("0.0"))

  # If input is BigComplex, split the object to parts and return them as new objects
  if real_part.class == BigComplex then
    real_part = BigDecimal(real_part.real)
  end
  if imag_part.class == BigComplex then
    imag_part = BigDecimal(imag_part.imag)
  end

  if real_part.class == Complex then
    real_part = BigDecimal(real_part.real)
  end
  if imag_part.class == Complex then
    imag_part = BigDecimal(imag_part.imag)
  end

  # @return [BigDecimal]
  # @param [Fixnum, Bignum, String, Float, BigDecimal]
  # Converts values to BigDecimal to use for creating BigComplex objects. If input is a String and starts with letter, the converted value will be 0.
  def convert_values(val)
    case val
      when Fixnum, Bignum, Float then BigDecimal(val.to_s) # Ruby 1.9.3< does not accept Integer, but 1.9.3+ does
      when String then BigDecimal(val)
      when BigDecimal then val
      else return nil
    end
  end
  raise(TypeError, "Not a Fixnum/Bignum, String, Float or BigDecimal!") unless acceptable_class_type?(real_part.class) and acceptable_class_type?(imag_part.class)
  self.real = real_part
  self.imag = imag_part
end

Instance Method Details

#*(other) ⇒ BigComplex

Multiplies self with other and returns a new object.

Parameters:

  • other (Fixnum, String, Float, BigDecimal, BigComplex)

    The multiplicand

Returns:



88
89
90
91
92
93
94
95
96
# File 'lib/bigcomplex.rb', line 88

def *(other)
  case other
    when Fixnum, Float, Bignum, BigDecimal
      return BigComplex.new(self.real * other, self.imag * other)
    when BigComplex
      return BigComplex.new((self.real*other.real - self.imag*other.imag), (self.real*other.imag + self.imag*other.real))
    else raise TypeError, "Not a Fixnum/Bignum, Float, BigDecimal or BigComplex!"
  end
end

#**(other) ⇒ BigComplex

Raises self to the power of other and returns a new object. Works well for huge exponents.

Parameters:

  • other (Fixnum, String, Float, BigDecimal, BigComplex)

    The exponent

Returns:



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/bigcomplex.rb', line 128

def **(other)
  case other
    when Fixnum, Bignum, BigDecimal
      if other == 0 then
        return BigComplex.new(1.0, 0.0)
        fail "This line should not be reached" # being over-paranoid here
      end

      if other == 1 then
        return self
        fail "This line should not be reached"
      end

      if other < 0 then
        return BigComplex.new
        fail "This line should not be reached"
      end

      if (other.class == BigDecimal) && (other.to_i != other) then
        raise TypeError, 'BigDecimal with a Rational value'
      else
        other = other.to_i
      end

      binary_repr_of_exponent = other.to_s(2).reverse.split('').map { |x| x.to_i }
      base = self
      result = binary_repr_of_exponent.reduce(BigComplex.new(1,0)) do | memo, value |
        memo *= (value == 1 ? base : 1)
        base = base * base
        memo
      end
      return result # explicit return, just for visibility
    else raise TypeError, 'Not a Fixnum, Bignum or BigDecimal for exponent'
  end
end

#+(other) ⇒ BigComplex

Adds other to self and returns a new object.

Parameters:

  • other (Fixnum, String, Float, BigDecimal, BigComplex)

    The addend

Returns:



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/bigcomplex.rb', line 101

def +(other)
  # format the object
  # @todo Check if input is String and if it can be converted. Automatic coerce somewhere?
  case other
    when Fixnum, Float, Bignum, BigDecimal
      return BigComplex.new(self.real + other, self.imag)
    when BigComplex
      return BigComplex.new(self.real + other.real, self.real + other.imag)
    else raise TypeError, "Not a Fixnum/Bignum, Float, BigDecimal or BigComplex!"
  end
end

#-(other) ⇒ BigComplex

Subtracts other from self and returns a new object.

Parameters:

  • other (Fixnum, String, Float, BigDecimal, BigComplex)

    The subtrahend

Returns:



116
117
118
119
120
121
122
123
# File 'lib/bigcomplex.rb', line 116

def -(other)
  case other
    when Fixnum, Float, Bignum, BigDecimal
      return BigComplex.new(self.real - other, self.imag)
    when BigComplex
      return BigComplex.new(self.real - other.real, self.imag - other.imag)
  end
end

#==(other) ⇒ Boolean

Returns true if other.real == self.real and other.imag == self.imag (no type checking).

Parameters:

  • other (Fixnum, String, Float, BigDecimal, BigComplex)

Returns:

  • (Boolean)


81
82
83
# File 'lib/bigcomplex.rb', line 81

def ==(other)
  self.real == other.real and self.imag == other.imag
end

#acceptable_class_type?(class_type) ⇒ Boolean Also known as: act?

Checks if class_type is among the acceptable class types for creating a BigComplex object

Parameters:

  • (Fixnum, Bignum, String, Float, BigDecimal)

Returns:

  • (Boolean)


9
10
11
# File 'lib/bigcomplex.rb', line 9

def acceptable_class_type?(class_type)
  return [Fixnum, Bignum, String, Float, BigDecimal].include?(class_type)
end

#conjugateBigComplex

Returns the conjugate of self as new object

Returns:



166
167
168
# File 'lib/bigcomplex.rb', line 166

def conjugate
  BigComplex.new(self.real, -self.imag)
end

#convert_values(val) ⇒ BigDecimal

Converts values to BigDecimal to use for creating BigComplex objects. If input is a String and starts with letter, the converted value will be 0.

Parameters:

  • (Fixnum, Bignum, String, Float, BigDecimal)

Returns:

  • (BigDecimal)


39
40
41
42
43
44
45
46
# File 'lib/bigcomplex.rb', line 39

def convert_values(val)
  case val
    when Fixnum, Bignum, Float then BigDecimal(val.to_s) # Ruby 1.9.3< does not accept Integer, but 1.9.3+ does
    when String then BigDecimal(val)
    when BigDecimal then val
    else return nil
  end
end

#imagBigDecimal Also known as: imaginary

Returns:

  • (BigDecimal)


64
# File 'lib/bigcomplex.rb', line 64

def imag; return @imag; end

#imag=(val) ⇒ BigDecimal Also known as: imaginary=

Returns Modifies self.imaginary.

Parameters:

  • val (Fixnum, String, Float, BigDecimal, BigComplex)

Returns:

  • (BigDecimal)

    Modifies self.imaginary

Raises:

  • TypeError



69
# File 'lib/bigcomplex.rb', line 69

def imag=(val); return @imag = convert_values(val); end

#magnitudeBigDecimal

Returns the magnitude of self. It can be calculation heavy for large numbers

Returns:

  • (BigDecimal)


172
173
174
# File 'lib/bigcomplex.rb', line 172

def magnitude
  (self.real**2 + self.imag**2).sqrt(12) # uhh-ohh, need to ditch sqrt as of now, it is imprecise as well.
end

#realBigDecimal

Returns the real part of self

Parameters:

Returns:

  • (BigDecimal)


55
# File 'lib/bigcomplex.rb', line 55

def real; @real; end

#real=(val) ⇒ BigDecimal

Modifies self.real

Parameters:

  • val (Fixnum, String, Float, BigDecimal, BigComplex)

Returns:

  • (BigDecimal)

Raises:

  • TypeError



61
# File 'lib/bigcomplex.rb', line 61

def real=(val); return @real = convert_values(val); end

#to_cComplex, BigComplex

Converts self to Complex if it fits Complex’ boundaries. The method will not require the Complex library and if no Complex class is available, returns self. Some rubies contain Complex class by default, some not (ie: MRI 1.8.7)

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/bigcomplex.rb', line 178

def to_c
  begin
    dmy = Complex(1,2) # dummy Complex value
  rescue NoMethodError
    return self # Complex class is not available
  rescue
    return self # some other thing hit the fan
  end
  return Complex(self.real.to_i, self.imag.to_i) # there is no type/size check yet. Converting with to_i loses fractional part but keeps magnitude.
end