class SY::Composition
Composition
of quantities.
Constants
- QUANTITY_TABLE
Cache for quantity construction.
- SR
Simplification rules for quantity combinations.
Public Class Methods
# File lib/sy/composition.rb, line 88 def empty self[] end
# File lib/sy/composition.rb, line 84 def singular quantity self[ SY.Quantity( quantity ) => 1 ] end
Public Instance Methods
Multiplication by a number.
# File lib/sy/composition.rb, line 189 def * number self.class[ self.with_values do |v| v * number end ] end
Merges two compositions.
# File lib/sy/composition.rb, line 177 def + other self.class[ self.merge( other ) { |_, v1, v2| v1 + v2 } ] end
Returns a new instance with same hash.
# File lib/sy/composition.rb, line 165 def +@ self.class[ self ] end
Subtracts two compositions.
# File lib/sy/composition.rb, line 183 def - other self + -other end
Negates hash exponents.
# File lib/sy/composition.rb, line 171 def -@ self.class[ self.with_values do |v| -v end ] end
Division by a number.
# File lib/sy/composition.rb, line 195 def / number self.class[ self.with_values do |val| raise TErr, "Compositions with rational exponents " + "not implemented!" if val % number != 0 val / number end ] end
Atomic compositions are singular compositions, whose quantity dimension is a base dimension.
# File lib/sy/composition.rb, line 132 def atomic? singular? && first[0].dimension.base? end
Whether this composition coerces another compotision.
# File lib/sy/composition.rb, line 138 def coerces? other # TODO: Think about caching. One way, ie. no way back, once something # coerces something else, so only false results would have to be re-checked, # and that only at most once each time after coerces / coerced_by method is # tampered. if singular? then other.singular? && self.first[0].coerces?( other.first[0] ) else # simplify the compositions a bit rslt = [].tap do |ary| find { |qnt, e| other.find { |qnt2, e2| ( ( e > 0 && e2 > 0 || e < 0 && e2 < 0 ) && qnt.coerces?( qnt2 ) ) .tap { |rslt| [] << qnt << qnt2 << ( e > 0 ? -1 : 1 ) if rslt } } } end # and ask recursively if rslt.empty? then return false else q, q2, e = rslt ( self + q.composition * e ).coerces? ( other + q2.composition * e ) end end end
Dimension of a composition is the sum of its member quantities' dimensions.
# File lib/sy/composition.rb, line 228 def dimension map { |qnt, exp| qnt.dimension * exp }.reduce SY::Dimension.zero, :+ end
Try to simplify the composition by decomposing its quantities.
# File lib/sy/composition.rb, line 256 def expand return self if irreducible? self.class[ reduce( self.class.empty ) { |cᴍ, pair| qnt, exp = pair ( cᴍ + if qnt.irreducible? then self.class.singular( qnt ) * exp else qnt.composition * exp end ) } ] end
Infers the measure of the composition's quantity. ('Measure' means measure of the pertinent standard quantity.)
# File lib/sy/composition.rb, line 235 def infer_measure map do |qnt, exp| if qnt.standardish? then SY::Measure.identity else qnt.measure( of: qnt.standard ) ** exp end end.reduce( SY::Measure.identity, :* ) end
Whether it is possible to expand this
# File lib/sy/composition.rb, line 250 def irreducible? all? { |qnt, exp| qnt.irreducible? } end
Directly (without attempts to simplify) creates a new quantity from self. If self is empty or singular, SY::Amount, resp. the singular quantity in question is returned.
# File lib/sy/composition.rb, line 222 def new_quantity args={} SY::Quantity.new args.merge( composition: self ) end
Simple composition is one that is either empty or singular.
# File lib/sy/composition.rb, line 245 def simple? empty? or singular? end
Simplifies a quantity hash by applying simplification rules.
# File lib/sy/composition.rb, line 205 def simplify ꜧ = self.to_hash SIMPLIFICATION_RULES.each { |rule| rule.( ꜧ ) } self.class[ ꜧ ] end
Singular compositions consist of only one quantity.
# File lib/sy/composition.rb, line 125 def singular? size == 1 && first[1] == 1 end
Returns the quantity appropriate to this composition.
# File lib/sy/composition.rb, line 213 def to_quantity args={} # All the work is delegated to the quantity table: QUANTITY_TABLE[ args.merge( self ) ] end