Class: SY::Quantity
Overview
Quantity.
Constant Summary collapse
- RELATIVE_QUANTITY_NAME_SUFFIX =
"±"
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.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sy/quantity.rb', line 54 def initialize( relative: nil, composition: nil, of: nil, measure: nil, amount: nil, coerces: [], coerces_to: [], **nn ) @units = [] # array of units as favored by this quantity @relative = relative if composition.nil? then @dimension = SY.Dimension( of ) else @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 } end |
Instance Attribute Details
#composition ⇒ Object (readonly)
Creates a composition from a dimension, or acts as composition getter if this has already been specified.
143 144 145 |
# File 'lib/sy/quantity.rb', line 143 def composition @composition end |
#dimension ⇒ Object (readonly)
Returns the value of attribute dimension.
11 12 13 |
# File 'lib/sy/quantity.rb', line 11 def dimension @dimension end |
#units ⇒ Object (readonly)
Returns the value of attribute units.
11 12 13 |
# File 'lib/sy/quantity.rb', line 11 def units @units end |
Class Method Details
.dimensionless(*args) ⇒ Object Also known as: zero
Dimensionless quantity constructor alias.
42 43 44 45 46 47 |
# File 'lib/sy/quantity.rb', line 42 def dimensionless *args ꜧ = args. raise TErr, "Dimension not zero!" unless ꜧ[:dimension].zero? if ꜧ.has? :dimension, syn!: :of new( *( args << ꜧ.merge!( of: SY::Dimension.zero ) ) ).protect! end |
.of(*args) ⇒ Object
Dimension-based quantity constructor. Examples: Quantity.of Dimension.new( "L.T⁻²" )
Quantity.of "L.T⁻²"
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/sy/quantity.rb', line 18 def of *args ꜧ = args. dim = case args.size when 0 then ꜧ.must_have :dimension ꜧ.delete :dimension else args.shift end args << ꜧ.merge!( of: SY::Dimension.new( dim ) ) return new( *args ).protect! end |
.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.)
35 36 37 38 |
# File 'lib/sy/quantity.rb', line 35 def standard( of: nil ) fail ArgumentError, "Dimension (:of argument) must be given!" if of.nil? return SY.Dimension( of ).standard_quantity end |
Instance Method Details
#*(q2) ⇒ Object
Quantity multiplication.
289 290 291 292 293 |
# File 'lib/sy/quantity.rb', line 289 def * q2 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.
305 306 307 |
# File 'lib/sy/quantity.rb', line 305 def ** num SY::Composition[ self => num ].to_quantity relative: relative? end |
#/(q2) ⇒ Object
Quantity division.
297 298 299 300 301 |
# File 'lib/sy/quantity.rb', line 297 def / q2 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.
239 240 241 |
# File 'lib/sy/quantity.rb', line 239 def absolute absolute? ? self : colleague end |
#absolute? ⇒ Boolean
Is the quantity absolute? (Opposite of #relative?)
205 206 207 |
# File 'lib/sy/quantity.rb', line 205 def absolute? not relative? end |
#coerce(other) ⇒ Object
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/sy/quantity.rb', line 351 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.
94 95 96 97 98 |
# File 'lib/sy/quantity.rb', line 94 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?
102 103 104 105 106 107 108 |
# File 'lib/sy/quantity.rb', line 102 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.
218 219 220 |
# File 'lib/sy/quantity.rb', line 218 def colleague @colleague ||= construct_colleague end |
#dimensionless? ⇒ Boolean
Is the quantity dimensionless?
311 312 313 |
# File 'lib/sy/quantity.rb', line 311 def dimensionless? dimension.zero? end |
#inspect ⇒ Object
Inspect string.
347 348 349 |
# File 'lib/sy/quantity.rb', line 347 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.
136 137 138 |
# File 'lib/sy/quantity.rb', line 136 def irreducible? simple? or protected? end |
#magnitude(amount) ⇒ Object
Constructs a absolute magnitude of this quantity.
251 252 253 |
# File 'lib/sy/quantity.rb', line 251 def magnitude amount Magnitude().new( of: self, amount: amount ) 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.
183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/sy/quantity.rb', line 183 def measure( of: nil ) return @measure if of.nil? # act as simple getter if :of not specified return SY::Measure.identity if of == self or of == colleague fail SY::DimensionError, "#{self} vs. #{of}!" unless same_dimension? of return of.measure( of: of.standard ).inverse if standardish? m = begin measure || colleague.measure || composition.infer_measure rescue NoMethodError fail SY::QuantityError, "Measure of #{of} by #{self} impossible!" end return m if of.standardish? 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.
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/sy/quantity.rb', line 268 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.
119 120 121 122 123 |
# File 'lib/sy/quantity.rb', line 119 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.
113 114 115 |
# File 'lib/sy/quantity.rb', line 113 def protected? @protected end |
#read(magnitude_of_other_quantity) ⇒ Object
Converts magnitude of another quantity to a magnitude of this quantity.
167 168 169 170 171 |
# File 'lib/sy/quantity.rb', line 167 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.
211 212 213 |
# File 'lib/sy/quantity.rb', line 211 def relative relative? ? self : colleague end |
#relative? ⇒ Boolean
Is the quantity relative?
199 200 201 |
# File 'lib/sy/quantity.rb', line 199 def relative? @relative ? true : false end |
#set_colleague(q2) ⇒ Object
Acts as colleague setter.
224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/sy/quantity.rb', line 224 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).
149 150 151 152 153 |
# File 'lib/sy/quantity.rb', line 149 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).
157 158 159 160 161 162 163 |
# File 'lib/sy/quantity.rb', line 157 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.
87 88 89 90 |
# File 'lib/sy/quantity.rb', line 87 def simple? cᴍ = composition cᴍ.empty? || cᴍ.singular? && cᴍ.first[0] == self end |
#standard ⇒ Object
Returns the standard quantity for this quantity’s dimension.
323 324 325 |
# File 'lib/sy/quantity.rb', line 323 def standard dimension.standard_quantity end |
#standard! ⇒ Object
Make the quantity standard for its dimension.
317 318 319 |
# File 'lib/sy/quantity.rb', line 317 def standard! SY::Dimension.standard_quantities[ dimension ] = self end |
#standard? ⇒ Boolean
Is the dimension standard?
329 330 331 |
# File 'lib/sy/quantity.rb', line 329 def standard? self == standard end |
#standard_unit ⇒ Object
Reader of standard unit.
245 246 247 |
# File 'lib/sy/quantity.rb', line 245 def standard_unit Unit().standard end |
#standardish? ⇒ Boolean
Is the dimension or its colleague standard?
335 336 337 |
# File 'lib/sy/quantity.rb', line 335 def standardish? standard? || colleague.standard? end |
#to_s ⇒ Object
A string briefly describing the quantity.
341 342 343 |
# File 'lib/sy/quantity.rb', line 341 def to_s name.nil? ? "[#{dimension}]" : name.to_s end |
#unit(**nn) ⇒ Object
Constructs a new unit of this quantity.
257 258 259 260 261 |
# File 'lib/sy/quantity.rb', line 257 def unit **nn u = Unit().new( nn.update( of: self ) ) ( units << u ).uniq! # Add it to @units array. return u end |
#unprotect! ⇒ Object
Unprotects quantity from decomposition.
127 128 129 130 131 |
# File 'lib/sy/quantity.rb', line 127 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.
175 176 177 178 |
# File 'lib/sy/quantity.rb', line 175 def write amount_of_this_quantity, other_quantity measure( of: other_quantity ) .write( magnitude( amount_of_this_quantity ), other_quantity ) end |