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