Class: SY::Quantity
Overview
Quantity.
Constant Summary collapse
- RELATIVE_QUANTITY_NAME_SUFFIX =
name_set_hook do |name, new_instance, old_name|
new_instance.protect!; nameend
"±"
Instance Attribute Summary collapse
-
#composition ⇒ Object
readonly
Creates a composition from a dimension, or acts as composition getter if this has already been specified.
-
#dimension ⇒ Object
readonly
Returns the value of attribute dimension.
-
#units ⇒ Object
readonly
Returns the value of attribute units.
Class Method Summary collapse
-
.dimensionless(*args) ⇒ Object
(also: zero)
Dimensionless quantity constructor alias.
-
.of(*args) ⇒ Object
Dimension-based quantity constructor.
-
.standard(of: nil) ⇒ Object
Standard quantity.
Instance Method Summary collapse
-
#*(q2) ⇒ Object
Quantity multiplication.
-
#**(num) ⇒ Object
Quantity raising to a number.
-
#/(q2) ⇒ Object
Quantity division.
-
#absolute ⇒ Object
Absolute quantity related to this quantity.
-
#absolute? ⇒ Boolean
Is the quantity absolute? (Opposite of #relative?).
- #coerce(other) ⇒ Object
-
#coerces(*other_quantities) ⇒ Object
Quantities explicitly coerced by this quantity.
-
#coerces?(other) ⇒ Boolean
Is the quantity supplied as the argument coerced by this quantity?.
-
#colleague ⇒ Object
For an absolute quantity, colleague is the corresponding relative quantity.
-
#dimensionless? ⇒ Boolean
Is the quantity dimensionless?.
-
#initialize(relative: nil, composition: nil, of: nil, measure: nil, amount: nil, coerces: [], coerces_to: [], **nn) ⇒ Quantity
constructor
Standard constructor of a metrological quantity.
-
#inspect ⇒ Object
Inspect string.
-
#irreducible? ⇒ Boolean
Irreducible quantity is one which cannot or should not be reduced to its components in the process of quantity simplification.
-
#magnitude(amount) ⇒ Object
Constructs a absolute magnitude of this quantity.
-
#measure(of: nil) ⇒ Object
Creates a measure of a specified other quantity.
-
#new_standard_unit(amount: nil, measure: nil, **nn) ⇒ Object
Constructor of a new standard unit (replacing current @standard_unit).
-
#protect! ⇒ Object
Protects quantity from decomposition.
-
#protected? ⇒ Boolean
Protected quantity is not allowed to be decomposed in the process of quantity simplification.
-
#read(magnitude_of_other_quantity) ⇒ Object
Converts magnitude of another quantity to a magnitude of this quantity.
-
#relative ⇒ Object
Relative quantity related to this quantity.
-
#relative? ⇒ Boolean
Is the quantity relative?.
-
#set_colleague(q2) ⇒ Object
Acts as colleague setter.
-
#set_composition(comp) ⇒ Object
Acts as composition setter (dimension must match).
-
#set_measure(measure) ⇒ Object
Acts as setter of measure (of the pertinent standard quantity).
-
#simple? ⇒ Boolean
Simple quantity is one with simple composition.
-
#standard ⇒ Object
Returns the standard quantity for this quantity’s dimension.
-
#standard! ⇒ Object
Make the quantity standard for its dimension.
-
#standard? ⇒ Boolean
Is the dimension standard?.
-
#standard_unit ⇒ Object
Reader of standard unit.
-
#standardish? ⇒ Boolean
Is the dimension or its colleague standard?.
-
#to_s ⇒ Object
A string briefly describing the quantity.
-
#unit(**nn) ⇒ Object
Constructs a new unit of this quantity.
-
#unprotect! ⇒ Object
Unprotects quantity from decomposition.
-
#write(amount_of_this_quantity, other_quantity) ⇒ Object
Converts an amount of this quantity to a magnitude of other quantity.
Constructor Details
#initialize(relative: nil, composition: nil, of: nil, measure: nil, amount: nil, coerces: [], coerces_to: [], **nn) ⇒ Quantity
Standard constructor of a metrological quantity. A quantity may have a name and a dimension.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/sy/quantity.rb', line 59 def initialize( relative: nil, composition: nil, of: nil, measure: nil, amount: nil, coerces: [], coerces_to: [], **nn ) puts "Quantity init relative: #{relative}, composition: #{composition}, measure: #{measure}, #{nn}" if SY::DEBUG @units = [] # array of units as favored by this quantity @relative = relative if composition.nil? then puts "Composition not given, dimension expected." if SY::DEBUG @dimension = SY.Dimension( of ) else puts "Composition received (#{composition})." if SY::DEBUG @composition = SY::Composition[ composition ] @dimension = @composition.dimension end @measure = measure.is_a?( SY::Measure ) ? measure : if measure.nil? then if amount.nil? then nil else SY::Measure.simple_scale( amount ) end else fail ArgumentError, ":amount and :measure shouldn't be both supplied" unless amount.nil? SY::Measure.simple_scale( measure ) end coerces( *Array( coerces ) ) Array( coerces_to ).each { |qnt| qnt.coerces self } puts "Composition of the initialized instance is #{composition}." if SY::DEBUG puts "Initialized instance is #{relative? ? :relative : :absolute}" if SY::DEBUG puts "Initialized instance object_id is #{object_id}" if SY::DEBUG end |
Instance Attribute Details
#composition ⇒ Object (readonly)
Creates a composition from a dimension, or acts as composition getter if this has already been specified.
154 155 156 |
# File 'lib/sy/quantity.rb', line 154 def composition @composition end |
#dimension ⇒ Object (readonly)
Returns the value of attribute dimension.
15 16 17 |
# File 'lib/sy/quantity.rb', line 15 def dimension @dimension end |
#units ⇒ Object (readonly)
Returns the value of attribute units.
15 16 17 |
# File 'lib/sy/quantity.rb', line 15 def units @units end |
Class Method Details
.dimensionless(*args) ⇒ Object Also known as: zero
Dimensionless quantity constructor alias.
47 48 49 50 51 52 |
# File 'lib/sy/quantity.rb', line 47 def dimensionless *args |
.of(*args) ⇒ Object
Dimension-based quantity constructor. Examples: Quantity.of Dimension.new( "L.T⁻²" ) Quantity.of "L.T⁻²"
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/sy/quantity.rb', line 22 def of *args |
.standard(of: nil) ⇒ Object
Standard quantity. Example: Quantity.standard of: Dimension.new( "L.T⁻²" ) or <tt>Quantity.standard of: “L.T⁻²” (Both should give Acceleration as their result.)
39 40 41 42 43 |
# File 'lib/sy/quantity.rb', line 39 def standard( of: nil ) fail ArgumentError, "Dimension (:of argument) must be given!" if of.nil? puts "Constructing standard quantity of #{of} dimension" if SY::DEBUG return SY.Dimension( of ).standard_quantity end |
Instance Method Details
#*(q2) ⇒ Object
Quantity multiplication.
309 310 311 312 313 314 |
# File 'lib/sy/quantity.rb', line 309 def * q2 puts "#{self.name} * #{q2.name}" if SY::DEBUG rel = [ self, q2 ].any? &:relative ( SY::Composition[ self => 1 ] + SY::Composition[ q2 => 1 ] ) .to_quantity relative: rel end |
#**(num) ⇒ Object
Quantity raising to a number.
327 328 329 330 |
# File 'lib/sy/quantity.rb', line 327 def ** num puts "#{self.name} ** #{num}" if SY::DEBUG SY::Composition[ self => num ].to_quantity relative: relative? end |
#/(q2) ⇒ Object
Quantity division.
318 319 320 321 322 323 |
# File 'lib/sy/quantity.rb', line 318 def / q2 puts "#{self.name} / #{q2.name}" if SY::DEBUG rel = [ self, q2 ].any? &:relative? ( SY::Composition[ self => 1 ] - SY::Composition[ q2 => 1 ] ) .to_quantity relative: rel end |
#absolute ⇒ Object
Absolute quantity related to this quantity.
256 257 258 |
# File 'lib/sy/quantity.rb', line 256 def absolute absolute? ? self : colleague end |
#absolute? ⇒ Boolean
Is the quantity absolute? (Opposite of #relative?)
222 223 224 |
# File 'lib/sy/quantity.rb', line 222 def absolute? not relative? end |
#coerce(other) ⇒ Object
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/sy/quantity.rb', line 376 def coerce other case other when Numeric then return SY::Amount.relative, self when SY::Quantity then # By default, coercion between quantities doesn't exist. The basic # purpose of having quantities is to avoid mutual mixing of # incompatible magnitudes, as in "one cannot sum pears with apples". # if other == self then return other, self else raise SY::QuantityError, "#{other} and #{self} do not mix!" end else raise TErr, "#{self} cannot be coerced into a #{other.class}!" end end |
#coerces(*other_quantities) ⇒ Object
Quantities explicitly coerced by this quantity.
105 106 107 108 109 |
# File 'lib/sy/quantity.rb', line 105 def coerces *other_quantities if other_quantities.empty? then @coerces ||= [] else other_quantities.each { |qnt| coerces << qnt } end end |
#coerces?(other) ⇒ Boolean
Is the quantity supplied as the argument coerced by this quantity?
113 114 115 116 117 118 119 |
# File 'lib/sy/quantity.rb', line 113 def coerces? other other == self || coerces.include?( other ) || colleague.coerces.include?( other.colleague ) || if simple? then false else composition.coerces? other.composition end end |
#colleague ⇒ Object
For an absolute quantity, colleague is the corresponding relative quantity. Vice-versa, for a relative quantity, colleague is its absolute quantity.
235 236 237 |
# File 'lib/sy/quantity.rb', line 235 def colleague @colleague ||= construct_colleague end |
#dimensionless? ⇒ Boolean
Is the quantity dimensionless?
334 335 336 |
# File 'lib/sy/quantity.rb', line 334 def dimensionless? dimension.zero? end |
#inspect ⇒ Object
Inspect string.
372 373 374 |
# File 'lib/sy/quantity.rb', line 372 def inspect "#<Quantity:#{to_s}>" end |
#irreducible? ⇒ Boolean
Irreducible quantity is one which cannot or should not be reduced to its components in the process of quantity simplification.
147 148 149 |
# File 'lib/sy/quantity.rb', line 147 def irreducible? simple? or protected? end |
#magnitude(amount) ⇒ Object
Constructs a absolute magnitude of this quantity.
268 269 270 271 272 273 274 |
# File 'lib/sy/quantity.rb', line 268 def magnitude amount puts "self.object_id is #{object_id}" if SY::DEBUG puts "composition is #{composition}" if SY::DEBUG puts "Constructing #{self}#magnitude with amount #{amount}." if SY::DEBUG Magnitude().new( of: self, amount: amount ) .tap { puts "#{self}#magnitude constructed!" if SY::DEBUG } end |
#measure(of: nil) ⇒ Object
Creates a measure of a specified other quantity. If no :of is specified, simply acts as a getter of @measure attribute.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/sy/quantity.rb', line 194 def measure( of: nil ) return @measure if of.nil? # act as simple getter if :of not specified puts "#{self.inspect} asked about measure of #{of}" if SY::DEBUG return SY::Measure.identity if of == self or of == colleague raise SY::DimensionError, "#{self} vs. #{of}!" unless same_dimension? of return of.measure( of: of.standard ).inverse if standardish? m = begin puts "composition is #{composition}, class #{composition.class}" if SY::DEBUG measure || colleague.measure || composition.infer_measure rescue NoMethodError fail SY::QuantityError, "Measure of #{of} by #{self} impossible!" end return m if of.standardish? puts "#{of} not standardish, obtained measure relates to #{standard}, and " + "it will have to be extended to #{of}." if SY::DEBUG return m * standard.measure( of: of ) end |
#new_standard_unit(amount: nil, measure: nil, **nn) ⇒ Object
Constructor of a new standard unit (replacing current @standard_unit). For standard units, amount is implicitly 1. So :amount argument here has different meaning – it sets the measure of the quantity. Measure can also be specified more explicitly by :measure named argument.
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/sy/quantity.rb', line 288 def new_standard_unit( amount: nil, measure: nil, **nn ) explain_amount_of_standard_units if amount.is_a? Numeric # n00b help # For standard units, amount has special meaning of setting up mapping. if measure then raise ArgumentError, "When :measure is specified, :amount must not be " + "expliticly specified." unless amount.nil? raise TypeError, ":measure argument must be a SY::Measure!" unless measure.is_a? SY::Measure set_measure( measure ) else set_measure( SY::Measure.simple_scale( amount.nil? ? 1 : amount.amount ) ) end # Replace @standard_unit with the newly constructed unit. Unit().instance_variable_set( :@standard, unit( **nn ).tap do |u| ( units.unshift u ).uniq! end ) end |
#protect! ⇒ Object
Protects quantity from decomposition.
130 131 132 133 134 |
# File 'lib/sy/quantity.rb', line 130 def protect! @protected = true @composition ||= SY::Composition.singular self return self end |
#protected? ⇒ Boolean
Protected quantity is not allowed to be decomposed in the process of quantity simplification.
124 125 126 |
# File 'lib/sy/quantity.rb', line 124 def protected? @protected end |
#read(magnitude_of_other_quantity) ⇒ Object
Converts magnitude of another quantity to a magnitude of this quantity.
178 179 180 181 182 |
# File 'lib/sy/quantity.rb', line 178 def read magnitude_of_other_quantity other_quantity = magnitude_of_other_quantity.quantity other_amount = magnitude_of_other_quantity.amount magnitude measure( of: other_quantity ).r.( other_amount ) end |
#relative ⇒ Object
Relative quantity related to this quantity.
228 229 230 |
# File 'lib/sy/quantity.rb', line 228 def relative relative? ? self : colleague end |
#relative? ⇒ Boolean
Is the quantity relative?
216 217 218 |
# File 'lib/sy/quantity.rb', line 216 def relative? @relative ? true : false end |
#set_colleague(q2) ⇒ Object
Acts as colleague setter.
241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/sy/quantity.rb', line 241 def set_colleague q2 raise SY::DimensionError, "Mismatch: #{self}, #{q2}!" unless same_dimension? q2 raise SY::QuantityError, "#{self} an #{q2} are both " + "{relative? ? 'relative' : 'absolute'}!" if relative? == q2.relative? if measure && q2.measure then raise SY::QuantityError, "Measure mismatch: #{self}, #{q2}!" unless measure == q2.measure end @colleague = q2 q2.instance_variable_set :@colleague, self end |
#set_composition(comp) ⇒ Object
Acts as composition setter (dimension must match).
160 161 162 163 164 |
# File 'lib/sy/quantity.rb', line 160 def set_composition comp @composition = SY::Composition[ comp ] .aT "composition, when redefined after initialization,", "match the dimension" do |comp| comp.dimension == dimension end end |
#set_measure(measure) ⇒ Object
Acts as setter of measure (of the pertinent standard quantity).
168 169 170 171 172 173 174 |
# File 'lib/sy/quantity.rb', line 168 def set_measure measure @measure = if measure.is_a?( SY::Measure ) then measure else SY::Measure.simple_scale( measure ) end end |
#simple? ⇒ Boolean
Simple quantity is one with simple composition. If nontrivial composition is known for the colleague, it is assumed that the same composition would apply for this quantity, so it is not simple.
98 99 100 101 |
# File 'lib/sy/quantity.rb', line 98 def simple? c |
#standard ⇒ Object
Returns the standard quantity for this quantity’s dimension.
346 347 348 349 350 |
# File 'lib/sy/quantity.rb', line 346 def standard puts "Dimension of this quantity is #{dimension}" if SY::DEBUG puts "Its standard quantity is #{dimension.standard_quantity}" if SY::DEBUG dimension.standard_quantity end |
#standard! ⇒ Object
Make the quantity standard for its dimension.
340 341 342 |
# File 'lib/sy/quantity.rb', line 340 def standard! SY::Dimension.standard_quantities[ dimension ] = self end |
#standard? ⇒ Boolean
Is the dimension standard?
354 355 356 |
# File 'lib/sy/quantity.rb', line 354 def standard? self == standard end |
#standard_unit ⇒ Object
Reader of standard unit.
262 263 264 |
# File 'lib/sy/quantity.rb', line 262 def standard_unit Unit().standard end |
#standardish? ⇒ Boolean
Is the dimension or its colleague standard?
360 361 362 |
# File 'lib/sy/quantity.rb', line 360 def standardish? standard? || colleague.standard? end |
#to_s ⇒ Object
A string briefly describing the quantity.
366 367 368 |
# File 'lib/sy/quantity.rb', line 366 def to_s name.nil? ? "[#{dimension}]" : name.to_s end |
#unit(**nn) ⇒ Object
Constructs a new unit of this quantity.
278 279 280 281 |
# File 'lib/sy/quantity.rb', line 278 def unit **nn Unit().new( nn.update( of: self ) ) .tap { |u| ( units << u ).uniq! } # add it to the @units array end |
#unprotect! ⇒ Object
Unprotects quantity from decomposition.
138 139 140 141 142 |
# File 'lib/sy/quantity.rb', line 138 def unprotect! @protected = false @composition = nil if @composition == SY::Composition.singular( self ) return self end |
#write(amount_of_this_quantity, other_quantity) ⇒ Object
Converts an amount of this quantity to a magnitude of other quantity.
186 187 188 189 |
# File 'lib/sy/quantity.rb', line 186 def write amount_of_this_quantity, other_quantity measure( of: other_quantity ) .write( magnitude( amount_of_this_quantity ), other_quantity ) end |