This repository contains the code to implement the synthesis of constant inputs to drive a dynamical system (particularly a continous-time RNN) from an initial state to a target state in a given time horizon (Tamekue et al., 2025).
Consider a nonlinear system with dynamics:
where
Under very general assumptions, we can prove that the flow of the autonumous dynamics
Goal: for an initial state
If
where
Two sufficient conditions for the invertibility of
- The spectral norm of the connectivity matrix
$|||W|||$ is smaller than the minimum decay rate$\lambda_{\min}(D)$ . -
$\lambda = i\frac{2\pi l}{T}, \forall l \in \mathbb{Z}$ is not an eigenvalue of$A = W - D$ , namely$e^{TA}$ does not have an eigenvalue of 1.
For nonlinear systems, we can only provide an approximate to the actual input that solves the two-point boundary value problem. In the sections below, we present several methods to synthesize the input
As the name suggests, we let
The following input
This method linearized the system at the origin (which is always a fixed point of the autonomous dynamics) rather than
This section covers the methods presented in the final version of this paper.
The synthesis is given by
The synthesis is given by
This section covers the methods developed during the review process of this paper.
The synthesis is given by
The synthesis is given by
This section covers the methods proposed in the preprint version of this paper, which are based on the Jacobian of the backward or forward flow.
This method is simply called "backward" method in the preprint. It is now called "backward_push" as it involves pushing forward a vector using the flow
For nonlinear case, denote
It can be proved that whenever
where the error term
Two sufficient conditions for the invertibility of
-
$|f'(0)|\cdot|||W||| < \lambda_{\min}(D)$ . -
$\lambda = i\frac{2\pi l}{T}, \forall l \in \mathbb{Z}$ is not an eigenvalue of$B_{T}(x^{1})$ .
Also note that if
and the error term is zero.
This method is simply called "forward" method in the preprint. It is now called "forward pull" as it involves pulling back a vector using the backward flow
The synthesis is given by
where the error term
We implement the synthesis using Pytorch and the torchdiffeq package. Here we use the "backward push" method as an example.
We need to compute three terms:
- The terminal state
$\Psi_{T}(x^{1})$ of the inverse flow starting from$x^{1}$ . - The differential
$DN$ at this terminal state. - The inverse of the differential
$D \Psi_{T}$ of the inverse flow starting from$x^{1}$ , or equivalently, the differential$D \Phi_{T}$ starting from the terminal state.
The main difficulty is to compute the differential of the flow. We can do this in two ways:
- Use
torch.autograd.functional.jvpto compute the product of$D \Phi_{T}(\Psi_{T}(x^{1})) = [D\Psi_{T}(x^{1})]^{-1}$ and the vector$[e^{TB_{T}(x^{1})} - \text{Id}]^{-1}B_{T}(x^{1})(\Psi_{T}(x^{1}) - x^{0})$ . - Use
torch.autograd.functional.jacobianto get the jacobian, then compute everything as they appeared in the equation.
The first method is very fast and memory efficient. The second method requires computing the whole matrix, which is VERY SLOW AND MEMORY INTENSE (mostly because it is not vectorized), so we did not use it.
Special note on the compatibility of torchdiffeq and torch.func
For torchdiffeq version 0.2.3 and torch version 2.0+:
torchdiffeqdoes not supporttorch.func.vmap().- Adaptive solvers in
torchdiffeqdoes not supporttorch.func.jvp(). - However, adaptive solvers do work well with
torch.autograd.functional.jvp(). torch.autograd.functional.jvp()is not aware of batch dimensions. However, its results are still mathematically correct even when the input is batched.- More specifically,
torch.autograd.functional.jvp()treats the input as if they were concatenated, and computes the jacobian of the multidimensional function with respect to the multidimensional input. However, the derivative of other batches with respect to any certain batch is zero anyway, so the result is still correct.
- More specifically,
In the "backward push" method, we need to compute the inverse of
In our examples, the decay part is usually large relatively to the nonlinear part, so the eigenvalues of
For the "forward pull" method, we have:
So the numerical synthesis is given by
In the "backward push" method, we need to compute
In practice, we found that T and whatever systems we tried (including chaotic RNNs with weight scaling factor g > 1), using the default ODE solver in torchdiffeq.odeint. On the contrary, T > 20) and close-to-chaotic systems (e.g., RNNs with g > 0.8), even when using an extremely small absolute tolerance (atol=1e-14, rtol=1e-13).
Our hypothesis to this phenomenon is the following. Most systems we tried were dominated by the decay term, so the numerical error is tolerated when simulating forward but will magnify when simulating backward. As a result, the "backward push" method is much more stable than the "forward pull" method for large
Practical guideline:
- Always check the third output of the
synthesizefunction, which is the norm of the IVP error ($|\Phi_{T}(\Psi_{T}(x^{1})) - x^{1}|$ for the "backward push" method, and$|\Psi_{T}(\Phi_{T}(x^{0})) - x^{0}|$ for the "forward pull" method). - If using the "backward push" method, usually the default setting of
odeintshould be enough. - If using the "forward pull" method, you need to specify the following parameters for
odeint_kwargsinput of thesynthesizefunction:{'method': 'dopri8', 'rtol': 1e-13, 'atol': 1e-14}.- For close-to-chaotic systems, it seems like the
radauIIA5solver will be better, based on simulations withscipy.integrate.solve_ivp. - However, the current implementation of the
radauIIA5solver intorchdiffeqis unacceptably slow. It seems like there is a pull request in progress to fix this issue. We recommend trying out this solver for the "forward pull" method after the pull request is merged.
- For close-to-chaotic systems, it seems like the
If you use this code, please cite the following paper:
C. Tamekue, R. Chen and S. Ching, "On the Control of Recurrent Neural Networks using Constant Inputs," in IEEE Transactions on Automatic Control, doi: 10.1109/TAC.2025.3615934.
@ARTICLE{11184738,
author={Tamekue, Cyprien and Chen, Ruiqi and Ching, ShiNung},
journal={IEEE Transactions on Automatic Control},
title={On the Control of Recurrent Neural Networks using Constant Inputs},
year={2025},
volume={},
number={},
pages={1-16},
keywords={Brain modeling;Brain;Biological system modeling;Recurrent neural networks;Control theory;Symmetric matrices;Nonlinear dynamical systems;Mathematical models;Jacobian matrices;Controllability;Control Synthesis;Nonlinear Control;Recurrent Neural Networks;Neurostimulation;Transcranial Direct Current Stimulation},
doi={10.1109/TAC.2025.3615934}}
Chen, R. T. Q., Rubanova, Y., Bettencourt, J., & Duvenaud, D. K. (2018). Neural Ordinary Differential Equations. Advances in Neural Information Processing Systems, 31. https://proceedings.neurips.cc/paper_files/paper/2018/hash/69386f6bb1dfed68692a24c8686939b9-Abstract.html
Schuessler, F., Dubreuil, A., Mastrogiuseppe, F., Ostojic, S., & Barak, O. (2020). Dynamics of random recurrent networks with correlated low-rank structure. Physical Review Research, 2(1), 013111. https://doi.org/10.1103/PhysRevResearch.2.013111