Implementation¶
EnergyModel class¶
-
class
EnergyModel(num_neuron=1, firing_model=[{'model': 'linear', 'params': {'r_slope': 50, 'r_bias': 60}}], peq_model={'model': 'linear_pot', 'params': {'slope': -2.65}}, p0_model=None, boundary_mode=None, D0=0.56, Nv=None, pde_solve_param={}, verbose=False)¶ Energy Model class.
Parameters: - num_neuron : int
A number of neuronal responses. The default is 1.
- firing_model : list
For each neuron, this list contains the firing rate function. Each entry is either a function that returns an array of firing rate values, or a dictionary that specifies a model from
firing_rate_models.pyfile. The default is [{“model”: “linear”, “params”: {“r_slope”: 50, “r_bias”: 60}}].- peq_model : dictionary or callable
Equilibrium probability distribution density (which defines the driving force and Langevin potential, see Supplementary Section 1.1 in Genkin et. al. 2020 paper). This quantitiy defines the Potential function via Phi(x)=-log(peq(x)). Can be specified as a function, or as a dictionary that specifies one of the models from
peq_models.pyfile. The default is {“model”: “linear_pot”, “params”: {“slope”: -2.65}}.- p0_model : dictionary or callable or None
Initial probability distribution. Can be specified as a function, or as a dictionary that specifies one of the models from
peq_models.pyfile. If set to None, it will be assumed to be equal to peq (the equilibirum/stationary inference). The default is None.- D0 : float
Diffusion, or noise magnitude value. The default is 0.56.
- boundary_mode : string
Specify boundary mode that will set boundary conditions for the optimization/data generation. Possbile options are “reflecting”, “absorbing”, None. If set to None, the boundary conditions can be specified in pde_solve_param dictionary. The default is None.
- Nv : int
A number of retained eigenvalues/eigenvectors of the operator H. Too low value can degrade the quality, while too high value can result in long computational times. The default value is N-2, where N is the total number of grid points(for SEM N=Ne*(Np-1)+1). Since there are two boundary conditions, this is the maximum possible number of the retained eigenvalues. Note, that for numberical stability it is preferable to use the default value due to possible parasitic oscillation that arise from absorption operator. This is because for the operator exp(-Hdt) the contributions from the large eigenvalues decays exponentially, while for the absorption operator A=H0 it decays linearly, and generally cannot be neglected.
- pde_solve_param : dictionary
Dictionary of the parameters for PDE_Solve class, see also docstrings in
PDE_Solve.pyfile. Optional, as every entry has the default value. Possible entries:- xbegin : float
The left boundary of the latent state. The default is -1.
- xend : float
The right boundary of the latent state. The default is 1.
- method : dictionary
- A dictionary that contains 2 keys:
- name : string
Specifies the method for the numerical solution of EV problem, can be either ‘FD’ or ‘SEM’ (forward differences or spectral elements method).
- gridsize : dictionary
Specifies number of grid size points N for ‘FD’ method, or Np and Ne for ‘SEM’ method (Ne is the number of elements, Np is the number of grid points in each element).
The default is {‘name’: ‘SEM’, ‘gridsize’: {‘Np’: 8, ‘Ne’: 256}}.
- BoundCond : dictionary
A dictionary that specifies boundary conditions (Dirichlet, Neumann or Robin). If boundary mode is supplied, it will overwrite this variable. For this input pararmeter to be in effect, the boundary_mode should be set to None. The default is {‘leftB’: ‘Neumann’, ‘rightB’: ‘Neumann’}.
- grid_mode_calc : str
Specify how to calculate SEM grid collocation points. Availiable options: ‘built_in’: using numpy.polynomial module ‘newton’: using Newton’s method to calculate zeros of Legendre polinomial for the GLL grid The default is ‘newton’.
- BC_method : str
Specify the method of boundary condition handling when transforming the EV problem into linear system of equations. Availiable options: ‘projection’: use projection operator. ‘bound_subst’: use boundary condition substitution into the first and the last equations of the associated linear system. The default is ‘projection’
- int_mode : str
Specify the integration mode. Availiable options:
‘full’ - use full integration matrix. ‘sparse’ - use sparse integration matrix with a bias vector.
The default is ‘full’. See Supplementary Information for M. Genkin, T. A. Engel, Nat Mach Intell 2, 674–683 (2020) for details.
- verbose : bool
A boolean specifying the verbose level. The true value displays more messages. The default is False.
Attributes: - x_d_ : numpy array, dtype=float
Grid points. Will be calculated with
PDE_Solveclass.- w_d_ : numpy array, dtype=float
The corresponding SEM weights (only for SEM method).
- dmat_d_ : numpy array, dtype=float
The matrix for numerical differentiation.
- peq_ : numpy array, dtype=float
The equilibrium probability density evaluated on SEM grid
- p0_ : numpy array, dtype=float
The initial distribution p0.
- D_ : float
Noise intensity.
- fr_: numpy array, dtype=float
An array with firing rate functions evaluated on SEM grid. The number of columns is equal to the number of neuronal responses.
- N : int
Number of grid points
- Np : int
Number of grid points per element (only SEM method).
- Ne : int
Number of elements (only SEM method).
Methods
FeatureComplexity([peq])Calculate feature complexity from a givein peq for the case of equilibrium inference FeatureComplexityFderiv([peq])Variational derivative of feature complexity wrt force F for the case of equilibrium inference SaveResults([results_type])Save fitting results to a file calc_F(peq)Calculate force from the peq calc_peq(F)Calculate peq from the force fit([optimizer, options])Perform model fitting generate_data([deltaT, time_epoch, …])Generate spike data and latent trajectories. score(data[, metadata, peq, rho0, D, fr])Evaluate negative log-likelihood for a given data and model transform_spikes_to_isi(spikes, time_epoch, …)Convert spike times to data array, which is a suitable format for optimization. -
FeatureComplexity(peq=None)¶ Calculate feature complexity from a givein peq for the case of equilibrium inference
Parameters: - peq : numpy array, dtype=float
The equilibrium probability density evaluated on SEM grid. The default is self.peq_
Returns: - float
Feature complexity (only valid for equilibrium or stationary inference).
-
FeatureComplexityFderiv(peq=None)¶ Variational derivative of feature complexity wrt force F for the case of equilibrium inference
Parameters: - peq : numpy array, dtype=float
The equilibrium probability density evaluated on SEM grid. The default is self.peq_
Returns: - numpy array
The variational derivative of loglikelihood w.r.t. feature complexity (only valid for equilibrium or stationary inference).
-
SaveResults(results_type='iterations', **options)¶ Save fitting results to a file
Parameters: - results_type : str
Type of the results to save. Supported types: ‘iterations’, which saves iteration results. The default is ‘iterations’
- options : dict
- Availiable options:
- results : dictionary
dictionary with the results (mandatory)
- path : str
path to files. The default is empty str
- name : str
enforce a particular file name, otherwise, the default name will be generated.
- sim_id : int
id of a simulation (appended to the name and saved inside the dictionary). The default is empty str.
- iter_start : int
Starting iteration used for automatic filename generation. The default is iter_num[0]
- iter_end : int
Terminal iteration used for automatic filename generation. The default is iter_num[-1]
-
calc_F(peq)¶ Calculate force from the peq
Parameters: - peq : numpy array, dtype=float
Equilibirum probability distribution (peq), 1D array
Returns: - F : numpy array, dtype=float
Driving force, 1D array
-
calc_peq(F)¶ Calculate peq from the force
Parameters: - F : numpy array, dtype=float
Driving force, 1D array
Returns: - result : numpy array, dtype=float
Equilibirum probability distribution (peq), 1D array
-
fit(optimizer='GD', options=None)¶ Perform model fitting
Parameters: - data : numpy array (N,2), dtype=np.ndarray.
See docstring for score function for details.
- optimizer : str
Optimizier. Currently, the only availible option is ‘GD’. The default is ‘GD’.
- options : dictionary
see self._GD_optimization for availiable options of GD optimizer. The default is None
Returns: - em : self
A fitted EnergyModel object.
-
generate_data(deltaT=1e-05, time_epoch=[(0, 1)], last_event_is_spike=False)¶ Generate spike data and latent trajectories.
Parameters: - deltaT : float
Size of the time bin in seconds for the numerical integration of the Langevin equation. The default is 0.00001.
- time_epoch : list
List of N tuples, where N is the number of trials. Each tuple consists of start time and stop time in seconds. For the case of absorbing boundary, stop time will be the maximum allowed time for the trial to last (the trial will terminate before this time due to absorption, or at this time in an arbitrary latent state). The default is [(0,1)]. Example: We want to generate 100 trials that start at t=0 and end at t=2, in this case time_epoch=[(0,2)]*100
- last_event_is_spike : bool
If true, trial termination time will not be recorded. Otherwise, trial termination time will be recorded. The default is False.
Returns: - data : numpy array (N,2), dtype=np.ndarray.
Spike data packed as numpy array of the size (N,2), where each elements is a 1D array. N is the number of trials, and for each trial the first column contains inter spike intervals (ISIs) in seconds for all neurons, and the second column contains the corresponding neuronal IDs (trial termination, if recorded, is indicated with -1). data[i][0] - 1D array, a sequence of ISIs of all neurons for the trial i. The last entry can be time interval between the last spike and trial termination time. data[i][1] - 1D array, neuronal IDs of type int64 for the trial i. The last entry is -1 if the trial termination time is recorded. Example: neuron 0 spiked at times 0.12, 0.15, 0.25, and neuron 1 spiked at times 0.05, 0.2. Trial 0 started at t=0 and ended at t=0.28. In this case data[0][0]=np.array([0.05,0.07,0.03,0.05,0.05,0.03]), and data[0][1]=np.array([1,0,0,1,0,-1]).
- time_bins : numpy array (N,), dtype=np.ndarray
For each trial contains times at which latent trajectory was recorded. N is the number of trials, and for each trial time is represented as 1D array of floats.
- x : numpy array (N,), dtype = np.ndarray
Latent trajectories for each trial, N is the number of trials. Each entry is 1D array of floats.
- metadata : dictionary
- A dictionary with two entries:
- last_event_is_spike : bool
Equals to the input parameter with the same name
- absorption_event : list (N,)
List of strings for each trial with the following entries: ‘absorbed’, if the trial terminated due to trajectory absorption, or ‘observation_ended’ if the trial terminated due to time out in an arbitrary latent state.
-
score(data, metadata=None, peq=None, rho0=None, D=None, fr=None)¶ Evaluate negative log-likelihood for a given data and model
Parameters: - data : numpy array (N,2), dtype=np.ndarray.
Spike data packed as numpy array of the size (N,2), where each elements is a 1D array. N is the number of trials, and for each trial the first column contains inter spike intervals (ISIs) in seconds for all neurons, and the second column contains the corresponding neuronal IDs (trial termination, if recorded, is indicated with -1). data[i][0] - 1D array, a sequence of ISIs of all neurons for the trial i. The last entry can be time interval between the last spike and trial termination time. data[i][1] - 1D array, neuronal IDs of type int64 for the trial i. The last entry is -1 if the trial termination time is recorded. Example: neuron 0 spiked at times 0.12, 0.15, 0.25, and neuron 1 spiked at times 0.05, 0.2. Trial 0 started at t=0 and ended at t=0.28. In this case data[0][0]=np.array([0.05,0.07,0.03,0.05,0.05,0.03]), and data[0][1]=np.array([1,0,0,1,0,-1]).
- metadata : dictionary
- Metadata dictionary that supports the following options:
- last_event_is_spike : bool or list/array of bools
If true, trial termination time will be ignored (even if recorded). Otherwise, trial termination time will be used. The default is False. Can be specified for all trials, or for each trial separately.
- absorption_event : bool or list/array of bools
If true, absorption operator will be applied in the end of the loglikelihood chain. The default is True. Can be specified for all trials, or for each trial separately.
The default is None.
- peq : numpy array, dtype=float
The equilibrium probability density evaluated on SEM grid. The default is self.peq_
- rho0 : numpy array, dtype=float
Scaled initial probaiblity distribution, normalized by sqrt(peq): rho0=p0/np.sqrt(peq). The default is self.p0_/np.sqrt(peq), if self.p0_ is not None, otherwise np.sqrt(peq).
- D : float
Noise intensity. The default is self.D_
- fr : numpy array, (N,num_neuron), dtype=float
2D array that contains firing rate functions for each neuron evaluated on SEM grid. The default is self.fr_
Returns: - likelihood : float
Negative loglikelihood of a data given a model
-
transform_spikes_to_isi(spikes, time_epoch, last_event_is_spike)¶ Convert spike times to data array, which is a suitable format for optimization.
Parameters: - spikes : numpy array (num_neuron,N), dtype=np.ndarray
A sequence of spike times for each neuron on each trial. Each entry is 1D array of floats.
- time_epoch : list of tuples
List of N tuples, where N is the number of trials. Each tuple consists of the trial’s start time and end time in seconds. Note that the end time should be an actual end time, but not the timeout in the case of last_event_is_spike is True.
- last_event_is_spike : bool
If true, trial termination time will not be recorded. Otherwise, trial termination time will be recorded.
Returns: - data : numpy array (N,2),dtype=np.ndarray.
Spike data packed as numpy array of the size (N,2), where each elements is a 1D array of floats. N is the number of trials, and for each trial the first column contains the interspike intervals (ISIs), and the second column contains the corresponding neuronal indices.
PDESolve class¶
-
class
PDESolve(xbegin=-1.0, xend=1.0, method={'gridsize': {'Ne': 256, 'Np': 8}, 'name': 'SEM'}, BoundCond={'leftB': 'Neumann', 'rightB': 'Neumann'}, grid_mode_calc='newton', BC_method='projection', int_mode='full')¶ Numerical solution of Stourm-Liouville problem
Parameters: - xbegin : float
The left boundary of the latent state. The default is -1.
- xend : float
The right boundary of the latent state. The default is 1.
- method : dictionary
- A dictionary that contains 2 keys:
- name : string
Specifies the method for the numerical solution of EV problem, can be either ‘FD’ or ‘SEM’ (forward differences or spectral elements method).
- gridsize : dictionary
Specifies number of grid size points N for ‘FD’ method, or Np and Ne for ‘SEM’ method (Ne is the number of elements, Np is the number of grid points in each element).
The default is {‘name’: ‘SEM’, ‘gridsize’: {‘Np’: 8, ‘Ne’: 256}}.
- BoundCond : dictionary
A dictionary that specifies boundary conditions (Dirichlet, Neumann or Robin). The default is {‘leftB’: ‘Neumann’, ‘rightB’: ‘Neumann’}
- grid_mode_calc : str
Specify how to calculate SEM grid collocation points. Availiable options: ‘built_in’: using numpy.polynomial module ‘newton’: using Newton’s method to calculate zeros of Legendre polinomial for the GLL grid The default is ‘newton’.
- BC_method : str
Specify the method of boundary condition handling when transforming the EV problem into linear system of equations. Availiable options: ‘projection’: use projection operator. ‘bound_subst’: use boundary condition substitution into the first and the last equations of the associated linear system. The default is ‘projection’
- int_mode : str
Specify the integration mode. Availiable options:
‘full’ - use full integration matrix. ‘sparse’ - use sparse integration matrix with bias.
The default is ‘full’. See Supplementary Materials 2.3 from M. Genkin, T. A. Engel, Nat Mach Intell 2, 674–683 (2020) for details.
Attributes: - AD_d : numpy array (N,N), dtype=float
Integration matrix (only for SEM method).
- dmat_d : numpy array (N,N), dtype=float
Differentiation matrix (only for SEM method).
- dx : float
Uniform grid step size (only for FD method).
- N : int
A total number of the grid points.
- Np : int
Degree of each element (number of grid points in each element, only for SEM method).
- Ne : int
A number of SEM elements (only for SEM method).
- w_d : numpy array (N,), dtype=float
Weights of the nodes (on the global grid).
- x_d: numpy array (N,), dtype=float
Domain grid points.
Methods
Integrate(f[, result])Takes an indefinite integral of a function f using integration matrix (and a cumulative correction for ‘sparse’ int_mode). set_BoundCond(BoundCond)Set new boundary conditions for the Stourm-Liouville probelem solve_EV([peq, D, q, w, mode, fr, Nv])Solve the Sturm-Liouville eigenvalue-eigenvector problem. -
Integrate(f, result=None)¶ Takes an indefinite integral of a function f using integration matrix (and a cumulative correction for ‘sparse’ int_mode).
Parameters: - f : numpy array, dtype=float
Function values evaluated on the grid
- result : numpy array, dtype=float
A container for the results (to avoid additional allocation). If not provided, will return a result. The default is None.
Returns: - numpy array
If the result is not provided at the input, it will be returned.
-
set_BoundCond(BoundCond)¶ Set new boundary conditions for the Stourm-Liouville probelem
Parameters: - BoundCond : dictionary
Specify boundary conditions keys : ‘leftB’, ‘rightB’, (optionally: ‘leftBCoeff’, ‘rightBCoeff’) values : ‘Dirichlet’ ‘Neumann’ or ‘Robin’. If ‘Robin’, addionally specify coefficients as a dictionary with two keys: [c1,c2], consistent with the boundary condition of the form: c1*y(B)+c2*y’(B)=0 Example: {‘leftB’:’Robin’,’leftBCoeff’:{‘c1’=1, ‘c2’=2}, ‘rightB’:’Robin’,’rightBCoeff’:{‘c1’=3, ‘c2’=4}} The default is {‘leftB’: ‘Neumann’, ‘rightB’: ‘Neumann, ‘leftBCoeff’: {‘c1’: 1, ‘c2’: 2} }
-
solve_EV(peq=None, D=1, q=None, w=None, mode='hdark', fr=None, Nv=64)¶ Solve the Sturm-Liouville eigenvalue-eigenvector problem. The problem can be specified either by peq, q and w functions or by the precalculated stiffmat and massmat
Parameters: - peq : numpy array, dtype=float
Equilibirum probabilioty distribution that determines potential Phi(x), see Suplementary Note 1.1. 1D array.
- D : float
Noise magnitude.
- q : numpy array, dtype=float
A function q(x) in the S-L problem. The default value is None, in this case q(x)=0
- w : numpy array, dtype=float
A function w(x) in the S-L problem (non-negative). The default is None, in this case w(x)=1
- mode : str
- Specify mode. Availiable modes:
‘normal’: solve Sturm-Liouville problem, ignore D and fr. ‘h0’: solve for eigenvalues and vectors of FP operator H0. ‘hdark’: solve for eigenvalues and vector of FP and H operator
The default is ‘hdark’.
- fr : numpy array
The firing rate function (required for ‘hdark’ mode). This firing rate function is an elementwise sum of the firing rate functions of all the neuronal responses. The default is None.
- Nv : int
A number of eigenvectors/eigenvalues returned. The default is 64.
Returns: - lQ : numpy array (Nv,), dtype=float
The least Nv eigenvalues for the eigenvalue problem of H0 operator.
- QxOrig : numpy array (Nv,Nv), dtype=float
The corresponding scaled eigenvectors
- Qx : numpy array (Nv,Nv), dtype=float
The eigenvectors of EV problem of H0 operator (only for ‘h0’ and ‘hdark’ modes).
- lQd: numpy array (Nv,), dtype=float
The eigenvalues of H operator (only for ‘hdark’ mode).
- Qd: numpy array (Nv,Nv), dtype=float
The corresponding eigenvectors in H0 basis (only for ‘hdark’ mode).
Utility functions¶
FC_stationary module¶
Below are the complimentary functions for Model selection based on feature complexity analysis for stationary data. See Genkin, Engel, Nat. Mach. Intel. (2020) paper for details. This module is optional and should be imported separately: from neuralflow.utilities import FC_stationary.
-
FeatureComplexity_st(peqs, grid_params, start_index=0, stop_index=-1)¶ Calculate Feature complexities for a given array of peqs for stationary data.
Parameters: - peqs : numpy array
2D array of peqs of size (N1,N2), where N1 - number of grid points, N2 - number of peqs.
- grid_params : dictionary
Contains two entries: ‘w’: SEM weights and ‘dmat’: SEM differentiation matrix. Can be extracted from Energymodel variable: grid_params = {‘w’: EnergyModel.w_d_, ‘dmat’: EnergyModel.dmat_d_}
- start_index : int
Starting index that determines the number of points at the left boundary to be skipped for FC calculation. The default is 0.
- stop_index : int
Stop index that determines the number of points at the right boundary to be skipped for FC calculation. The default is -1.
Returns: - FCs: numpy array
1D array of shape (N2,) that contains FC for each of the provided peqs
-
FeatureConsistencyAnalysis_st(data1, data2, grid_params, KL_thres, FC_radius, FC_final, FC_stride)¶ Perform feature consistency analysis on two fitting results obtained from different data samples for stationary data. The algorithm works as follows:
- Create a shared feature complexity axis.
- For each entry in shared FC, select all models from data1 and data2 that differ from the current FC by less than FC_radius.
- For all selected models, calculate each of the pairwise KL divergences.
- Select and save minimal KL divergence and the corresponding indices in the original data1/data2 arrays.
Parameters: - data1 : dictionary
Dictionary with two entries: ‘peqs’ and ‘FCs’ for fitting results on data sample 1. The first entry contains 2D array of peqs, and the second - 1D array of the corresponding feature complexities.
- data2 : dictionary
Dictionary with two entries: ‘peqs’ and ‘FCs’ for fitting results on data sample 2. The first entry contains 2D array of peqs, and the second - 1D array of the corresponding feature complexities.
- grid_params : dictionary
Contains two entries: ‘w’: SEM weights and ‘dmat’: SEM differentiation matrix. Can be extracted from Energymodel variable: grid_params = {‘w’: EnergyModel..w_d_, ‘dmat’: EnergyModel..dmat_d_}
- KL_thres : float
Threshold KL divergence for determining optimal feature complexity.
- FC_radius : float
Feature complexity radius that determines maximum slack in features complexities of two models.
- FC_final : float
Maximum feature complexity on shared feature complexity axis
- FC_stride : float
Feature complexity resolution on shared feature complexity axis
Returns: - FC_shared : numpy array, dtype=float
1D array of shared feature complexities (shared feature complexity axis)
- KL : numpy array, dtype=float
1D array of KL divergences between the two models.
- FC_opt_ind : int
Index of optimal KL divergence in FC_shared array
- ind1_shared : numpy array, dtype=int
Indices of peqs/FCs in data1 array that correspond to each entry in FC_shared.
- ind2_shared : numpy array, dtype=int
Indices of peqs/FCs in data2 array that correspond to each entry in FC_shared.
-
KL_divergence_st(peq1, peq2, weights, schema='pairwise')¶ Calculate KL divergence between two batches of distributions peq1 and peq2 for stationary data. KL = integral (p1*log(p1/p2))
Parameters: - peq1: numpy array
2D array of the first batch of distributions (each column contains a distribution)
- peq2: numpy array
2D array of the second batch of distributions (each column contains a distribution)
- weights: numpy array
1D array of SEM weights
- schema: ENUM(‘pairwise’,’all’)
‘pairwise’ mode calculates KL between each pair (peq1[:,0] peq2[:,0]), (peq1[:,1] peq2[:,1]), and so on ‘all’ mode calculates KL between all possible pairs from peq1 and peq2, e.g.
if peq1 contains 3 models and peq2 contains 4 models, 12 KL divergences will be calculated and packed in a 3x4 matrix.
Returns: - numpy array
Array with KL divergences
FC_nonstationary module¶
Below are the complimentary functions for Model selection based on feature complexity analysis for non-stationary data. See Genkin, Hughes, Engel, arxiv 2020 paper for details. This module is optional and should be imported separately: from neuralflow.utilities import FC_nonstationary.
-
FeatureComplexities(results, em, iterations)¶ Calculate feature complexities of the model at specified iterations, and also eigenvalues and eigenvectors of the H0 operator.
Parameters: - results : dictionary
Dictionary with the results (fitted models)
- em : EnergyModel
An instance of the EnergyModel class.
- iterations : numpy array
Iteration numbers on which feature complexities/EVs/EVVs should be calculated.
Returns: - FCs_array : numpy array
A 1D array of feature complexities.
- lQ_array : numpy array
A 2D array of H0 eigenvalues.
- Qx_array : numpy array
A 3D array of H0 eigenvectors.
-
FeatureComplexity(em, peq=None, p0=None, D=None)¶ Calculate feature complexity for a single model specified by (peq,D,p0).
Parameters: - em : EnergyModel
An instance of the EnergyModel class.
- peq : numpy array
Equilibirum probability distribution.
- p0 : numpy array
Distribution of the initial latent states.
- D : float
Noise magnitude
Returns: - FC : float
Feature complexity.
-
JS_divergence(p1, p2, weights, mode='normalized')¶ Calculate JS divergence between two distributions
Parameters: - p1 : numpy array
The first distribution, 1D array
- p2 : numpy array
The second distribution, 1D array
- weights: numpy array
1D array of SEM weights
- mode : ENUM(‘normalized’,’unnormalized’)
If normalized, both distribution are assumed to be normalized (integrate to 1). Otherwise, boundary term will be accounted for.
Returns: - JS : float
JS divergence
-
JS_divergence_tdp(peq1, D1, p01, peq2, D2, p02, weights, lQ1, Qx1, lQ2, Qx2, terminal_time=0.5, number_of_samples=5)¶ Calculate JS divergence between two time-dependent probability distributions that comes from two different non-stationary Langevin dynamics.
Parameters: - peq1 : numpy array
1D array of peq values (that defines Langevin potential) for the first dynamics.
- D1 : float
Noise magnitude for the first dynamics.
- p01 : numpy array
1D array of p0 distribution for the first dynamics.
- peq2 : numpy array
1D array of peq values (that defines Langevin potential) for the second dynamics.
- D2 : float
Noise magnitude for the second dynamics.
- p02 : numpy array
1D array of p0 distribution for the second dynamics.
- weights : numpy array
1D array of SEM weights
- lQ1 : numpy array
1D array of Eigenvalues of H0 operator for the first dynamics.
- Qx1 : numpy array
2D array of Eigenfunctions of H0 operator for the first dynamics.
- lQ2 : numpy array
1D array of Eigenvalues of H0 operator for the second dynamics.
- Qx2 : numpy array
2D array of Eigenfunctions of H0 operator for the second dynamics.
- terminal_time : float, optional
Terminal time that defines upper limit of the time integral. The default is 0.5.
- number_of_samples : int, optional
Number of time steps for numerical approxination of the time integral. The default is 5.
Returns: - out : float
JS divergence between the two time-dependent distributions.