Module: SY::Magnitude
- Includes:
- Comparable, ExpressibleInUnits
- Defined in:
- lib/sy/magnitude.rb
Overview
This module defines common assets of a magnitude – be it absolute (number of unit objects), or relative (magnitude difference).
Constant Summary
Constants included from ExpressibleInUnits
ExpressibleInUnits::COLLISION_WARNING, ExpressibleInUnits::REDEFINE_WARNING, ExpressibleInUnits::RecursionError
Instance Attribute Summary collapse
-
#amount ⇒ Object
(also: #in_standard_unit)
readonly
Returns the value of attribute amount.
-
#quantity ⇒ Object
readonly
Returns the value of attribute quantity.
Class Method Summary collapse
-
.absolute(of: nil, amount: nil) ⇒ Object
Constructs an absolute magnitude of a given quantity.
-
.difference(of: nil, amount: nil) ⇒ Object
Constructs a relative magnitude of a given quantity.
-
.of(quantity, amount: nil) ⇒ Object
Constructs a magnitude of a given quantity.
-
.one(of: nil) ⇒ Object
Magnitude 1 of a given quantity.
-
.zero(of: nil) ⇒ Object
Zero magnitude of a given quantity.
Instance Method Summary collapse
-
#%(m2) ⇒ Object
Percent operator (remainder after division).
-
#*(m2) ⇒ Object
Multiplication.
-
#**(exp) ⇒ Object
Exponentiation.
-
#+(m2) ⇒ Object
Addition.
-
#+@ ⇒ Object
Reframes the magnitude into its relative quantity.
-
#-(m2) ⇒ Object
Subtraction.
-
#-@ ⇒ Object
Reframes the magnitude into its relative quantity, with negative amount.
-
#/(m2) ⇒ Object
Division.
-
#<=>(m2) ⇒ Object
Three-way comparison operator of magnitudes.
-
#abs ⇒ Object
Absolute value of a magnitude (no reframe).
-
#absolute ⇒ Object
Computes absolute value and reframes into the absolute quantity.
-
#call(q2) ⇒ Object
Reframes a magnitude into a relative version of a given quantity.
-
#coerce(m2) ⇒ Object
Type coercion for magnitudes.
-
#eql?(other) ⇒ Boolean
Same magnitudes and same (#eql) quantities.
-
#in(m2) ⇒ Object
Gives the magnitude as a plain number in multiples of another magnitude, supplied as argument.
-
#inspect ⇒ Object
Inspect string of the magnitude.
-
#negative? ⇒ Boolean
True if amount is negative.
-
#nonnegative? ⇒ Boolean
Opposite of #negative?.
-
#reframe(q2) ⇒ Object
Reframes a magnitude into a different quantity.
-
#relative ⇒ Object
Reframes into the relative quantity.
-
#round(*args) ⇒ Object
Rounded value of a Magnitude: A new magnitude with rounded amount.
-
#to_magnitude ⇒ Object
Without arguments, it returns a new magnitude equal to self.
- #to_s(unit = quantity.units.first || quantity.standard_unit, number_format = default_amount_format) ⇒ Object
Methods included from ExpressibleInUnits
exponentiation_string, find_unit, included, included_in, known_units, method_family, #method_missing, prefix_method_string, #respond_to_missing?, unit_namespace
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class SY::ExpressibleInUnits
Instance Attribute Details
#amount ⇒ Object (readonly) Also known as: in_standard_unit
Returns the value of attribute amount.
55 56 57 |
# File 'lib/sy/magnitude.rb', line 55 def amount @amount end |
#quantity ⇒ Object (readonly)
Returns the value of attribute quantity.
55 56 57 |
# File 'lib/sy/magnitude.rb', line 55 def quantity @quantity end |
Class Method Details
.absolute(of: nil, amount: nil) ⇒ Object
Constructs an absolute magnitude of a given quantity.
10 11 12 |
# File 'lib/sy/magnitude.rb', line 10 def absolute( of: nil, amount: nil ) of.absolute.magnitude( amount ) end |
.difference(of: nil, amount: nil) ⇒ Object
Constructs a relative magnitude of a given quantity.
16 17 18 |
# File 'lib/sy/magnitude.rb', line 16 def difference( of: nil, amount: nil ) of.relative.magnitude( amount ) end |
.of(quantity, amount: nil) ⇒ Object
Constructs a magnitude of a given quantity.
22 23 24 |
# File 'lib/sy/magnitude.rb', line 22 def of( quantity, amount: nil ) quantity.magnitude( amount ) end |
.one(of: nil) ⇒ Object
Magnitude 1 of a given quantity.
34 35 36 |
# File 'lib/sy/magnitude.rb', line 34 def one( of: nil ) absolute of: of, amount: 1 end |
.zero(of: nil) ⇒ Object
Zero magnitude of a given quantity.
28 29 30 |
# File 'lib/sy/magnitude.rb', line 28 def zero( of: nil ) absolute of: of, amount: 0 end |
Instance Method Details
#%(m2) ⇒ Object
Percent operator (remainder after division)
177 178 179 180 181 |
# File 'lib/sy/magnitude.rb', line 177 def % m2 return magnitude amount % m2.amount if quantity == m2.quantity return self % m2.( quantity ) if quantity.coerces? m2.quantity apply_through_coerce :%, m2 end |
#*(m2) ⇒ Object
Multiplication.
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/sy/magnitude.rb', line 128 def * m2 case m2 when Numeric then magnitude amount * m2 # when SY::ZERO then # return magnitude 0 when Matrix then m2.map { |e| self * e } else ( quantity * m2.quantity ).magnitude( amount * m2.amount ) end end |
#**(exp) ⇒ Object
Exponentiation.
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/sy/magnitude.rb', line 158 def ** exp case exp when SY::Magnitude then raise SY::DimensionError, "Exponent must have zero dimension! " + "(exp given)" unless exp.dimension.zero? ( quantity ** exp.amount ).magnitude( amount ** exp.amount ) else ( quantity ** exp ).magnitude( amount ** exp ) end end |
#+(m2) ⇒ Object
Addition.
112 113 114 115 116 |
# File 'lib/sy/magnitude.rb', line 112 def + m2 return magnitude amount + m2.amount if quantity == m2.quantity return self + m2.( quantity ) if quantity.coerces? m2.quantity apply_through_coerce :+, m2 end |
#+@ ⇒ Object
Reframes the magnitude into its relative quantity.
88 89 90 |
# File 'lib/sy/magnitude.rb', line 88 def +@ quantity.relative.magnitude( amount ) end |
#-(m2) ⇒ Object
Subtraction.
120 121 122 123 124 |
# File 'lib/sy/magnitude.rb', line 120 def - m2 return magnitude amount - m2.amount if quantity == m2.quantity return self - m2.( quantity ) if quantity.coerces? m2.quantity apply_through_coerce :-, m2 end |
#-@ ⇒ Object
Reframes the magnitude into its relative quantity, with negative amount.
94 95 96 |
# File 'lib/sy/magnitude.rb', line 94 def -@ quantity.relative.magnitude( -amount ) end |
#/(m2) ⇒ Object
Division.
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/sy/magnitude.rb', line 143 def / m2 case m2 when Numeric then magnitude amount / m2 # when SY::ZERO then # raise ZeroDivisionError, "Attempt to divide #{self} by #{SY::ZERO}." when Matrix then amount / m2 * quantity.magnitude( 1 ) else ( quantity / m2.quantity ).magnitude( amount / m2.amount ) end end |
#<=>(m2) ⇒ Object
Three-way comparison operator of magnitudes.
49 50 51 52 53 |
# File 'lib/sy/magnitude.rb', line 49 def <=> m2 return amount <=> m2.amount if quantity == m2.quantity return self <=> m2.( quantity ) if quantity.coerces? m2.quantity apply_through_coerce :<=>, m2 end |
#abs ⇒ Object
Absolute value of a magnitude (no reframe).
100 101 102 |
# File 'lib/sy/magnitude.rb', line 100 def abs magnitude amount.abs end |
#absolute ⇒ Object
Computes absolute value and reframes into the absolute quantity.
76 77 78 |
# File 'lib/sy/magnitude.rb', line 76 def absolute quantity.absolute.magnitude( amount.abs ) end |
#call(q2) ⇒ Object
Reframes a magnitude into a relative version of a given quantity. (If absolute quantity is supplied as an argument, its relative colleague is used to reframe.)
229 230 231 232 233 234 |
# File 'lib/sy/magnitude.rb', line 229 def call q2 case q2 when SY::Quantity then q2.relative.read self when SY::Unit then q2.quantity.relative.read self else raise TypeError, "Unable to reframe into a #{q2.class}!" end end |
#coerce(m2) ⇒ Object
Type coercion for magnitudes.
185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/sy/magnitude.rb', line 185 def coerce m2 if m2.is_a? Numeric then return SY::Amount.relative.magnitude( m2 ), self elsif m2.is_a? Matrix then return m2 * SY::UNIT, self elsif quantity.coerces? m2.quantity then return m2.( quantity ), self else raise TypeError, "#{self} cannot be coerced into a #{m2.class}!" end end |
#eql?(other) ⇒ Boolean
Same magnitudes and same (#eql) quantities.
171 172 173 |
# File 'lib/sy/magnitude.rb', line 171 def eql? other quantity == other.quantity && amount == other.amount end |
#in(m2) ⇒ Object
Gives the magnitude as a plain number in multiples of another magnitude, supplied as argument. The quantities must match.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/sy/magnitude.rb', line 200 def in m2 case m2 when Symbol, String then begin self.in eval( "1.#{m2}" ).aT_kind_of SY::Magnitude # digest it rescue TypeError raise TypeError, "Evaluating 1.#{m2} does not result in a magnitude; " + "method collision with another library?" end when SY::Magnitude then quantity.measure( of: m2.quantity ).w.( amount ) / m2.amount else raise TypeError, "Unexpected type for Magnitude#in method! (#{m2.class})" end end |
#inspect ⇒ Object
Inspect string of the magnitude
310 311 312 |
# File 'lib/sy/magnitude.rb', line 310 def inspect "#<#{çς}: #{self} >" end |
#negative? ⇒ Boolean
True if amount is negative. Implicitly false for absolute quantities.
238 239 240 |
# File 'lib/sy/magnitude.rb', line 238 def negative? amount < 0 end |
#nonnegative? ⇒ Boolean
Opposite of #negative?. Implicitly true for absolute quantities.
244 245 246 |
# File 'lib/sy/magnitude.rb', line 244 def nonnegative? amount >= 0 end |
#reframe(q2) ⇒ Object
Reframes a magnitude into a different quantity. Dimension must match.
218 219 220 221 222 223 |
# File 'lib/sy/magnitude.rb', line 218 def reframe q2 case q2 when SY::Quantity then q2.read self when SY::Unit then q2.quantity.read self else raise TypeError, "Unable to reframe into a #{q2.class}!" end end |
#relative ⇒ Object
Reframes into the relative quantity.
82 83 84 |
# File 'lib/sy/magnitude.rb', line 82 def relative quantity.relative.magnitude( amount ) end |
#round(*args) ⇒ Object
Rounded value of a Magnitude: A new magnitude with rounded amount.
106 107 108 |
# File 'lib/sy/magnitude.rb', line 106 def round *args magnitude amount.round( *args ) end |
#to_magnitude ⇒ Object
Without arguments, it returns a new magnitude equal to self. If argument is given, it is treated as factor, by which the amount is to be muliplied.
317 318 319 |
# File 'lib/sy/magnitude.rb', line 317 def to_magnitude magnitude( amount ) end |
#to_s(unit = quantity.units.first || quantity.standard_unit, number_format = default_amount_format) ⇒ Object
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/sy/magnitude.rb', line 267 def to_s( unit=quantity.units.first || quantity.standard_unit, number_format=default_amount_format ) begin un = unit.short || unit.name if un then number = self.in unit number_ς = number_format % number prefix = '' exp = 1 # unit_presentation = prefix, unit, exp unit_ς = SY::SPS.( [ "#{prefix}#{unit.short}" ], [ exp ] ) [ number_ς, unit_ς ].join '.' else number = amount # otherwise, use units of component quantities ꜧ = quantity.composition.to_hash symbols, exponents = ꜧ.each_with_object Hash.new do |pair, memo| qnt, exp = pair if qnt.standard_unit.name std_unit = qnt.standard_unit memo[ std_unit.short || std_unit.name ] = exp else m = qnt.magnitude( 1 ).to_s memo[ m[2..-1] ] = exp number = m[0].to_i * number end end.to_a.transpose # assemble SPS unit_ς = SY::SPS.( symbols, exponents ) # interpolate number_ς = number_format % number return number_ς if unit_ς == '' || unit_ς == 'unit' [ number_ς, unit_ς ].join '.' end rescue fail number_ς = number_format % amount [ number_ς, "unit[#{quantity}]" ].join '.' end end |