module DataLayerProcessorSimpleSmoother
encoding: utf-8
Constants
- DEFAULT_GAUSS_COEFF
default Gauss coefficient
- DEFAULT_SIMPLE_SMOOTHER_STRATEGY
- MAX_SIMPLE_SMOOTHER_LEVEL
- MIN_SIMPLE_SMOOTHER_LEVEL
- PROCESS_WITH_PARAMETER_DISTANCE
use 'x' axis for processing also
- SIMPLE_SMOOTHER_STRATEGIES
Smoothing
Attributes
smooth using X distance
Public Instance Methods
This vector will be used to process values (Y'es) Use proper simple_smoother_strategy
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 53 def generate_vector method = SIMPLE_SMOOTHER_STRATEGIES[@simple_smoother_strategy] if method.nil? method = SIMPLE_SMOOTHER_STRATEGIES[DEFAULT_SIMPLE_SMOOTHER_STRATEGY] end return self.send(method) end
This vector will be used to process values (Y'es), linear algorithm
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 167 def generate_vector_gauss # http://www.techotopia.com/index.php/Ruby_Math_Functions_and_Methods#Ruby_Math_Constants # http://pl.wikipedia.org/wiki/Okno_czasowe # calculation count = (simple_smoother_level.to_f / 2.0).floor + 1 v = Array.new # calculated (1..count).each do |i| v << Math::E ** ((-0.5) * (i*gauss_coeff) ** 2) end @vector = make_mirror(v, simple_smoother_level) normalize_vector return @vector end
This vector will be used to process values (Y'es), linear algorithm
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 157 def generate_vector_rectangular @vector = Array.new # calculated (1..simple_smoother_level).each do |i| @vector << 1.0 / simple_smoother_level.to_f end return @vector end
Make mirror array size = 7 => [ i, i, i, i, i, i, i ] size = 8 => [ i, i, i, i, i, i, i, i ]
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 208 def make_mirror(input, size) a = Array.new(size, 0.1) if size.even? # two 'first' in central c_left = size/2 - 1 c_right = size/2 a[c_left] = input[0] a[c_right] = input[0] else # there is one 'first' c_left = (size/2.0).floor c_right = (size/2.0).floor a[c_left] = input[0] # a[c_right] = input[0] end # the rest i = 0 while c_left > 0 i += 1 c_left -= 1 c_right += 1 a[c_left] = input[i] a[c_right] = input[i] end return a end
Multiply vector to have sum eq. 1.0
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 188 def normalize_vector s = 0.0 @vector.each do |v| s += v end new_vector = Array.new @vector.each do |v| new_vector << v / s end @vector = new_vector return @vector end
Process part (size depends on simple_smoother_level
)
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 104 def process_part(old_data, position, y_based = true) # neutral data, used where position is near edge to calculate new value neutral_data = DataPoint.xy(old_data[position].x, old_data[position].y) part_array = Array.new(simple_smoother_level, neutral_data) # add data from old_data to part_array offset = (simple_smoother_level/2.0).floor # copying data (0...simple_smoother_level).each do |l| copy_pos = position + l - offset # if copy_pos is inside data if copy_pos >= 0 and old_data.size > copy_pos part_array[l] = old_data[copy_pos] end end # here we should have part_array and vector # and now do some magic :] if y_based return process_part_only_y(part_array) else return process_part_only_x(part_array, neutral_data) end end
Process part (size depends on simple_smoother_level
), Y and X data
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 140 def process_part_only_x(part_array, neutral_data) weights = Array.new w_sum = 0.0 (0...simple_smoother_level).each do |l| p = part_array[l] x_distance = p.x_distance(neutral_data) w = (Math::E ** (-1.0 * 0.2 * x_distance)) + 1.0 w_sum += w weights << w end w_prod = 0.0 part_array.each_index { |i| w_prod += part_array[i].y * weights[i].to_f } return w_prod.to_f / w_sum.to_f end
Process part (size depends on simple_smoother_level
), only Y data
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 131 def process_part_only_y(part_array, neutral_data = nil) y_sum = 0.0 (0...simple_smoother_level).each do |l| y_sum += part_array[l].y * vector[l] end return y_sum end
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 20 def simple_smoother_initialize(options) @simple_smoother = options[:simple_smoother] == true @simple_smoother_strategy = options[:simple_smoother_strategy] || DEFAULT_SIMPLE_SMOOTHER_STRATEGY @simple_smoother_level = options[:simple_smoother_level] || MIN_SIMPLE_SMOOTHER_LEVEL @simple_smoother_x = options[:simple_smoother_x] == true @vector = Array.new @gauss_coeff = DEFAULT_GAUSS_COEFF end
Simple_smoother_level of approximation
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 34 def simple_smoother_level=(l) @simple_smoother_level = l.to_i if l.to_i >= MIN_SIMPLE_SMOOTHER_LEVEL and l.to_i < MAX_SIMPLE_SMOOTHER_LEVEL end
Smooth values
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 62 def simple_smoother_process # not turned on return if simple_smoother == false # vector used for smoothing generate_vector t = Time.now old_data = @data new_data = Array.new # pre-processing, distance if simple_smoother_x == true logger.debug "X axis distance smoothing enabled" t = Time.now (0...old_data.size).each do |i| new_data << DataPoint.xy(old_data[i].x, process_part(old_data, i, false)) end old_data = new_data new_data = Array.new logger.debug "X axis distance smoothing completed" logger.debug " TIME COST #{Time.now - t}" end logger.debug "Y axis distance smoothing" t = Time.now (0...old_data.size).each do |i| new_data << DataPoint.xy(old_data[i].x, process_part(old_data, i)) end logger.debug "Y axis Smoothing completed, simple_smoother_level #{simple_smoother_level}, data size #{old_data.size}" logger.debug " TIME COST #{Time.now - t}" @data = new_data return new_data end
Choose other simple_smoother_strategy
from SIMPLE_SMOOTHER_STRATEGIES
# File lib/technical_graph/data_layer_processor_simple_smoother.rb, line 41 def simple_smoother_strategy=(s) method = SIMPLE_SMOOTHER_STRATEGIES[s] @simple_smoother_strategy = s unless method.nil? end