class SY::Composition

Composition of quantities.

Constants

QUANTITY_TABLE

Cache for quantity construction.

SR

Simplification rules for quantity combinations.

Public Class Methods

empty() click to toggle source
# File lib/sy/composition.rb, line 88
def empty
  self[]
end
singular(quantity) click to toggle source
# File lib/sy/composition.rb, line 84
def singular quantity
  self[ SY.Quantity( quantity ) => 1 ]
end

Public Instance Methods

*(number) click to toggle source

Multiplication by a number.

# File lib/sy/composition.rb, line 189
def * number
  self.class[ self.with_values do |v| v * number end ]
end
+(other) click to toggle source

Merges two compositions.

# File lib/sy/composition.rb, line 177
def + other
  self.class[ self.merge( other ) { |_, v1, v2| v1 + v2 } ]
end
+@() click to toggle source

Returns a new instance with same hash.

# File lib/sy/composition.rb, line 165
def +@
  self.class[ self ]
end
-(other) click to toggle source

Subtracts two compositions.

# File lib/sy/composition.rb, line 183
def - other
  self + -other
end
-@() click to toggle source

Negates hash exponents.

# File lib/sy/composition.rb, line 171
def -@
  self.class[ self.with_values do |v| -v end ]
end
/(number) click to toggle source

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?() click to toggle source

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
coerces?(other) click to toggle source

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() click to toggle source

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
expand() click to toggle source

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
infer_measure() click to toggle source

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
irreducible?() click to toggle source

Whether it is possible to expand this

# File lib/sy/composition.rb, line 250
def irreducible?
  all? { |qnt, exp| qnt.irreducible? }
end
new_quantity(args={}) click to toggle source

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?() click to toggle source

Simple composition is one that is either empty or singular.

# File lib/sy/composition.rb, line 245
def simple?
  empty? or singular?
end
simplify() click to toggle source

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?() click to toggle source

Singular compositions consist of only one quantity.

# File lib/sy/composition.rb, line 125
def singular?
  size == 1 && first[1] == 1
end
to_quantity(args={}) click to toggle source

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