class Quantify::Unit::Compound
Attributes
Public Class Methods
Compound
units are units made up of two or more units and powers thereof.
The relationships between these units represent multiplication or division. E.g. a 'kilowatt hour' is the unit derived from multiplying a kilowatt and an hour. The 'kilogram per cubic metre' similarly represents the kilogram divided by the cubic metre (which itself represents metre x metre x metre).
There are many SI
units and NonSI
units which are technically compound units - being derived from several base units. For example, the watt represents the joule (itself compound) divided by the second. In this case though, the use of a special name for the unit - the 'watt' rather than the 'kilogram square metre per cubic second' - allows it to be treated as a standard SI
unit.
The Compound
class provides support for arbitrarily defined compound units which don't have well-established names.
Quantify::Unit::Base::initialize_prefixed_version
# File lib/quantify/unit/compound_unit.rb, line 23 def self.initialize_prefixed_version(prefix,compound) if compound.has_multiple_base_units? raise Exceptions::InvalidArgumentError, "Cannot apply prefix to compound unit with multiple base units: #{self.name}" end super end
Initialize a compound unit by providing an array containing a represenation of each base unit.
Array may contain elements specified as follows:
1. a instance of CompoundBaseUnit 2. an instance of Unit::Base (in which case its index is assumed as 1 3. a sub-array of size 2 containing an instance of Unit::Base and an explicit index
# File lib/quantify/unit/compound_unit.rb, line 44 def initialize(*units,&block) @base_units = CompoundBaseUnitList.new units.each do |unit| if unit.is_a? CompoundBaseUnit @base_units << unit elsif unit.is_a? Unit::Base @base_units << CompoundBaseUnit.new(unit) elsif unit.is_a?(Array) && unit.first.is_a?(Unit::Base) && !unit.first.is_a?(Compound) && unit.size == 2 @base_units << CompoundBaseUnit.new(unit.first,unit.last) else raise Exceptions::InvalidArgumentError, "#{unit} does not represent a valid base unit" end end @acts_as_alternative_unit = true @acts_as_equivalent_unit = false block.call(self) if block_given? consolidate_numerator_and_denominator_units! end
Private Class Methods
# File lib/quantify/unit/compound_unit.rb, line 203 def self.block_for_prefixed_version(prefix,compound) base = compound.base_units.first base.unit = base.unit.with_prefix(prefix) return Proc.new do |compound| compound.base_units << base end end
Public Instance Methods
Cancel base units across numerator and denominator. If similar units occur in both the numerator and denominator, they can be cancelled, i.e. their powers reduced correspondingly until one is removed.
This method is useful when wanting to remove specific units that can be cancelled from the compound unit configuration while retaining the remaining units in the current format.
If no other potentially cancelable units need to be retained, the method consolidate_base_units!
can be called with the :full argument instead
This method takes an arbitrary number of arguments which represent the units which are required to be cancelled (string, symbol or object)
# File lib/quantify/unit/compound_unit.rb, line 143 def cancel_base_units!(*units) @base_units.cancel!(*units) initialize_attributes end
Consilidates base quantities by finding multiple instances of the same unit type and reducing them into a single unit representation, by altering the repsective index. It has the effect of raising units to powers and cancelling those which appear in the numerator AND denominator
# File lib/quantify/unit/compound_unit.rb, line 153 def consolidate_base_units! @base_units.consolidate! initialize_attributes end
Similar to consolidate_base_units!
but operates on the numerator and denomiator are separately. This means that two instances of the same unit should not occur in the numerator OR denominator (rather they are combined and the index changed accordingly), but similar units are not cancelled across the numerator and denominators.
# File lib/quantify/unit/compound_unit.rb, line 164 def consolidate_numerator_and_denominator_units! @base_units.consolidate_numerator_and_denominator! initialize_attributes end
Returns an array containing only the base units which have negative indices
# File lib/quantify/unit/compound_unit.rb, line 77 def denominator_units @base_units.denominator_units end
Return a known unit which is equivalent to self in terms of its physical quantity (dimensions), factor and scaling attributes (i.e. representing the precise same physical unit but perhaps with different identifiers), e.g.
((Unit.kg*(Unit.m**"))/(Unit.s**2)).equivalent_known_unit.name #=> "joule"
# File lib/quantify/unit/compound_unit.rb, line 111 def equivalent_known_unit Unit.units.find do |unit| self.is_equivalent_to?(unit) && !unit.is_compound_unit? end end
# File lib/quantify/unit/compound_unit.rb, line 99 def has_multiple_base_units? @base_units.size > 1 end
# File lib/quantify/unit/compound_unit.rb, line 95 def is_base_quantity_si_unit? @base_units.is_base_quantity_si_unit? end
# File lib/quantify/unit/compound_unit.rb, line 91 def is_non_si_unit? @base_units.is_non_si_unit? end
Determine is a unit object represents an SI
named unit.
# File lib/quantify/unit/compound_unit.rb, line 87 def is_si_unit? @base_units.is_si_unit? end
Returns an array containing only the base units which have positive indices
# File lib/quantify/unit/compound_unit.rb, line 72 def numerator_units @base_units.numerator_units end
Returns an equivalent known unit (via equivalent_known_unit
) if it exists. Otherwise, returns false.
# File lib/quantify/unit/compound_unit.rb, line 120 def or_equivalent equivalent_unit = equivalent_known_unit if equivalent_unit && equivalent_unit.acts_as_equivalent_unit return equivalent_unit else return self end end
Convenient accessor method for pluralized names
# File lib/quantify/unit/compound_unit.rb, line 82 def pluralized_name @base_units.name(true) end
Make compound unit use consistent units for representing each physical quantity. For example, lb/kg => kg/kg.
The units to use for particular physical dimension can be specified. If no unit is specified for a physical quantity which is represented in the self
, then the first unit found for that physical quantity is used as the canonical one.
# File lib/quantify/unit/compound_unit.rb, line 177 def rationalize_base_units!(*units) @base_units.rationalize!(*units) initialize_attributes end
Similar to rationalize_base_units!
but operates on the numerator and denomiator are separately. This means that different units representing the same physical quantity may remain across the numerator and denominator units.
# File lib/quantify/unit/compound_unit.rb, line 187 def rationalize_numerator_and_denominator_units!(*units) @base_units.rationalize_numerator_and_denominator!(*units) initialize_attributes end
Refresh all unit attributes. Can be used following a change to unit attribute global configurations
# File lib/quantify/unit/compound_unit.rb, line 67 def refresh_attributes initialize_attributes end
Private Instance Methods
# File lib/quantify/unit/compound_unit.rb, line 194 def initialize_attributes self.dimensions = @base_units.dimensions self.name = @base_units.name self.symbol = @base_units.symbol self.factor = @base_units.factor self.label = @base_units.label return self end
Quantify::Unit::Base#initialize_copy
# File lib/quantify/unit/compound_unit.rb, line 211 def initialize_copy(source) super instance_variable_set("@base_units", @base_units.clone) end