Class: SY::Composition
- Inherits:
-
Hash
- Object
- Hash
- SY::Composition
- Defined in:
- lib/sy/composition.rb
Overview
Composition of quantities.
Constant Summary collapse
- SR =
Simplification rules for quantity combinations.
SIMPLIFICATION_RULES = []
- QUANTITY_TABLE =
Cache for quantity construction.
Hash.new { |ꜧ, args| if args.keys.include? [:name] || args.keys.include?( :ɴ ) then ɴ = args.delete( :name ) || args.delete( :ɴ ) # won't cache name ꜧ[args].tap { |ɪ| ɪ.name = ɴ } # recursion elsif args.keys.include? :mapping then ᴍ = args.delete( :mapping ) # won't cache mapping ꜧ[args].tap { |ɪ| ɪ.set_mapping ᴍ } # recursion elsif args.keys.include? :relative then ʀ = args.delete( :relative ) ? true : false # won't cache :relative ꜧ[args].send ʀ ? :relative : :absolute # recursion else cᴍ = SY::Composition[ args ].simplify ꜧ[args] = if cᴍ != args then ꜧ[ cᴍ ] # recursion while #simplify else x = cᴍ. # we'll try to #expand now if x != cᴍ then ꜧ[ x ] # recursion while #expand else if x.empty? then # use std. ∅ quantity SY.Dimension( :∅ ).standard_quantity elsif x.singular? then x.first[0] # unwrap the quantity else # create new quantity SY::Quantity.new composition: x end end end end }
Class Method Summary collapse
Instance Method Summary collapse
-
#*(number) ⇒ Object
Multiplication by a number.
-
#+(other) ⇒ Object
Merges two compositions.
-
#+@ ⇒ Object
Returns a new instance with same hash.
-
#-(other) ⇒ Object
Subtracts two compositions.
-
#-@ ⇒ Object
Negates hash exponents.
-
#/(number) ⇒ Object
Division by a number.
-
#atomic? ⇒ Boolean
Atomic compositions are singular compositions, whose quantity dimension is a base dimension.
-
#coerces?(other) ⇒ Boolean
Whether this composition coerces another compotision.
-
#dimension ⇒ Object
Dimension of a composition is the sum of its member quantities’ dimensions.
-
#expand ⇒ Object
Try to simplify the composition by decomposing its quantities.
-
#infer_measure ⇒ Object
Infers the measure of the composition’s quantity.
-
#irreducible? ⇒ Boolean
Whether it is possible to expand this.
-
#new_quantity(args = {}) ⇒ Object
Directly (without attempts to simplify) creates a new quantity from self.
-
#simple? ⇒ Boolean
Simple composition is one that is either empty or singular.
-
#simplify ⇒ Object
Simplifies a quantity hash by applying simplification rules.
-
#singular? ⇒ Boolean
Singular compositions consist of only one quantity.
-
#to_quantity(args = {}) ⇒ Object
Returns the quantity appropriate to this composition.
Class Method Details
.empty ⇒ Object
88 89 90 |
# File 'lib/sy/composition.rb', line 88 def empty self[] end |
.singular(quantity) ⇒ Object
84 85 86 |
# File 'lib/sy/composition.rb', line 84 def singular quantity self[ SY.Quantity( quantity ) => 1 ] end |
Instance Method Details
#*(number) ⇒ Object
Multiplication by a number.
189 190 191 |
# File 'lib/sy/composition.rb', line 189 def * number self.class[ self.with_values do |v| v * number end ] end |
#+(other) ⇒ Object
Merges two compositions.
177 178 179 |
# File 'lib/sy/composition.rb', line 177 def + other self.class[ self.merge( other ) { |_, v1, v2| v1 + v2 } ] end |
#+@ ⇒ Object
Returns a new instance with same hash.
165 166 167 |
# File 'lib/sy/composition.rb', line 165 def +@ self.class[ self ] end |
#-(other) ⇒ Object
Subtracts two compositions.
183 184 185 |
# File 'lib/sy/composition.rb', line 183 def - other self + -other end |
#-@ ⇒ Object
Negates hash exponents.
171 172 173 |
# File 'lib/sy/composition.rb', line 171 def -@ self.class[ self.with_values do |v| -v end ] end |
#/(number) ⇒ Object
Division by a number.
195 196 197 198 199 200 201 |
# 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? ⇒ Boolean
Atomic compositions are singular compositions, whose quantity dimension is a base dimension.
132 133 134 |
# File 'lib/sy/composition.rb', line 132 def atomic? singular? && first[0].dimension.base? end |
#coerces?(other) ⇒ Boolean
Whether this composition coerces another compotision.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# 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 ⇒ Object
Dimension of a composition is the sum of its member quantities’ dimensions.
228 229 230 |
# File 'lib/sy/composition.rb', line 228 def dimension map { |qnt, exp| qnt.dimension * exp }.reduce SY::Dimension.zero, :+ end |
#expand ⇒ Object
Try to simplify the composition by decomposing its quantities.
256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/sy/composition.rb', line 256 def 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 ⇒ Object
Infers the measure of the composition’s quantity. (‘Measure’ means measure of the pertinent standard quantity.)
235 236 237 238 239 240 241 |
# 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? ⇒ Boolean
Whether it is possible to expand this
250 251 252 |
# File 'lib/sy/composition.rb', line 250 def irreducible? all? { |qnt, exp| qnt.irreducible? } end |
#new_quantity(args = {}) ⇒ Object
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.
222 223 224 |
# File 'lib/sy/composition.rb', line 222 def new_quantity args={} SY::Quantity.new args.merge( composition: self ) end |
#simple? ⇒ Boolean
Simple composition is one that is either empty or singular.
245 246 247 |
# File 'lib/sy/composition.rb', line 245 def simple? empty? or singular? end |
#simplify ⇒ Object
Simplifies a quantity hash by applying simplification rules.
205 206 207 208 209 |
# File 'lib/sy/composition.rb', line 205 def simplify ꜧ = self.to_hash SIMPLIFICATION_RULES.each { |rule| rule.( ꜧ ) } self.class[ ꜧ ] end |
#singular? ⇒ Boolean
Singular compositions consist of only one quantity.
125 126 127 |
# File 'lib/sy/composition.rb', line 125 def singular? size == 1 && first[1] == 1 end |
#to_quantity(args = {}) ⇒ Object
Returns the quantity appropriate to this composition.
213 214 215 216 |
# 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 |