DSD_MG() combines
Moving Generator Clusters (MGCs) into an evolving data
stream. Each component specifies a cluster’s location, shape, size, and
density over time. This guide expands on the generator introduced in the
original stream_vignette.Rnw, using examples from the
DSD_MG and MGC help pages.
Start with a Gaussian cluster, a uniform rectangular cluster, and
uniform background noise. All components must have the stream’s
dimensionality. parameter gives standard deviations for
Shape_Gaussian and side lengths for
Shape_Block.
stream <- DSD_MG(dimension = 2,
MGC_Static(density = 45, center = c(1, 0), parameter = 0.1),
MGC_Static(density = 45, center = c(2, 0), parameter = c(0.4, 0.6),
shape = Shape_Block),
MGC_Noise(density = 10, range = rbind(c(0, 3), c(-1, 1))),
labels = c(1, 2, NA)
)
stream
#> Moving Data GeneratorClass: DSD_MG, DSD_R, DSD
#> With 3 clusters in 2 dimensions. Time is 1
get_points(stream, n = 5)
#> X1 X2 .class
#> 1 1.827095 0.14322891 2
#> 2 1.021095 -0.06553463 1
#> 3 2.102185 -0.10974945 2
#> 4 1.110681 -0.14546372 1
#> 5 1.034556 0.02119348 1
plot(stream, n = 500, xlim = c(0, 3), ylim = c(-1, 1))density controls both the relative chance of choosing a
component and the number of points generated per unit of generator time.
Here the total density is 100, so approximately 100 points advance the
generator by one time unit. Noise has label NA in the
.class column. Supply the same label to multiple components
when they should represent one ground-truth cluster.
MGC_Linear() interpolates the center, density, and shape
parameters between keyframes. The next example starts with one cluster.
At time 50, a second component appears at the same location, then moves
in another direction.
c1 <- MGC_Linear(dimension = 2, keyframelist = list(
keyframe(time = 1, density = 20, center = c(0, 0), parameter = 5),
keyframe(time = 50, density = 20, center = c(50, 50), parameter = 5),
keyframe(time = 100, density = 20, center = c(50, 100), parameter = 5)
))
c2 <- MGC_Linear(dimension = 2, keyframelist = list(
keyframe(time = 50, density = 20, center = c(50, 50), parameter = 5),
keyframe(time = 100, density = 20, center = c(100, 50), parameter = 5)
))
stream <- DSD_MG(dimension = 2, c1, c2)
get_keyframes(c1)
#> time parameter density centers reset
#> 1 1 5 20 0, 0 FALSE
#> 2 50 5 20 50, 50 FALSE
#> 3 100 5 20 50, 100 FALSEA linear component produces no points before its first keyframe.
After its last keyframe it keeps its final attributes. A keyframe with
reset = TRUE can make the trajectory repeat, as in
DSD_Benchmark(1).
Generator time is different from the count of requested points. The second component starts after about 980 points: 49 time units at density 20. Once it appears, the total density becomes 40. Plot three short sections around this change and near the end of the movement:
local({
old_par <- par(mfrow = c(1, 3))
on.exit(par(old_par))
plot(stream, n = 200, xlim = c(-15, 115), ylim = c(-15, 115),
main = "One cluster")
invisible(get_points(stream, n = 780))
plot(stream, n = 200, xlim = c(-15, 115), ylim = c(-15, 115),
main = "Second cluster appears")
invisible(get_points(stream, n = 1400))
plot(stream, n = 200, xlim = c(-15, 115), ylim = c(-15, 115),
main = "Separate paths")
})Generators can be modified after construction.
get_clusters() returns the component list;
remove_cluster() takes an index in that list.
noise <- MGC_Noise(density = 2, range = rbind(c(-15, 115), c(-15, 115)))
add_cluster(stream, noise, label = NA)
length(get_clusters(stream))
#> [1] 3
plot(stream, n = 500, xlim = c(-15, 115), ylim = c(-15, 115))Use add_keyframe() and remove_keyframe() to
edit a linear component’s trajectory. Stream and component objects
contain mutable state: updating a component can also affect a stream
that contains it.
MGC_Function() accepts functions of generator time for
density, center, and shape parameters. Here a Gaussian cluster travels
around a circle while a static cluster remains at the center.
orbit <- MGC_Function(
density = function(t) 20,
center = function(t) c(0.5 + 0.35 * cos(t / 10),
0.5 + 0.35 * sin(t / 10)),
parameter = function(t) 0.03
)
stream <- DSD_MG(dimension = 2, orbit,
MGC_Static(density = 5, center = c(0.5, 0.5), parameter = 0.03))The GIF below shows the functional generator in batches of 50 points, making the orbiting cluster’s movement visible. It loops automatically at ten frames per second and is embedded directly in the HTML.
Knitr creates the GIF using the gifski R package.
Install gifski before rendering to include the animation.
The animation chunk is skipped when gifski is unavailable
or the output is not HTML.
local({
set.seed(1000)
reset_stream(stream)
for (i in seq_len(30)) {
plot(stream, n = 50, xlim = c(0, 1), ylim = c(0, 1),
main = paste("Moving Generator after", i * 50, "points"))
}
})For interactive exploration, the following example uses the
animation package and is not run during vignette
builds.