Generates a volume with perfectly separable clusters for testing clustering algorithm correctness. Each cluster is a spatially contiguous cubic sub-region with identical timeseries within the cluster and orthogonal signals between clusters.
Usage
make_synthetic_clusters(
n_time = 100,
noise_sd = 0,
n_clusters = 27,
dim_per_cluster = 3,
seed = NULL
)Arguments
- n_time
Number of timepoints. Default 100.
- noise_sd
Standard deviation of Gaussian noise to add. Default 0 (no noise = perfect separability).
- n_clusters
Number of clusters. Must be a perfect cube (8, 27, 64, etc.) for cubic cluster geometry. Default 27.
- dim_per_cluster
Voxels per dimension per cluster. Default 3.
- seed
Random seed for reproducibility. Default NULL.
Value
A list with:
- vec
NeuroVec object
- mask
NeuroVol mask (all ones)
- true_clusters
NeuroVol with ground truth cluster labels
- true_labels
Integer vector of true cluster assignments
- n_clusters
Number of clusters
- cluster_size
Size of each cluster in voxels
- signals
Matrix of cluster signals (n_time x n_clusters)
Details
For the default n_clusters=27, creates a 9x9x9 volume divided into 27 cubic 3x3x3 clusters arranged in a 3x3x3 grid:
z=1-3: z=4-6: z=7-9:
y y y
^ ^ ^
| 7 | 8 | 9 | | 16| 17| 18| | 25| 26| 27|
| 4 | 5 | 6 | | 13| 14| 15| | 22| 23| 24|
| 1 | 2 | 3 | | 10| 11| 12| | 19| 20| 21|
+-----------> x +-----------> x +-----------> x
Each cluster has a unique orthogonal signal generated from QR decomposition of a random matrix, ensuring zero correlation between clusters.
This creates an "easy" test case where any reasonable clustering algorithm should achieve perfect or near-perfect recovery with noise_sd=0.
Examples
# Default: 27 clusters, perfect separability
data <- make_synthetic_clusters()
table(data$true_labels) # 27 voxels per cluster
#>
#> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#> 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27
#> 27
#> 27
# 8 clusters (2x2x2 grid of 3x3x3 cubes = 6x6x6 volume)
data <- make_synthetic_clusters(n_clusters = 8)
# With noise for more realistic testing
data <- make_synthetic_clusters(noise_sd = 0.5)