lib/cosmos/conversions/segmented_polynomial_conversion.rb in cosmos-5.0.2 vs lib/cosmos/conversions/segmented_polynomial_conversion.rb in cosmos-5.0.3
- old
+ new
@@ -21,18 +21,22 @@
module Cosmos
# Segmented polynomial conversions consist of polynomial conversions that are
# applied for a range of values.
class SegmentedPolynomialConversion < Conversion
+ # @return [Array<Segment>] Segments which make up this conversion
+ attr_reader :segments
+
# A polynomial conversion segment which applies the conversion from the
# lower bound (inclusive) until another segment's lower bound is
# encountered.
class Segment
# @return [Integer] The value at which point this polynomial conversion
# should apply. All values >= to this value will be converted using the
# given coefficients.
attr_reader :lower_bound
+
# @return [Array<Integer>] The polynomial coefficients
attr_reader :coeffs
# Creates a polynomial conversion segment. Multiple Segments are used to
# implemnt a {SegmentedPolynomialConversion}.
@@ -55,10 +59,18 @@
# if they are equal, -1 if self.lower_bound < other_segment.lower_bound
def <=>(other_segment)
return other_segment.lower_bound <=> @lower_bound
end
+ # Implement equality operator primarily for ease of testing
+ #
+ # @param segment [Segment] Other segment
+ def ==(other_segment)
+ @lower_bound == other_segment.lower_bound &&
+ @coeffs == other_segment.coeffs
+ end
+
# Perform the polynomial conversion
#
# @param value [Numeric] The value to convert
# @return [Float] The converted value
def calculate(value)
@@ -69,13 +81,19 @@
return converted
end
end
# Initialize the converted_type to :FLOAT and converted_bit_size to 64.
- def initialize
+ #
+ # @param segments [Array] Array of segments typically generated by as_json
+ # Format similar to the following: [[15, [3, 2]], [10, [1, 2]]]
+ # Where each entry is an array with the first value as the lower_bound
+ # and the other entry is an array of the coefficients for that segment.
+ def initialize(segments = [])
super()
@segments = []
+ segments.each { |lower_bound, coeffs| add_segment(lower_bound, *coeffs) }
@converted_type = :FLOAT
@converted_bit_size = 64
end
# Add a segment to the segmented polynomial. The lower bound is inclusive, but
@@ -93,13 +111,11 @@
# @param (see Conversion#call)
# @return [Float] The value with the polynomial applied
def call(value, packet, buffer)
# Try to find correct segment
@segments.each do |segment|
- if value >= segment.lower_bound
- return segment.calculate(value)
- end
+ return segment.calculate(value) if value >= segment.lower_bound
end
# Default to using segment with smallest lower_bound
segment = @segments[-1]
if segment
@@ -110,11 +126,11 @@
end
# @return [String] The name of the class followed by a description of all
# the polynomial segments.
def to_s
- result = ""
+ result = ''
count = 0
@segments.each do |segment|
result << "\n" if count > 0
result << "Lower Bound: #{segment.lower_bound} Polynomial: "
segment.coeffs.length.times do |index|
@@ -134,19 +150,20 @@
# @param (see Conversion#to_config)
# @return [String] Config fragment for this conversion
def to_config(read_or_write)
config = ''
@segments.each do |segment|
- config << " SEG_POLY_#{read_or_write}_CONVERSION #{segment.lower_bound} #{segment.coeffs.join(' ')}\n"
+ config <<
+ " SEG_POLY_#{read_or_write}_CONVERSION #{segment.lower_bound} #{segment.coeffs.join(' ')}\n"
end
config
end
def as_json
params = []
@segments.each do |segment|
params << [segment.lower_bound, segment.coeffs]
end
- { 'class' => self.class.name.to_s, 'params' => params }
+ { 'class' => self.class.name.to_s, 'params' => [params] }
end
- end # class SegmentedPolynomialConversion
-end # module Cosmos
+ end
+end