L
librarising
I needed to create some sample data for a project that resembled realistic usage, so I wrote a quick algorithm that follows a sinusoidal(periodic - upand down) pattern but still has a bit of randomness to it. As well, the algorithm has the ability trend upwards, downwards, or none.
If anyone cares to, I'd love some feedback on the algorithm: ways to optimize, ways to make a bit more jittery/random.
The output of the below code can be pasted into Google charts playground for visualization:
https://code.google.com/apis/ajax/playground/?type=visualization#line_chart
Also, the code with better syntax highlighting can be viewed here: http://pastie.org/8494591
# In order to generate a semi-realistic looking graph behavior
# we use a sine function to generate periodic behavior(ups and downs). In order to avoid
# a graph that is too regular, we introduce randomness at two levels:
# The delta between steps across the x-axis is random, but within a range(deltavariance)
# The wavelength of the sine function is varied by randomly incrementing the index we pass
# to the sine function(sine_index)
# CONFIGURATION VARIABLES
yvalue = 1 # start value
range = 100 # y-range
deltavariance = 10 # allowable variance between changes
sine_index, wavelength = 0, 0.33 #index into our sine function that determines whether we change direction or not
i, maxi = 0, 100 # our counter and its maximum
data = {sine_index => yvalue} # seed our data structure with its first value
trend = ositive # :negative, :none # do we want the graph to trend upwards, downwards or neither
periodmin, periodmax = 0, 0 # vars to enforce trending
direction = 1 # start in a positive direction, -1 for negative
# DO NOT EDIT BELOW THIS LINE
while(i < maxi)
olddirection = direction
direction = Math.sin(sine_index).to_f
direction = direction < 0 ? direction.floor : direction.ceil
delta = rand(deltavariance)
yvalue += delta * direction
if trend == ositive
yvalue = periodmin if yvalue < periodmin
periodmin = yvalue if olddirection < direction
elsif trend == :negative
yvalue = periodmax if yvalue > periodmax
periodmax = yvalue if olddirection > direction
end
data[sine_index] = yvalue
sine_index += Math.sin(rand) # Math.sin(rand) will give random numbers from -1..1
i += 1
end
code = <<-CODE
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['x', 'Cats'],
DATASTR
]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {curveType: "function",
width: 500, height: 400,
vAxis: {maxValue: 10}}
);
}
CODE
datastr = data.collect{|k,v| "[#{k},#{v}]"}.join(",")
code = code.gsub('DATASTR', datastr)
puts code
If anyone cares to, I'd love some feedback on the algorithm: ways to optimize, ways to make a bit more jittery/random.
The output of the below code can be pasted into Google charts playground for visualization:
https://code.google.com/apis/ajax/playground/?type=visualization#line_chart
Also, the code with better syntax highlighting can be viewed here: http://pastie.org/8494591
# In order to generate a semi-realistic looking graph behavior
# we use a sine function to generate periodic behavior(ups and downs). In order to avoid
# a graph that is too regular, we introduce randomness at two levels:
# The delta between steps across the x-axis is random, but within a range(deltavariance)
# The wavelength of the sine function is varied by randomly incrementing the index we pass
# to the sine function(sine_index)
# CONFIGURATION VARIABLES
yvalue = 1 # start value
range = 100 # y-range
deltavariance = 10 # allowable variance between changes
sine_index, wavelength = 0, 0.33 #index into our sine function that determines whether we change direction or not
i, maxi = 0, 100 # our counter and its maximum
data = {sine_index => yvalue} # seed our data structure with its first value
trend = ositive # :negative, :none # do we want the graph to trend upwards, downwards or neither
periodmin, periodmax = 0, 0 # vars to enforce trending
direction = 1 # start in a positive direction, -1 for negative
# DO NOT EDIT BELOW THIS LINE
while(i < maxi)
olddirection = direction
direction = Math.sin(sine_index).to_f
direction = direction < 0 ? direction.floor : direction.ceil
delta = rand(deltavariance)
yvalue += delta * direction
if trend == ositive
yvalue = periodmin if yvalue < periodmin
periodmin = yvalue if olddirection < direction
elsif trend == :negative
yvalue = periodmax if yvalue > periodmax
periodmax = yvalue if olddirection > direction
end
data[sine_index] = yvalue
sine_index += Math.sin(rand) # Math.sin(rand) will give random numbers from -1..1
i += 1
end
code = <<-CODE
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['x', 'Cats'],
DATASTR
]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {curveType: "function",
width: 500, height: 400,
vAxis: {maxValue: 10}}
);
}
CODE
datastr = data.collect{|k,v| "[#{k},#{v}]"}.join(",")
code = code.gsub('DATASTR', datastr)
puts code