OSCR

Manifold-constrained plasticity enables stable learning in recurrent neural circuits.

Code ↔ Paper

5 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 5 matches · 3 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § Results › Decoder performance depends on alignment with the intrinsic activity manifold ↔ SPLIT2.m, lines 1–140 · score 0.55 · random rotation, outside manifold, QR, orthogonal, matrix, orthonormal
  2. [2] § Results › Manifold-constrained learning stabilizes decoder adaptation in low-dimensional networks ↔ SPLIT3.m, the whole file · a weak match · score 0.53 · neural space, low dimensional manifold, high dimensional, decoder updates, reconstruct, adaptation
  3. [3] § Results › Manifold-constrained learning stabilizes decoder adaptation in low-dimensional networks ↔ SPLIT1.m, the whole file · a weak match · score 0.53 · neural space, low dimensional manifold, high dimensional, decoder updates, reconstruct, adaptation
  4. [4] § Results › SPLiT outperforms existing drift-adaptation rules under constrained dynamics ↔ ideal_observer1.m, the whole file · a weak match · score 0.53 · postsynaptic neuron, inverse correlation, readout, dynamics
  5. [5] § Results › Decoder performance depends on alignment with the intrinsic activity manifold ↔ SPLIT2.m, lines 1–140 · score 0.52 · orthogonal rotation, latent coordinates, remapped, subspace, perturbations, activity

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

MATLAB · 259 lines · 9.3 KB · no license · 2 matches

  1. clear all;
  2. warning off all
  3. rng(1);
  4. % == Parameters ===
  5. N = 25; %(25)
  6. dt = 0.01; %0.01
  7. tau = 0.3; %(0.3)
  8. eta_r = 0.001; % step size for random drift in activity (0.001)
  9. proj_dim = 1; % dimension of low-D manifold (1)
  10. g = 1.5; % gain for initial weights (1.5)
  11. alpha = 1.5; % feedback strength (1.5)
  12. eta_U = 0.01; %Oja manifold adaptation rate (0.01)
  13. feedback_ratio = 1; %increase when increasing proj_dim (1)
  14. lambda = 0.1; %decoder learning rate (0.1)
  15. use_within_manifold = false;
  16. perturb_mode = 'outside'; % 'within' or 'outside' or 'none'
  17. theta = pi/2; % "outside-ness": 0 = fully within; pi/2 = fully orthogonal
  18. target_noise_var = 0;
  19. % Target output: center out task
  20. centerout;
  21. z2 = repmat(z_target,1,3);
  22. z_target = z2;
  23. steps = size(z_target,2);
  24. T = steps*dt;
  25. % === Fixed manifold basis ===
  26. U_fixed = orth(randn(N, proj_dim)); % low-D manifold
  27. % === Initialization ===
  28. x = 0.1 * randn(N,1);
  29. r = tanh(x);
  30. s = U_fixed' * r; % low-D coordinates if using manifold
  31. % Fixed recurrent weights
  32. W = g * randn(N, N) / sqrt(N);
  33. W_red = U_fixed' * W * U_fixed; % projected weights for low-D dynamics
  34. desired_rho = 1;
  35. rho_red = max(abs(eig(W_red)));
  36. W_red = W_red / max(1, rho_red / desired_rho);
  37. % Low-D basis (Oja's rule)
  38. U = orth(randn(N, proj_dim));
  39. D_proj = zeros(2, proj_dim); % decoder for 2D output
  40. % Logging
  41. r_log = zeros(N, steps);
  42. z_out = zeros(2, steps);
  43. % ============================
  44. % Perturbation configuration
  45. % ============================
  46. out_dim = size(z_target,1); % 1 for sine, 2 for cursor, etc.
  47. D_proj = zeros(out_dim, proj_dim); % decoder
  48. z_out = zeros(out_dim, steps);
  49. k_pert = round(steps/2); % apply perturbation halfway
  50. % --- Within-manifold: latent coordinate remapping P ---
  51. % Use either a permutation or a random rotation.
  52. P = eye(proj_dim); % no perturbation initially
  53. use_rotation = true; % true = random orthogonal rotation; false = permutation
  54. % --- Outside-manifold: build a subspace U_perp orthogonal to U_fixed ---
  55. % (same dimension as manifold)
  56. U_perp = randn(N, proj_dim);
  57. U_perp = U_perp - U_fixed*(U_fixed' * U_perp); % remove components in span(U_fixed)
  58. U_perp = orth(U_perp); % orthonormalize
  59. % --- I/O basis used for decoding + feedback injection (starts unperturbed) ---
  60. U_io = U; % by default, same as your learned Oja basis
  61. % === Freeze Oja for a short window after perturbation ===
  62. oja_freeze_start = 1601;
  63. oja_freeze_end = 1600*2;
  64. freeze_dec_len = round(0.1*steps); % x% window
  65. dec_freeze_end = oja_freeze_end;
  66. lambda0 = lambda;
  67. % === Weight-change logging ===
  68. dD_norm = zeros(1, steps); % magnitude of decoder update
  69. for k = 1:steps
  70. % ================================================================
  71. % Apply perturbation at k_pert (BCI mapping change)
  72. % ================================================================
  73. if k == k_pert
  74. switch lower(perturb_mode)
  75. case 'within'
  76. % Keep U_io the same, change only latent coordinates via P
  77. if use_rotation
  78. % Random orthogonal rotation: P'P = I
  79. [Q,~] = qr(randn(proj_dim));
  80. P = Q;
  81. D_proj = D_proj * P'; %optional
  82. else
  83. % Permutation matrix
  84. p = randperm(proj_dim);
  85. P = eye(proj_dim);
  86. P = P(:,p);
  87. end
  88. case 'outside'
  89. % Keep P = I; change the basis used for readout/feedback to include orthogonal component
  90. P = eye(proj_dim);
  91. % Mix current U with an orthogonal-to-U_fixed subspace
  92. % (and re-orthonormalize)
  93. U_io = orth(cos(theta)*U + sin(theta)*U_perp);
  94. otherwise
  95. % 'none'
  96. P = eye(proj_dim);
  97. U_io = U;
  98. end
  99. use_within_manifold = false; %MODIFIED HERE: SETTING OUTSIDE MANIFOLD AFTER PERTURBATION
  100. end
  101. if use_within_manifold
  102. % ================================================================
  103. % 1) Compute feedback from current activity (pre-update)
  104. % ================================================================
  105. % Current low-D readout coordinates (for decoding only)
  106. y_fb = U_io' * r; % proj_dim x 1
  107. y_fb_eff = P * y_fb; % perturbed latent coords (within-manifold)
  108. z_fb = D_proj * y_fb_eff; % out_dim x 1
  109. % Mix target and current output (same as before)
  110. feedback = (1 - feedback_ratio) * z_fb + feedback_ratio * z_target(:,k);
  111. feedback = min(max(feedback, -2), 2);
  112. %MODIFIED HERE: SETTING FEEDBACK TO ZERO
  113. %%%%%%%%%%%%%%%%%%%%%
  114. % feedback = zeros(1,2)';
  115. %%%%%%%%%%%%%%%%%%%%%
  116. % Map feedback back into neural space, then project into manifold
  117. % Effective decoder under within-manifold perturbation:
  118. % z = D_proj * (P * (U_io' r)) => D_eff = D_proj * P
  119. D_eff = D_proj * P;
  120. I_fb_full = alpha * U_io * (D_eff') * feedback; % N x 1
  121. I_fb_low = U_fixed' * I_fb_full; % proj_dim x 1
  122. % ================================================================
  123. % 2) Low-dimensional manifold dynamics for s
  124. % ================================================================
  125. d_s_rec = (-s + W_red * s) / tau; % recurrent term
  126. d_s_noise = (eta_r * sqrt(N/proj_dim)) * randn(proj_dim,1); % noise
  127. % Add feedback as an extra driving term in low-D
  128. s = s + dt * (d_s_rec + I_fb_low) + d_s_noise;
  129. % ================================================================
  130. % 3) Reconstruct full activity strictly within manifold
  131. % ================================================================
  132. x = U_fixed * s; % latent variable along manifold
  133. r = tanh(x); % N x 1 activity on manifold
  134. % Optional numerical safety on r/x (not used for dynamics here)
  135. r_clipped = max(min(r, 0.999), -0.999);
  136. x = atanh(r_clipped);
  137. else
  138. % ================================================================
  139. % Unconstrained high-dimensional dynamics (original branch)
  140. % ================================================================
  141. d_r = eta_r * randn(N,1);
  142. r = tanh(r + dt * (-r + W * r) / tau + d_r);
  143. r_clipped = max(min(r, 0.999), -0.999);
  144. x = atanh(r_clipped);
  145. end
  146. % ================================================================
  147. % 4) Oja's Rule for low-D decoder basis U
  148. % Freeze temporarily after perturbation
  149. % ================================================================
  150. if ~(k >= oja_freeze_start && k < oja_freeze_end)
  151. r_centered = r - mean(r);
  152. for i = 1:proj_dim
  153. u = U(:,i);
  154. % (r_proj/var_proj not needed for your delta_u form; can remove if you want)
  155. delta_u = eta_U * (r_centered * (r_centered' * u) - (u' * u) * u);
  156. U(:,i) = u + delta_u;
  157. end
  158. U = orth(U); % re-orthonormalize decoder basis
  159. end
  160. % Keep default I/O basis tied to current U unless we're in "outside" mode
  161. % where U_io is explicitly set at perturbation and should remain fixed.
  162. if ~strcmpi(perturb_mode,'outside')
  163. U_io = U;
  164. end
  165. % ================================================================
  166. % 5) Update decoder D_proj using OP-LMS (unchanged)
  167. % Uses updated r (post-dynamics) but same time index k
  168. % ================================================================
  169. y = U_io' * r; % proj_dim x 1
  170. y_eff = P * y; % perturbed latent coords
  171. z = D_proj * y_eff; % out_dim x 1
  172. z_out(:,k) = z;
  173. if k >= k_pert && k < dec_freeze_end
  174. lambda_eff = 0; % no learning immediately after perturbation
  175. else
  176. lambda_eff = lambda0; % relearn afterwards
  177. end
  178. err = z - z_target(:,k) + randn(out_dim,1).*target_noise_var;
  179. y_eff_norm = y_eff / (norm(y_eff) + 1e-8);
  180. dD = -lambda_eff * err * (y_eff_norm)'; % out_dim x proj_dim
  181. D_proj = D_proj + dD;
  182. dD_norm(k) = norm(dD, 'fro');
  183. % ================================================================
  184. % 6) Logging
  185. % ================================================================
  186. r_log(:,k) = r;
  187. end
  188. z = z_target(:,1600*2+1:end);
  189. o = z_out(:,1600*2+1:end);
  190. final_err = mean((z(:)-o(:)).^2);
  191. %plot center-out task
  192. %initial learning
  193. figure;
  194. plot(z_target(1,1:1600), z_target(2,1:1600), 'Color', [181 59 59]./255,'linewidth',12);
  195. hold on;
  196. plot(z_out(1,1:1600), z_out(2,1:1600),'Color', [158 159 43]./255,'linewidth',6);
  197. axis off
  198. %recovery after perturbation
  199. figure;
  200. plot(z_target(1,1600*2+1:end), z_target(2,1600*2+1:end), 'Color', [181 59 59]./255,'linewidth',12);
  201. hold on;
  202. plot(z_out(1,1600*2+1:end), z_out(2,1600*2+1:end),'Color', [158 159 43]./255,'linewidth',6);
  203. axis off

SPLIT2.m, no license · at the source

Overview

Authors: Camille Godin1, Jean-Philippe Thivierge1,2
  1. School of Psychology, University of Ottawa, Ottawa, Canada
  2. Brain and Mind Research Institute, University of Ottawa, Ottawa, Canada
Journal: PLoS computational biology, volume 22, issue 8, article e1014719
Dates: received 2 March 2026; accepted 17 August 2026; published online 25 August 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pcbi.1014719 · PMID 42640956 · PMCID PMC13529248 · OpenAlex W7204199017
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: human (organism)
Methods: Machine learning, Connectivity
MeSH: Learning*, Models, Neurological*, Nerve Net*, Neural Networks, Computer*, Neuronal Plasticity*, Algorithms, Animals, Computational Biology, Humans, Neurons, Recurrent Neural Networks (* major topic)
Topic: Advanced Memory and Neural Computing (Electrical and Electronic Engineering, Engineering), according to OpenAlex
Funding: Natural Sciences and Engineering Research Council of Canada (NSERC); natural sciences and engineering council of canada (210977)
Citations: not cited yet (Europe PMC); 85 references in the paper

Abstract

The activity of large neuronal populations is often confined to low-dimensional manifolds that can drift over time, posing a challenge for learning rules that assume stable, full-rank representations. Here, we introduce SPLiT (Synaptic Projection Learning with intrinsic Tracking), a synaptic plasticity rule for recurrent neural networks that combines unsupervised manifold tracking with supervised learning. SPLiT uses an online Oja rule to continuously estimate the intrinsic low-dimensional activity subspace and performs normalized least-mean-squares learning in manifold coordinates. In this way, SPLiT keeps synaptic weights aligned with evolving population dynamics. Using a rate-based recurrent network, we show that SPLiT reliably learns time-varying target signals under both constrained dynamics, where activity is restricted to a fixed low-dimensional manifold, and unconstrained dynamics exhibiting changes in the dominant activity subspace. We show that manifold-constrained learning with SPLiT yields faster convergence, less sensitivity to recurrent gain, smaller weight updates, and is more robust to noisy teaching signals. Analytical results show that SPLiT learns the optimal decoder projected onto the instantaneous principal subspace and maintains bounded error under drift. Together, these findings provide a mechanistic account of how synaptic plasticity can leverage the structure of neural manifolds to enable stable and efficient supervised learning despite representational drift.

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

Repository

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

supp:PMC13529248/pcbi.1014719.s002.zip

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Languages: MATLAB (9)
Size: 10 files, 9 scripts
Software Heritage: not checked
Found in: the supplementary material
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
10 files

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:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 9 scripts, each with its path and the digest of its content;
  • 5 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 relevant data are within the manuscript and its Supporting Information files.

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, 2 authors, 11 MeSH terms, 2 funders, 80 references.

Cite

This paper

Godin, C., & Thivierge, J.-P. (2026). Manifold-constrained plasticity enables stable learning in recurrent neural circuits. PLoS computational biology, 22(8), e1014719. https://doi.org/10.1371/journal.pcbi.1014719

BibTeX

@article{godin2026manifold,
author = {Godin, Camille and Thivierge, Jean-Philippe},
title = {{Manifold-constrained plasticity enables stable learning in recurrent neural circuits}},
journal = {PLoS computational biology},
year = {2026},
month = aug,
volume = {22},
number = {8},
pages = {e1014719},
publisher = {PLOS},
issn = {1553-734X},
doi = {10.1371/journal.pcbi.1014719},
url = {https://doi.org/10.1371/journal.pcbi.1014719},
pmid = {42640956},
pmcid = {PMC13529248}
}

RIS

TY - JOUR
AU - Godin, Camille
AU - Thivierge, Jean-Philippe
TI - Manifold-constrained plasticity enables stable learning in recurrent neural circuits
T2 - PLoS computational biology
J2 - PLoS Comput Biol
PY - 2026
DA - 2026/08/25
VL - 22
IS - 8
SP - e1014719
SN - 1553-734X
PB - PLOS
DO - 10.1371/journal.pcbi.1014719
UR - https://doi.org/10.1371/journal.pcbi.1014719
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pcbi.1014719",
"type": "article-journal",
"title": "Manifold-constrained plasticity enables stable learning in recurrent neural circuits",
"container-title": "PLoS computational biology",
"author": [
{
"family": "Godin",
"given": "Camille"
},
{
"family": "Thivierge",
"given": "Jean-Philippe"
}
],
"container-title-short": "PLoS Comput Biol",
"volume": "22",
"issue": "8",
"page": "e1014719",
"DOI": "10.1371/journal.pcbi.1014719",
"PMID": "42640956",
"PMCID": "PMC13529248",
"ISSN": "1553-734X",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pcbi.1014719",
"language": "en",
"issued": {
"date-parts": [
[
2026,
8,
25
]
]
}
}

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.1016/j.neuron.2026.07.016 [code]
Inferring brain-wide interactions using data-constrained recurrent neural network models.
Journal: Neuron
In common: 11 references
[2] doi:10.1371/journal.pone.0321830
Long-term neuron tracking reveals balance of stability and plasticity in functional properties.
Journal: PloS one
In common: 8 references
[3] doi:10.1371/journal.pcbi.1014297 [code]
Statistics of cortical representational drift can enable robust readout.
Journal: PLoS computational biology
In common: 6 references
[4] doi:10.1016/j.isci.2026.117492 [code]
Neural subspace reorganization reflects value-based decision-making.
Journal: iScience
In common: 7 references
[5] doi:10.1038/s42003-026-10036-y
Drifting population dynamics with transient resets characterize sensorimotor transformation in the monkey superior colliculus.
Journal: Communications biology
In common: 7 references
[6] doi:10.3390/biomimetics11080569 [code]
Pretraining of Embodied Recurrent Networks Bridges the Gap Between Artificial and Cortical Neural Activities.
Journal: Biomimetics (Basel, Switzerland)
In common: 7 references
[7] doi:10.1038/s41598-026-55225-1 [code]
Benchmarking criteria to determine latent linear dimensionality in neural data.
Journal: Scientific reports
In common: 7 references
[8] doi:10.1080/26941899.2026.2619222
Neurodatascience: Past, Present, and Future.
Journal: Data science in science
In common: 7 references
[9] doi:10.1371/journal.pcbi.1014162 [code]
Exploring neural manifolds across a wide range of intrinsic dimensions.
Journal: PLoS computational biology
In common: 6 references
[10] doi:10.1038/s41467-026-75924-7 [code]
Data-driven reduced modeling of neural dynamics.
Journal: Nature communications
In common: 6 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.