OSCR

Coordinative structures as scale-free networks: Cascade and percolation dynamics in motor learning with empirical validation.

Code ↔ Paper

14 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 14 matches
  1. [1] § 2. Materials and methods › 2.2. Cascade dynamics model ↔ simulations/02_cascade_dynamics.py, lines 115–208 · score 0.90 · neighbor mediated propagation, state variables, spontaneous activation, state transition, coordination strength, timestep
  2. [2] § 3. Results › 3.2. Cascade dynamics ↔ simulations/02_cascade_dynamics.py, lines 1–44 · score 0.86 · topology isolated trials, DOF recruitment, spontaneous activation, single seed, asymmetry ratio, Cascade dynamics
  3. [3] § 2. Materials and methods › 2.4. Percolation model and coupled learning dynamics ↔ simulations/04_coupled_learning.py, lines 1–41 · score 0.82 · Hebbian weight updates, preferential attachment, step coupled, practice iteration, fitness, 2–4
  4. [4] § 2. Materials and methods › 2.1. Network model specifications ↔ simulations/01_network_generation.py, lines 1–42 · score 0.78 · Barab si Albert, canonical network, Watts Strogatz, scale free networks, Erd, nyi
  5. [5] § 2. Materials and methods › 2.2. Cascade dynamics model ↔ simulations/02_cascade_dynamics.py, lines 1–44 · score 0.74 · baseline stability, centrality weighted, coordination strength, neighbors, S2, activation
  6. [6] § 3. Results › 3.4. Coupled learning dynamics ↔ simulations/04_coupled_learning.py, lines 1–41 · score 0.72 · Hebbian learning rate, coupled learning dynamics, practice iterations, weight hierarchy, algorithm, decay
  7. [7] § 2. Materials and methods › 2.1. Network model specifications ↔ simulations/01_network_generation.py, lines 1–42 · score 0.65 · small world network, power law, random network, scale free network, clustering, connecting
  8. [8] § 2. Materials and methods › 2.4. Percolation model and coupled learning dynamics ↔ simulations/03_percolation_robustness.py, lines 82–127 · score 0.58 · giant component fraction, occupation probability, bond, percolation
  9. [9] § 3. Results › 3.1. Network topology comparison ↔ simulations/01_network_generation.py, lines 244–371 · score 0.57 · exemplar network, hub fraction, eigenvector centrality, Gini, scale free network, seed
  10. [10] § 3. Results › 3.3. Percolation dynamics and robustness-fragility ↔ simulations/03_percolation_robustness.py, lines 1–41 · score 0.56 · bond occupation sweeps, robustness, susceptibility, fragility, percolation, realizations
  11. [11] § 2. Materials and methods › 2.3. Mapping network topology to coordinative structures ↔ simulations/03_percolation_robustness.py, lines 173–196 · score 0.56 · random node removal, fragmentation ratio, Robustness
  12. [12] § 3. Results › 3.1. Network topology comparison ↔ simulations/01_network_generation.py, lines 103–124 · score 0.54 · Gini coefficient, hub fraction, eigenvector centrality, nodes, networks
  13. [13] § 2. Materials and methods › 2.4. Percolation model and coupled learning dynamics ↔ simulations/04_coupled_learning.py, lines 147–176 · score 0.54 · co activated, coupled learning, decay, strengthen, Edges, weights
  14. [14] § 3. Results › 3.1. Network topology comparison ↔ simulations/01_network_generation.py, lines 244–371 · score 0.53 · Power law fitting, network ensembles, KS, WS, BA, topologies

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 455 lines · 17 KB · MIT · 5 matches

  1. #!/usr/bin/env python3
  2. """
  3. 01_network_generation.py
  4. ========================
  5. Coordinative Structures as Scale-Free Networks (Park, 2026)
  6. Manuscript Section 2.1 — Network Topology
  7. Generates three canonical network topologies with matched connectivity:
  8. - Erdős–Rényi (ER) random network
  9. - Watts–Strogatz (WS) small-world network
  10. - Barabási–Albert (BA) scale-free network
  11. Computes structural metrics for manuscript Tables S1a–S1d and Table 2:
  12. - Degree statistics: ⟨k⟩, σ_k, k_max
  13. - Degree heterogeneity: κ = ⟨k²⟩/⟨k⟩
  14. - Power-law exponent: γ̂ (MLE) with KS goodness-of-fit
  15. - Centrality: eigenvector centrality, Gini coefficient, hub fraction
  16. - Topology: clustering coefficient, average path length
  17. Parameters (from manuscript §2.1):
  18. N = 100 nodes
  19. ⟨k⟩ ≈ 6 (matched across topologies)
  20. ER: p = 0.0606
  21. WS: K = 6, β = 0.1
  22. BA: m = 3 (m₀ = 3 initial complete graph)
  23. Realizations: 100
  24. Base random seed: 42
  25. Output:
  26. data/simulation_outputs/network_structural_metrics.csv
  27. data/simulation_outputs/network_ensemble_data.npz
  28. Usage:
  29. python simulations/01_network_generation.py
  30. """
  31. import numpy as np
  32. import networkx as nx
  33. from scipy import stats
  34. import os
  35. import sys
  36. import time
  37. # ══════════════════════════════════════════════════════════════
  38. # PARAMETERS — manuscript §2.1, Tables S1b, S1d
  39. # ══════════════════════════════════════════════════════════════
  40. N = 100 # Number of nodes (degrees of freedom)
  41. N_REALIZATIONS = 100 # Independent network instances
  42. BASE_SEED = 42 # For reproducibility
  43. # Topology-specific parameters (Table S1b)
  44. ER_P = 6.0 / (N - 1) # ≈ 0.0606, targeting ⟨k⟩ ≈ 6
  45. WS_K = 6 # Ring neighbors (each side K/2 = 3)
  46. WS_BETA = 0.1 # Rewiring probability
  47. BA_M = 3 # Edges per new node (⟨k⟩ → 2m = 6)
  48. # Hub identification threshold
  49. HUB_CRITERION = 'mean_plus_sd' # C_e > μ + σ
  50. # Output directory
  51. OUTPUT_DIR = os.path.join(os.path.dirname(os.path.dirname(
  52. os.path.abspath(__file__))), 'data', 'simulation_outputs')
  53. # ══════════════════════════════════════════════════════════════
  54. # NETWORK GENERATION FUNCTIONS
  55. # ══════════════════════════════════════════════════════════════
  56. def generate_er(n, p, seed):
  57. """Erdős–Rényi G(N,p) random network (Eq S1 Appendix, Algorithm 1)."""
  58. return nx.erdos_renyi_graph(n, p, seed=seed)
  59. def generate_ws(n, k, beta, seed):
  60. """Watts–Strogatz small-world network (Algorithm 2)."""
  61. return nx.watts_strogatz_graph(n, k, beta, seed=seed)
  62. def generate_ba(n, m, seed):
  63. """Barabási–Albert scale-free network via preferential attachment (Eq 1)."""
  64. return nx.barabasi_albert_graph(n, m, seed=seed)
  65. # ══════════════════════════════════════════════════════════════
  66. # STRUCTURAL ANALYSIS FUNCTIONS
  67. # ══════════════════════════════════════════════════════════════
  68. def compute_degree_stats(G):
  69. """Compute degree distribution statistics."""
  70. degrees = np.array([G.degree(n) for n in G.nodes()])
  71. k_mean = degrees.mean()
  72. k_std = degrees.std()
  73. k_max = degrees.max()
  74. k_second_moment = (degrees ** 2).mean()
  75. kappa = k_second_moment / k_mean if k_mean > 0 else 0.0
  76. return {
  77. 'k_mean': k_mean,
  78. 'k_std': k_std,
  79. 'k_max': k_max,
  80. 'kappa': kappa,
  81. 'degrees': degrees,
  82. }
  83. def compute_centrality_stats(G):
  84. """Compute eigenvector centrality and derived measures."""
  85. try:
  86. ce = nx.eigenvector_centrality_numpy(G)
  87. except nx.NetworkXError:
  88. # Fallback for disconnected graphs
  89. ce = nx.eigenvector_centrality(G, max_iter=1000, tol=1e-6)
  90. ce_vals = np.array([ce[n] for n in G.nodes()])
  91. # Gini coefficient of eigenvector centrality
  92. gini = _gini_coefficient(ce_vals)
  93. # Hub fraction: nodes with C_e > μ + σ
  94. ce_mean = ce_vals.mean()
  95. ce_std = ce_vals.std()
  96. hub_fraction = np.mean(ce_vals > (ce_mean + ce_std))
  97. return {
  98. 'gini_ce': gini,
  99. 'hub_fraction': hub_fraction,
  100. 'ce_values': ce_vals,
  101. }
  102. def _gini_coefficient(values):
  103. """Compute Gini coefficient for a set of values."""
  104. sorted_vals = np.sort(values)
  105. n = len(sorted_vals)
  106. if n == 0 or sorted_vals.sum() == 0:
  107. return 0.0
  108. index = np.arange(1, n + 1)
  109. return (2 * np.sum(index * sorted_vals) / (n * np.sum(sorted_vals))) - (n + 1) / n
  110. def compute_topology_stats(G):
  111. """Compute clustering coefficient and average path length."""
  112. clustering = nx.average_clustering(G)
  113. # Average shortest path length (handle disconnected graphs)
  114. if nx.is_connected(G):
  115. avg_path = nx.average_shortest_path_length(G)
  116. else:
  117. # Use largest connected component
  118. gcc = max(nx.connected_components(G), key=len)
  119. subG = G.subgraph(gcc).copy()
  120. avg_path = nx.average_shortest_path_length(subG) if len(subG) > 1 else float('inf')
  121. return {
  122. 'clustering': clustering,
  123. 'avg_path_length': avg_path,
  124. }
  125. def powerlaw_fit(degrees, k_min=None):
  126. """
  127. Maximum Likelihood Estimation of power-law exponent γ̂.
  128. Uses the discrete MLE formula (Eq S1 in S1 Appendix):
  129. γ̂ = 1 + n [Σᵢ ln(kᵢ / (k_min − 0.5))]⁻¹
  130. Following Clauset, Shalizi & Newman (2009) [Ref 58 in manuscript].
  131. Returns:
  132. gamma_hat: MLE exponent estimate
  133. ks_pvalue: KS test p-value against power-law distribution
  134. k_min_used: k_min threshold used
  135. """
  136. degrees = np.array(degrees)
  137. degrees = degrees[degrees > 0] # Remove zeros
  138. if k_min is None:
  139. # Find optimal k_min by minimizing KS statistic
  140. unique_k = np.unique(degrees)
  141. unique_k = unique_k[unique_k >= 2] # Minimum meaningful k_min
  142. best_ks = np.inf
  143. best_kmin = 2
  144. best_gamma = 3.0
  145. for km in unique_k:
  146. if km >= degrees.max():
  147. break
  148. tail = degrees[degrees >= km]
  149. if len(tail) < 10:
  150. break
  151. g = 1 + len(tail) * (np.sum(np.log(tail / (km - 0.5)))) ** (-1)
  152. if g > 1.5 and g < 5.0: # Reasonable range
  153. # KS statistic
  154. cdf_emp = np.sort(tail)
  155. cdf_emp = np.arange(1, len(cdf_emp) + 1) / len(cdf_emp)
  156. cdf_theo = 1 - (np.sort(tail) / km) ** (-(g - 1))
  157. ks = np.max(np.abs(cdf_emp - cdf_theo))
  158. if ks < best_ks:
  159. best_ks = ks
  160. best_kmin = km
  161. best_gamma = g
  162. k_min = best_kmin
  163. # Final fit with chosen k_min
  164. tail = degrees[degrees >= k_min]
  165. if len(tail) < 5:
  166. return np.nan, np.nan, k_min
  167. gamma_hat = 1 + len(tail) * (np.sum(np.log(tail / (k_min - 0.5)))) ** (-1)
  168. # KS goodness-of-fit via Monte Carlo (simplified)
  169. n_mc = 500
  170. ks_orig = _ks_stat_powerlaw(tail, gamma_hat, k_min)
  171. n_exceed = 0
  172. rng = np.random.RandomState(BASE_SEED)
  173. for _ in range(n_mc):
  174. # Generate synthetic power-law sample
  175. synth = _generate_powerlaw_sample(len(tail), gamma_hat, k_min, rng)
  176. if len(synth) < 5:
  177. continue
  178. g_synth = 1 + len(synth) * (np.sum(np.log(synth / (k_min - 0.5)))) ** (-1)
  179. ks_synth = _ks_stat_powerlaw(synth, g_synth, k_min)
  180. if ks_synth >= ks_orig:
  181. n_exceed += 1
  182. ks_pvalue = n_exceed / n_mc
  183. return gamma_hat, ks_pvalue, k_min
  184. def _ks_stat_powerlaw(data, gamma, k_min):
  185. """KS statistic between data and power-law CDF."""
  186. sorted_data = np.sort(data)
  187. n = len(sorted_data)
  188. cdf_emp = np.arange(1, n + 1) / n
  189. cdf_theo = 1 - (sorted_data / k_min) ** (-(gamma - 1))
  190. return np.max(np.abs(cdf_emp - cdf_theo))
  191. def _generate_powerlaw_sample(n, gamma, k_min, rng):
  192. """Generate discrete power-law random sample via inverse transform."""
  193. u = rng.uniform(0, 1, size=n)
  194. samples = np.floor(k_min * (1 - u) ** (-1.0 / (gamma - 1))).astype(int)
  195. return samples[samples >= k_min]
  196. # ══════════════════════════════════════════════════════════════
  197. # MAIN ENSEMBLE SIMULATION
  198. # ══════════════════════════════════════════════════════════════
  199. def run_ensemble():
  200. """
  201. Generate network ensembles and compute all structural metrics.
  202. Reproduces Tables S1b, S1d, and Table 2 (structural rows).
  203. """
  204. print("=" * 70)
  205. print("01_network_generation.py")
  206. print("Coordinative Structures as Scale-Free Networks")
  207. print(f"N = {N}, ⟨k⟩ ≈ 6, {N_REALIZATIONS} realizations, seed = {BASE_SEED}")
  208. print("=" * 70)
  209. topologies = {
  210. 'ER': {'generator': lambda seed: generate_er(N, ER_P, seed),
  211. 'params': f'p = {ER_P:.4f}'},
  212. 'WS': {'generator': lambda seed: generate_ws(N, WS_K, WS_BETA, seed),
  213. 'params': f'K = {WS_K}, β = {WS_BETA}'},
  214. 'BA': {'generator': lambda seed: generate_ba(N, BA_M, seed),
  215. 'params': f'm = {BA_M}'},
  216. }
  217. # Storage for ensemble results
  218. results = {}
  219. ensemble_data = {}
  220. for topo_name, topo_info in topologies.items():
  221. print(f"\n--- {topo_name} ({topo_info['params']}) ---")
  222. t0 = time.time()
  223. # Per-realization storage
  224. k_means = []
  225. k_stds = []
  226. k_maxs = []
  227. kappas = []
  228. clusterings = []
  229. path_lengths = []
  230. gini_ces = []
  231. hub_fracs = []
  232. gamma_hats = []
  233. ks_pvals = []
  234. all_degrees = []
  235. for r in range(N_REALIZATIONS):
  236. seed = BASE_SEED + r
  237. G = topo_info['generator'](seed)
  238. # Degree statistics
  239. dstats = compute_degree_stats(G)
  240. k_means.append(dstats['k_mean'])
  241. k_stds.append(dstats['k_std'])
  242. k_maxs.append(dstats['k_max'])
  243. kappas.append(dstats['kappa'])
  244. all_degrees.append(dstats['degrees'])
  245. # Centrality statistics
  246. cstats = compute_centrality_stats(G)
  247. gini_ces.append(cstats['gini_ce'])
  248. hub_fracs.append(cstats['hub_fraction'])
  249. # Topology statistics
  250. tstats = compute_topology_stats(G)
  251. clusterings.append(tstats['clustering'])
  252. path_lengths.append(tstats['avg_path_length'])
  253. # Power-law fit (BA only — ER and WS are not power-law)
  254. if topo_name == 'BA':
  255. gamma, ks_p, _ = powerlaw_fit(dstats['degrees'])
  256. gamma_hats.append(gamma)
  257. ks_pvals.append(ks_p)
  258. elapsed = time.time() - t0
  259. print(f" Completed {N_REALIZATIONS} realizations in {elapsed:.1f}s")
  260. # Ensemble statistics
  261. res = {
  262. 'k_mean': (np.mean(k_means), np.std(k_means)),
  263. 'k_std': (np.mean(k_stds), np.std(k_stds)),
  264. 'k_max': (np.mean(k_maxs), np.std(k_maxs)),
  265. 'kappa': (np.mean(kappas), np.std(kappas)),
  266. 'clustering': (np.mean(clusterings), np.std(clusterings)),
  267. 'avg_path': (np.mean(path_lengths), np.std(path_lengths)),
  268. 'gini_ce': (np.mean(gini_ces), np.std(gini_ces)),
  269. 'hub_fraction': (np.mean(hub_fracs), np.std(hub_fracs)),
  270. }
  271. if topo_name == 'BA':
  272. valid_gamma = [g for g in gamma_hats if not np.isnan(g)]
  273. valid_ks = [p for p in ks_pvals if not np.isnan(p)]
  274. res['gamma_hat'] = (np.mean(valid_gamma), np.std(valid_gamma))
  275. res['ks_pvalue'] = (np.mean(valid_ks), np.std(valid_ks))
  276. results[topo_name] = res
  277. # Store ensemble arrays for downstream use
  278. ensemble_data[f'{topo_name}_kappas'] = np.array(kappas)
  279. ensemble_data[f'{topo_name}_gini'] = np.array(gini_ces)
  280. ensemble_data[f'{topo_name}_hub_frac'] = np.array(hub_fracs)
  281. ensemble_data[f'{topo_name}_k_means'] = np.array(k_means)
  282. ensemble_data[f'{topo_name}_k_stds'] = np.array(k_stds)
  283. ensemble_data[f'{topo_name}_k_maxs'] = np.array(k_maxs)
  284. ensemble_data[f'{topo_name}_clusterings'] = np.array(clusterings)
  285. ensemble_data[f'{topo_name}_path_lengths'] = np.array(path_lengths)
  286. # Store exemplar network (seed=42) for visualization
  287. G_exemplar = topo_info['generator'](BASE_SEED)
  288. pos_exemplar = nx.spring_layout(G_exemplar, seed=BASE_SEED,
  289. k=1.8 / np.sqrt(N), iterations=80)
  290. deg_exemplar = np.array([G_exemplar.degree(n) for n in G_exemplar.nodes()])
  291. try:
  292. ce_exemplar = np.array(list(
  293. nx.eigenvector_centrality_numpy(G_exemplar).values()))
  294. except Exception:
  295. ce_exemplar = np.zeros(N)
  296. ce_norm = (ce_exemplar - ce_exemplar.min()) / (
  297. ce_exemplar.max() - ce_exemplar.min() + 1e-10)
  298. pos_array = np.array([pos_exemplar[n] for n in G_exemplar.nodes()])
  299. edges_array = np.array(list(G_exemplar.edges()))
  300. ensemble_data[f'net_{topo_name}_pos'] = pos_array
  301. ensemble_data[f'net_{topo_name}_degs'] = deg_exemplar
  302. ensemble_data[f'net_{topo_name}_ce'] = ce_norm
  303. ensemble_data[f'net_{topo_name}_edges'] = edges_array
  304. return results, ensemble_data
  305. def print_results(results):
  306. """Print results in Table S1d format."""
  307. print("\n" + "=" * 70)
  308. print("TABLE S1d — Structural validation measures")
  309. print(f"(ensemble means ± SD; {N_REALIZATIONS} realizations; "
  310. f"N = {N}, ⟨k⟩ ≈ 6, seed base = {BASE_SEED})")
  311. print("=" * 70)
  312. measures = [
  313. ('⟨k⟩', 'k_mean'),
  314. ('σ_k', 'k_std'),
  315. ('k_max', 'k_max'),
  316. ('κ = ⟨k²⟩/⟨k⟩', 'kappa'),
  317. ('Clustering', 'clustering'),
  318. ('Avg path', 'avg_path'),
  319. ('Gini(C_e)', 'gini_ce'),
  320. ('Hub fraction', 'hub_fraction'),
  321. ]
  322. header = f"{'Measure':<18} {'ER (Random)':<20} {'WS (Small-World)':<20} {'BA (Scale-Free)':<20}"
  323. print(header)
  324. print("-" * 78)
  325. for label, key in measures:
  326. row = f"{label:<18}"
  327. for topo in ['ER', 'WS', 'BA']:
  328. mean, sd = results[topo][key]
  329. row += f" {mean:>7.2f} ± {sd:<6.2f} "
  330. print(row)
  331. # BA-specific measures
  332. if 'gamma_hat' in results['BA']:
  333. mean, sd = results['BA']['gamma_hat']
  334. print(f"{'γ̂ (MLE)':<18} {'---':<20} {'---':<20} {mean:>7.2f} ± {sd:<6.2f}")
  335. if 'ks_pvalue' in results['BA']:
  336. mean, sd = results['BA']['ks_pvalue']
  337. print(f"{'KS p-value':<18} {'---':<20} {'---':<20} {mean:>7.2f} ± {sd:<6.2f}")
  338. # Manuscript Table 2 comparison
  339. print("\n" + "=" * 70)
  340. print("VERIFICATION against manuscript Table 2")
  341. print("=" * 70)
  342. expected = {
  343. 'ER': {'kappa': 6.84, 'gini_ce': 0.26, 'hub_fraction': 0.16},
  344. 'WS': {'kappa': 6.09, 'gini_ce': 0.16, 'hub_fraction': 0.16},
  345. 'BA': {'kappa': 9.67, 'gini_ce': 0.35, 'hub_fraction': 0.10},
  346. }
  347. for topo in ['ER', 'WS', 'BA']:
  348. print(f"\n {topo}:")
  349. for key, exp_val in expected[topo].items():
  350. sim_val = results[topo][key][0]
  351. match = "✓" if abs(sim_val - exp_val) / (exp_val + 1e-10) < 0.15 else "✗"
  352. print(f" {key:<15} expected={exp_val:.2f} simulated={sim_val:.2f} {match}")
  353. def save_results(results, ensemble_data):
  354. """Save results to CSV and NPZ files."""
  355. os.makedirs(OUTPUT_DIR, exist_ok=True)
  356. # CSV summary
  357. csv_path = os.path.join(OUTPUT_DIR, 'network_structural_metrics.csv')
  358. with open(csv_path, 'w') as f:
  359. f.write("topology,measure,mean,sd\n")
  360. for topo in ['ER', 'WS', 'BA']:
  361. for key, (mean, sd) in results[topo].items():
  362. f.write(f"{topo},{key},{mean:.6f},{sd:.6f}\n")
  363. print(f"\nSaved: {csv_path}")
  364. # NPZ ensemble data (for downstream scripts and figure generation)
  365. npz_path = os.path.join(OUTPUT_DIR, 'network_ensemble_data.npz')
  366. np.savez_compressed(npz_path, **ensemble_data)
  367. print(f"Saved: {npz_path}")
  368. # ══════════════════════════════════════════════════════════════
  369. # ENTRY POINT
  370. # ══════════════════════════════════════════════════════════════
  371. if __name__ == '__main__':
  372. results, ensemble_data = run_ensemble()
  373. print_results(results)
  374. save_results(results, ensemble_data)
  375. print("\n✓ 01_network_generation.py complete.")

01_network_generation.py at commit 04d398f, under MIT · at the source

Overview

Authors: Chulwook Park1,2,3
ORCID iDs: Chulwook Park
  1. Department of Physical Education, Seoul National University, Seoul, South Korea
  2. Systemic Risk and Resilience, International Institute for Applied Systems Analysis (IIASA), Laxenburg, Austria
  3. Complexity Science and Evolution, Okinawa Institute of Science and Technology (OIST), Okinawa, Japan
Journal: PLoS computational biology, volume 22, issue 7, article e1014523
Dates: received 6 March 2026; accepted 1 July 2026; published online 21 July 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pcbi.1014523 · PMID 42479799 · PMCID PMC13423191 · OpenAlex W7169861276
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: computational modeling (no new data) (modality), human (organism), computational (subfield)
Methods: Statistics, Smoothing, state filtering, decompositions, Graphs, Physiology & signal measures, Spectral & time-frequency
MeSH: Learning*, Models, Neurological*, Motor Skills*, Nerve Net*, Brain, Computational Biology, Computer Simulation, Humans (* major topic)
Topic: Motor Control and Adaptation (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: National Research Foundation of Korea (2020R1I1A1A01056967); Ministry of Education (MOE), Korea – BK21 FOUR Program
Citations: not cited yet (Europe PMC); 71 references in the paper

Abstract

Coordinative structures are the functional groupings of degrees of freedom that simplify motor control. Decades of research have documented them well, yet they remain mechanistically unexplained. How they emerge and why they are hierarchically organized are both unresolved questions. This study proposes scale-free network topology as the missing mechanism. Systematic simulations compared random networks, small-world networks, and scale-free networks. Scale-free organization reproduced the defining features of coordinative structures more completely than either alternative. Those features are a hub-periphery hierarchy, ordered hub-first recruitment, an abrupt onset of global coordination, and a balance between stability and flexibility. Four formal correspondences connect these features to established coordination phenomena. A coupled learning model reproduced the characteristic curve of skill acquisition, and scale-free networks reached the coordination threshold fastest. The model was then validated against published data from five independent studies spanning motor learning, bimanual coordination, brain networks, and joint coordination. It yields eleven testable predictions with explicit quantitative thresholds, together with five criteria that would disconfirm it. Network topology therefore offers a principled account of how coordinative structures form through structural constraints and experience. That account is empirically grounded and open to falsification.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 14 matches between paragraphs and lines of code.

pcw8531/Coordinative-structures-scale-free-networks

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 04d398f99cf12af41cbd2324fba7fa8754bf5036, 7 July 2026
Languages: Python (4)
Size: 16 files, 4 scripts
Software Heritage: not archived
Found in: “Data Availability”
Holds: README, license file, environment (requirements.txt)
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: NetworkX (4 files), NumPy (4 files), SciPy (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
6 files

Zenodo 20694466

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data Availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NetworkX (4 files), NumPy (4 files), SciPy (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
6 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 8 scripts, each with its path and the digest of its content;
  • 14 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data Availability

All data underlying the findings are within the paper and its Supporting information files. The complete simulation source code is openly available under an MIT license at https://github.com/pcw8531/Coordinative-structures-scale-free-networks and archived on Zenodo at https://doi.org/10.5281/zenodo.20694466.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 1 author, 8 MeSH terms, 2 funders, 47 references.

Cite

This paper

Park, C. (2026). Coordinative structures as scale-free networks: Cascade and percolation dynamics in motor learning with empirical validation. PLoS computational biology, 22(7), e1014523. https://doi.org/10.1371/journal.pcbi.1014523

BibTeX

@article{park2026coordinative,
author = {Park, Chulwook},
title = {{Coordinative structures as scale-free networks: Cascade and percolation dynamics in motor learning with empirical validation}},
journal = {PLoS computational biology},
year = {2026},
month = jul,
volume = {22},
number = {7},
pages = {e1014523},
publisher = {PLOS},
issn = {1553-734X},
doi = {10.1371/journal.pcbi.1014523},
url = {https://doi.org/10.1371/journal.pcbi.1014523},
pmid = {42479799},
pmcid = {PMC13423191}
}

RIS

TY - JOUR
AU - Park, Chulwook
TI - Coordinative structures as scale-free networks: Cascade and percolation dynamics in motor learning with empirical validation
T2 - PLoS computational biology
J2 - PLoS Comput Biol
PY - 2026
DA - 2026/07/21
VL - 22
IS - 7
SP - e1014523
SN - 1553-734X
PB - PLOS
DO - 10.1371/journal.pcbi.1014523
UR - https://doi.org/10.1371/journal.pcbi.1014523
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pcbi.1014523",
"type": "article-journal",
"title": "Coordinative structures as scale-free networks: Cascade and percolation dynamics in motor learning with empirical validation",
"container-title": "PLoS computational biology",
"author": [
{
"family": "Park",
"given": "Chulwook"
}
],
"container-title-short": "PLoS Comput Biol",
"volume": "22",
"issue": "7",
"page": "e1014523",
"DOI": "10.1371/journal.pcbi.1014523",
"PMID": "42479799",
"PMCID": "PMC13423191",
"ISSN": "1553-734X",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pcbi.1014523",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
21
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41467-026-72510-9 [code]
Single-neuron network topology governs neural computation and learning in primate cortex.
Journal: Nature communications
In common: SciPy, NumPy, 5 references
[2] doi:10.1038/s41467-026-74466-2 [code]
Neuromorphic hierarchical modular reservoirs.
Journal: Nature communications
In common: NetworkX, SciPy, NumPy, computational, 2 references
[3] doi:10.1088/1741-2552/ae5fd7 [code]
Metric validation for detection of delayed and directed coupling.
Journal: Journal of neural engineering
In common: NetworkX, SciPy, NumPy, computational modeling (no new data), 2 references
[4] doi:10.1038/s41467-026-73347-y [code]
A week in the life of the human brain reveals stable states punctuated by chaotic-like transitions.
Journal: Nature communications
In common: SciPy, NumPy, computational, computational modeling (no new data), 2 references
[5] doi:10.1162/netn.a.545 [code]
Structure-function multilayer network integration and cognition in multiple sclerosis.
Journal: Network neuroscience (Cambridge, Mass.)
In common: NetworkX, SciPy, NumPy, 2 references
[6] doi:10.1016/j.isci.2026.116144 [code]
Spatial continuity of neurons explains non-random network architecture.
Journal: iScience
In common: NetworkX, SciPy, NumPy, 2 references
[7] doi:10.1523/jneurosci.0912-25.2026 [code]
Hierarchical Afferent Connectivity Drives Population-Wide Bursting Dynamics in a Computational Model of Human-Derived Excitatory Neuronal Networks.
Journal: The Journal of neuroscience : the official journal of the Society for Neuroscience
In common: NetworkX, SciPy, NumPy, 2 references
[8] doi:10.1371/journal.pcbi.1014730 [code]
A unified model of short- and long-term plasticity: Effects on network connectivity and information capacity.
Journal: PLoS computational biology
In common: NetworkX, SciPy, NumPy, computational modeling (no new data), 1 reference
[9] doi:10.1038/s41598-026-43529-1 [code]
A spiking neural network inspired by neuroscience and psychology for Western mode- and key-conditioned music learning and composition.
Journal: Scientific reports
In common: NetworkX, SciPy, NumPy, computational modeling (no new data), 1 reference
[10] doi:10.1073/pnas.2604933123
Neuromotor modules revealed by direct electrical stimulation of the human primary motor cortex.
Journal: Proceedings of the National Academy of Sciences of the United States of America
In common: 3 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.