Class: Quantify::Unit::CompoundBaseUnitList

Inherits:
Array
  • Object
show all
Defined in:
lib/quantify/unit/compound_base_unit_list.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.attribute_string(units, attribute, unit_delimiter, reciprocal = false) ⇒ Object

Returns a string represents of the units contained within units based on attribute and unit_delimiter.



10
11
12
13
14
15
16
17
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 10

def self.attribute_string(units,attribute,unit_delimiter,reciprocal=false)
  string = ""
  units.each do |base|
    string << unit_delimiter unless string.empty?
    string << base.send(attribute,reciprocal)
  end
  return string
end

Instance Method Details

#cancel!(*units) ⇒ Object

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)



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 60

def cancel!(*units)
  units.each do |unit|
    raise Exceptions::InvalidArgumentError, "Cannot cancel by a compound unit" if unit.is_a? Unit::Compound
    unit = Unit.for unit unless unit.is_a? Unit::Base

    numerator_unit = numerator_units.find { |base| unit.is_equivalent_to? base.unit }
    denominator_unit = denominator_units.find { |base| unit.is_equivalent_to? base.unit }

    if numerator_unit && denominator_unit
      cancel_value = [numerator_unit.index,denominator_unit.index].min.abs
      numerator_unit.index -= cancel_value
      denominator_unit.index += cancel_value
    end
  end
  consolidate_numerator_and_denominator!
end

#consolidate!Object

Consilidates base quantities by finding multiple instances of the same unit type and reducing them into a single unit represenation, by altering the repsective index. It has the effect of raising units to powers and cancelling those which appear in the numerator AND denominator

This is a class method which takes an arbitrary array of base units as an argument. This means that consolidation can be performed on either all base units or just a subset - the numerator or denominator units.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 86

def consolidate!
  new_base_units = []
  while size > 0 do
    new_base = shift
    next if new_base.unit.is_dimensionless?

    new_base.index = select do |other_base|
      new_base.unit.is_equivalent_to? other_base.unit
    end.inject(new_base.index) do |index,other_base|
      delete other_base
      index += other_base.index
    end
    new_base_units << new_base unless new_base.is_dimensionless?
  end
  replace(new_base_units)
end

#consolidate_numerator_and_denominator!Object

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.



109
110
111
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 109

def consolidate_numerator_and_denominator!
  replace(numerator_units.consolidate! + denominator_units.consolidate!)
end

#denominator_unitsObject

Returns an CompoundBaseUnitList containing only the base units which have

negative indices


27
28
29
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 27

def denominator_units
  CompoundBaseUnitList.new select { |base| base.is_denominator? }
end

#dimensionsObject

Derive a representation of the physical dimensions of the compound unit by multilying together the dimensions of each of the base units.



142
143
144
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 142

def dimensions
  inject(Dimensions.dimensionless) { |dimension,base| dimension * base.dimensions }
end

#factorObject

Derive the multiplicative factor for the unit based on those of the base units



192
193
194
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 192

def factor
  inject(1) { |factor,base| factor * base.factor }
end

#is_base_quantity_si_unit?Boolean

Returns true if all base untis are SI base units

Returns:

  • (Boolean)


42
43
44
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 42

def is_base_quantity_si_unit?
  all? { |base| base.is_base_quantity_si_unit? }
end

#is_non_si_unit?Boolean

Returns true if all base untis are not SI units

Returns:

  • (Boolean)


37
38
39
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 37

def is_non_si_unit?
  any? { |base| base.is_non_si_unit? }
end

#is_si_unit?Boolean

Returns true if all base untis are SI units

Returns:

  • (Boolean)


32
33
34
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 32

def is_si_unit?
  all? { |base| base.is_si_unit? }
end

#labelObject

Derive a label for the comound unit. This follows the format used in the JScience library in using a middot notation (“·”) to spearate units and slash notation “/” to separate numerator and denominator. Since the denominator is differentiated, denominator unit powers are rendered in absolute terms (i.e. minus sign omitted) except when no numerator values are present.



185
186
187
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 185

def label
  attribute_string_with_denominator_syntax(:label, "/", "·")
end

#name(plural = false) ⇒ Object

Derive a name for the unit based on the names of the base units

Both singluar and plural names can be derived. In the case of pluralized names, the last unit in the numerator is pluralized. Singular names are assumed by default, in which case no argument is required.

Format for names includes the phrase ‘per’ to differentiate denominator units and words, rather than numbers, for representing powers, e.g.

square metres per second


157
158
159
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 157

def name(plural=false)
  attribute_string_with_denominator_syntax(:name, " per ", " ", plural)
end

#numerator_unitsObject

Returns an CompoundBaseUnitList containing only the base units which have positive indices



21
22
23
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 21

def numerator_units
  CompoundBaseUnitList.new select { |base| base.is_numerator? }
end

#rationalize!(*required_units) ⇒ Object

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.



121
122
123
124
125
126
127
128
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 121

def rationalize!(*required_units)
  each do |base|
    new_unit = required_units.map { |unit| Unit.for(unit) }.find { |unit| unit.dimensions == base.unit.dimensions } ||
      find { |other_base| other_base.unit.dimensions == base.unit.dimensions }.unit
    base.unit = new_unit
  end
  consolidate_numerator_and_denominator!
end

#rationalize_numerator_and_denominator!(*units) ⇒ Object

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.



135
136
137
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 135

def rationalize_numerator_and_denominator!(*units)
  replace(numerator_units.rationalize!(*units) + denominator_units.rationalize!(*units))
end

#symbolObject

Derive a symbol for the unit based on the symbols of the base units

Get the units in order first so that the denominator values (those with negative powers) follow the numerators

Symbol format use unit symbols, with numerator symbols followed by denominator symbols and powers expressed using the “^” notation with ‘true’ values (i.e. preservation of minus signs).



170
171
172
173
174
175
176
# File 'lib/quantify/unit/compound_base_unit_list.rb', line 170

def symbol
  if Unit.use_symbol_denominator_syntax?
    attribute_string_with_denominator_syntax(:symbol,Unit.symbol_denominator_delimiter, Unit.symbol_unit_delimiter)
  else
    attribute_string_with_indices_only(:symbol,Unit.symbol_unit_delimiter)
  end
end