vendredi 16 juin 2023

How to generate a random number with likelihoods that follow a modified (squished) cosine curve?

I am trying to generate a number that follows a cosine curve with an increased period. The goal is to generate a number between 0 and 1, but be able to supply an amplitude/factor and a period/interval.

For example, given the following:

10_000.times.map do
  num = randcos(factor: 5, intervals: 3)
  (num * 13).floor # Group in 12 groups for graphing visibility
end

And then graphing those points based on frequency, I would want a chart that looks something like this:

desired graph

Because we set intervals: 3, we have 3 "spikes" where those groups of numbers are more likely. The low points still occur, but are approximately 1/5 as likely because we set factor: 5.

I've been trying to use Math.cos to do this, but I'm getting stuck when trying to map those higher numbers to a likelihood of generating a new set. I can get it to show the one "spike" just using Math.sin/Math.cos, but I want to be able to customize how many of them show up.

Here is an example of my most recent iteration, although it just has a descending chart:

def randcos(factor:, intervals:)
  max_scale = intervals*Math::PI
  min_scale = -max_scale

  # Grab a random index and apply it to the squished cos
  x = min_scale + (2 * max_scale * rand) 
  num = (Math.cos(x)+1)/2 # Normalize 0..1 instead of -1..1

  # Trying to use the `num` from above to then multiply by the factor to give us 
  # more likely high numbers when the cos is nearer to 1
  rand * num * factor 
end



Aucun commentaire:

Enregistrer un commentaire