Skip to content

Instantly share code, notes, and snippets.

@ChildrenofkoRn
Created September 19, 2021 11:46
Show Gist options
  • Save ChildrenofkoRn/cc39ec97aa2744a274532b921557fc00 to your computer and use it in GitHub Desktop.
Save ChildrenofkoRn/cc39ec97aa2744a274532b921557fc00 to your computer and use it in GitHub Desktop.
nonlinear sequence generator between numbers on Ruby
def get_sequence_nonlinear(count, start = 0, stop = 1, curvature: 1)
  step = 1 / (count - 1).to_f
  linear_steps = 0.step(by: step, to: 1)
  sequence = if curvature.positive?
               linear_steps.map { |num| 1 - Math.exp(num * -curvature.abs) }
             else
               linear_steps.map { |num| Math.exp(num * curvature.abs) - 1 }
             end
  max = sequence.max
  sequence.map { |num| (num / max) * (stop - start) + start }
end

puts get_sequence_nonlinear(14, 1, 10, curvature: -5)

1.0
1.0286368107863673
1.070705694586487
1.132506954419181
1.2232960453552535
1.356669686205176
1.5526021257764628
1.840436518177533
2.2632794002963466
2.8844563953977844
3.796995959289106
5.137561469978989
7.106918152759751
10.0

curvature

@ChildrenofkoRn
Copy link
Author

you can make generator a little faster using numo/narray

require 'numo/narray'

def get_sequence_nonlinear_numo(count, start = 0, stop = 1, curvature: 1)
  linear_steps = Numo::DFloat.linspace(0, 1, count)
  sequence = if curvature.positive?
               1 - Numo::NMath.exp(linear_steps * -curvature.abs)
             else
               Numo::NMath.exp(linear_steps * curvature.abs) - 1
             end
  (sequence / sequence.max) * (stop - start) + start
end
require "benchmark/ips"

Benchmark.ips do |x|
  params = [149, 1, 10, {curvature: -5}]

  x.report "get_sequence_nonlinear" do
    get_sequence_nonlinear(*params)
  end

  # object Numo to Array
  x.report "get_sequence_nonlinear_numo" do
    get_sequence_nonlinear_numo(*params).to_a
  end

  x.compare!
end


Warming up --------------------------------------
get_sequence_nonlinear
                         1.973k i/100ms
get_sequence_nonlinear_numo
                         3.352k i/100ms
Calculating -------------------------------------
get_sequence_nonlinear
                         19.421k (± 2.0%) i/s -     98.650k in   5.081639s
get_sequence_nonlinear_numo
                         32.952k (± 1.9%) i/s -    167.600k in   5.088079s

Comparison:
get_sequence_nonlinear_numo:    32952.2 i/s
get_sequence_nonlinear:         19421.4 i/s - 1.70x  (± 0.00) slower

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment