Skip to content

Commit 3c7163f

Browse files
committed
first commit
1 parent 506160c commit 3c7163f

12 files changed

+689
-2
lines changed

.gitattributes

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
*.mlx -crlf -diff -merge
2+
*.mat -crlf -diff -merge
3+
*.fig -crlf -diff -merge
4+
*.p -crlf -diff -merge
5+
*.slx -crlf -diff -merge
6+
*.mdl -crlf -diff -merge
7+
8+
*.mdlp -crlf -diff -merge
9+
*.slxp -crlf -diff -merge
10+
*.sldd -crlf -diff -merge
11+
*.mexa64 -crlf -diff -merge
12+
*.mexw64 -crlf -diff -merge
13+
*.mexmaci64 -crlf -diff -merge
14+
*.xlsx -crlf -diff -merge
15+
*.docx -crlf -diff -merge
16+
*.pdf -crlf -diff -merge
17+
*.jpg -crlf -diff -merge
18+
*.png -crlf -diff -merge

.gitignore

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# External dependencies
2+
external/
3+
4+
##---------------------------------------------------
5+
## Remove autosaves generated by the Matlab editor
6+
## We have git for backups!
7+
##---------------------------------------------------
8+
9+
# psb log files
10+
*.o*
11+
*.o*
12+
13+
# Atom editor files
14+
.idea*
15+
16+
17+
# Zip files
18+
*.zip
19+
20+
21+
# Windows default autosave extension
22+
*.asv
23+
24+
# OSX / *nix default autosave extension
25+
*.m~
26+
27+
# Compiled MEX binaries (all platforms)
28+
*.mex*
29+
30+
# Simulink Code Generation
31+
slprj/
32+
33+
# Session info
34+
octave-workspace

LICENSE.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
This software is Copyright © 2020 The University of Southern California. All Rights Reserved.
2+
3+
Permission to use, copy, modify, and distribute this software and its documentation for educational, research
4+
and non-profit purposes, without fee, and without a written agreement is hereby granted, provided that the
5+
above copyright notice, this paragraph and the following three paragraphs appear in all copies.
6+
7+
Permission to make commercial use of this software may be obtained by contacting:
8+
USC Stevens Center for Innovation
9+
University of Southern California
10+
1150 S. Olive Street, Suite 2300
11+
Los Angeles, CA 90115, USA
12+
13+
This software program and documentation are copyrighted by The University of Southern California. The software
14+
program and documentation are supplied "as is", without any accompanying services from USC. USC does not warrant
15+
that the operation of the program will be uninterrupted or error-free. The end-user understands that the program
16+
was developed for research purposes and is advised not to rely exclusively on the program for any reason.
17+
18+
IN NO EVENT SHALL THE UNIVERSITY OF SOUTHERN CALIFORNIA BE LIABLE TO ANY PARTY FOR
19+
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
20+
PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
21+
UNIVERSITY OF SOUTHERN CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
22+
DAMAGE. THE UNIVERSITY OF SOUTHERN CALIFORNIA SPECIFICALLY DISCLAIMS ANY
23+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED
25+
HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF SOUTHERN CALIFORNIA HAS NO
26+
OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
27+
MODIFICATIONS

README.md

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,37 @@
1-
# Preprint
2-
Omid G. Sani, Bijan Pesaran, Maryam M. Shanechi (2019). _Modeling behaviorally relevant neural dynamics enabled by preferential subspace identification (PSID)_ bioRxiv 808154, doi: https://doi.org/10.1101/808154
1+
# PSID: Preferential subspace identification
2+
3+
Given signals y_t (e.g. neural signals) and z_t (e.g behavior), PSID learns a dynamic model for y_t while prioritizing the dynamics that are relevant to z_t.
4+
5+
For the derivation and results in real neural data see:
6+
7+
Omid G. Sani, Bijan Pesaran, Maryam M. Shanechi (2019). *Modeling behaviorally relevant neural dynamics using Preferential Subspace IDentification (PSID)* bioRxiv 808154, doi: 10.1101/808154, https://doi.org/10.1101/808154
8+
9+
10+
# Usage guide
11+
## Initialization
12+
Add the source directory and its subdirectories to the path. You can run init.m to do this.
13+
14+
## Main learning function
15+
The main function for the MATLAB implementation is [source/PSID.m](source/PSID.m). A complete usage guide is available in the function. The following shows an example case:
16+
```
17+
idSys = PSID(y, z, nx, n1, i);
18+
```
19+
Inputs:
20+
- y and z are time x dimension matrices with neural (e.g. LFP signal powers or spike counts) and behavioral data (e.g. joint angles, hand position, etc), respectively.
21+
- nx is the total number of latent states to be identified.
22+
- n1 is the number of states that are going to be dedicated to behaviorally relevant dynamics.
23+
- i is the subspace horizon used for modeling.
24+
25+
Output:
26+
- idSys: a structure containing all model parameters (A, Cy, Cz, etc). For a full list see the code.
27+
28+
# Example script
29+
Example simulated data and the script for running PSID on the data is provided in
30+
[example/example.m](example/example.m)
31+
This script perform PSID model identification and visualizes the learned eigenvalues similar to in Supplementary Fig 2.
32+
33+
# Licence
34+
Copyright (c) 2020 University of Southern California
35+
See full notice in [LICENSE.md](LICENSE.md)
36+
Omid G. Sani and Maryam M. Shanechi
37+
Shanechi Lab, University of Southern California

example/example.m

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2+
% Copyright (c) 2020 University of Southern California
3+
% See full notice in LICENSE.md
4+
% Omid G. Sani and Maryam M. Shanechi
5+
% Shanechi Lab, University of Southern California
6+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7+
8+
%% Add PSID to the path (or call init.m)
9+
addpath(genpath('../source'));
10+
11+
%% Load data
12+
data = load('./sample_data.mat');
13+
% This data is generated from a system (shown in Supplementary Fig. 2) with
14+
% (a) 2 behaviorally relevant latent states,
15+
% (b) 2 behaviorally irrelevant latent states, and
16+
% (c) 2 states that drive behavior but are not represented in neural activity
17+
18+
% Separate data into training and test data:
19+
trainInds = (1:round(0.5*size(data.y, 1)))';
20+
testInds = ((1+trainInds(end)):size(data.y, 1))';
21+
yTrain = data.y(trainInds, :);
22+
yTest = data.y(testInds, :);
23+
zTrain = data.z(trainInds, :);
24+
zTest = data.z(testInds, :);
25+
%% (Example 1) PSID can be used to dissociate and extract only the
26+
% behaviorally relevant latent states (with nx = n1 = 2)
27+
idSys1 = PSID(yTrain', zTrain', 2, 2, 10);
28+
29+
% Predict behavior using the learned model
30+
[zTestPred1, xTestPred1] = PSIDPredict(idSys1, yTest);
31+
32+
% Compute CC of decoding
33+
nz = size(zTest, 2);
34+
CC = arrayfun( @(i)( corr(zTestPred1(:, i), zTest(:, i)) ), 1:nz );
35+
36+
% Predict behavior using the true model for comparison
37+
[zTestPredIdeal, xTestIdeal] = PSIDPredict(data.trueSys, yTest);
38+
CCIdeal = arrayfun( @(i)( corr(zTestPredIdeal(:, i), zTest(:, i)) ), 1:nz ); % Compute CC of ideal decoding
39+
40+
fprintf('PSID decoding CC = %.3g, ideal decoding CC using true model = %.3g\n', mean(CC), mean(CCIdeal));
41+
%% (Example 2) Optionally, PSID can additionally also learn the
42+
% behaviorally irrelevant latent states (with nx = 4, n1 = 2)
43+
idSys2 = PSID(yTrain', zTrain', 4, 2, 10);
44+
45+
%% (Example 3) PSID can be used if data is available in discontinious segments (e.g. different trials)
46+
% In this case, y and z data segments must be provided as elements of a cell array
47+
% Here, for example assume that trials start at every 1000 samples.
48+
% And each each trial has a random length of 500 to 900 samples
49+
trialStartInds = (1:1000:(size(data.y, 1)-1000))';
50+
trialDurRange = [900 990];
51+
trialDur = trialDurRange(1)-1 + randi(diff(trialDurRange)+1, size(trialStartInds));
52+
trialInds = arrayfun( @(ti)( (trialStartInds(ti)-1+(1:trialDur(ti)))' ), (1:numel(trialStartInds))', 'UniformOutput', false );
53+
yTrials = arrayfun( @(tInds)( data.y(tInds{1}, :)' ), trialInds, 'UniformOutput', false );
54+
zTrials = arrayfun( @(tInds)( data.z(tInds{1}, :)' ), trialInds, 'UniformOutput', false );
55+
56+
% Separate data into training and test data:
57+
trainInds = (1:round(0.5*numel(yTrials)))';
58+
testInds = ((1+trainInds(end)):numel(yTrials))';
59+
yTrain = yTrials(trainInds, :);
60+
yTest = yTrials(testInds, :);
61+
zTrain = zTrials(trainInds, :);
62+
zTest = zTrials(testInds, :);
63+
64+
idSys3 = PSID(yTrain, zTrain, 2, 2, 10);
65+
66+
yTestT = arrayfun( @(yt)( yt{1}.' ), yTest, 'UniformOutput', false);
67+
% yTestCat = cell2mat( yTestT ); % Data can also be concatenated for
68+
% decoding if taking last state in a previous trial as the
69+
% initial state in the next trial makes sense
70+
[zTestPred1, xTestPred1Cell] = PSIDPredict(idSys3, yTestT);
71+
72+
zTestPred1Cat = cell2mat( zTestPred1 );
73+
% zTestPred1Cat = zTestPred1;
74+
75+
zTestT = arrayfun( @(zt)( zt{1}.' ), zTest, 'UniformOutput', false);
76+
zTestCat = cell2mat( zTestT );
77+
CCTrialBased = arrayfun( @(i)( corr(zTestPred1Cat(:, i), zTestCat(:, i)) ), 1:nz );
78+
79+
fprintf('Trial-based PSID decoding CC = %.3g, ideal decoding CC using true model = %.3g\n', mean(CCTrialBased), mean(CCIdeal));
80+
81+
%%
82+
% Plot the true and identified eigenvalues
83+
84+
% (Example 1) Eigenvalues when only learning behaviorally relevant states
85+
idEigs1 = eig(idSys1.A);
86+
87+
% (Example 2) Additional eigenvalues when also learning behaviorally irrelevant states
88+
% The identified model is already in form of Eq. 4, with behaviorally irrelevant states
89+
% coming as the last 2 dimensions of the states in the identified model
90+
idEigs2 = eig(idSys2.A(3:4, 3:4));
91+
92+
relevantDims = data.trueSys.zDims; % Dimensions that drive both behavior and neural activity
93+
irrelevantDims = find(~ismember(1:size(data.trueSys.a,1), data.trueSys.zDims)); % Dimensions that only drive the neural activity
94+
trueEigsRelevant = eig(data.trueSys.a(relevantDims, relevantDims));
95+
trueEigsIrrelevant = eig(data.trueSys.a(irrelevantDims, irrelevantDims));
96+
nonEncodedEigs = eig(data.epsSys.a); % Eigenvalues for states that only drive behavior
97+
98+
figure; zplane([], []); ax = gca; hold(ax, 'on');
99+
h1 = scatter(ax, real(nonEncodedEigs), imag(nonEncodedEigs), 'o', 'MarkerEdgeColor', 'b', 'DisplayName', 'Not encoded in neural signals');
100+
h2 = scatter(ax, real(trueEigsIrrelevant), imag(trueEigsIrrelevant), 'o', 'MarkerEdgeColor', 'r', 'DisplayName', 'Behaviorally irrelevant');
101+
h3 = scatter(ax, real(trueEigsRelevant), imag(trueEigsRelevant), 'o', 'MarkerEdgeColor', 'g', 'DisplayName', 'Behaviorally relevant');
102+
h4 = scatter(ax, real(idEigs1), imag(idEigs1), 'x', 'MarkerEdgeColor', [0 0.5 0], 'DisplayName', 'PSID Identified (stage 1)');
103+
h5 = scatter(ax, real(idEigs2), imag(idEigs2), 'x', 'MarkerEdgeColor', [0.5 0 0], 'DisplayName', '(optional) PSID Identified (stage 2)');
104+
legend(ax, [h1, h2, h3, h4, h5], 'Location', 'EO');

example/sample_data.mat

1.42 MB
Binary file not shown.

init.m

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2+
% Copyright (c) 2020 University of Southern California
3+
% See full notice in LICENSE.md
4+
% Omid G. Sani and Maryam M. Shanechi
5+
% Shanechi Lab, University of Southern California
6+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7+
8+
% Add functions to the path
9+
addpath(genpath('./source'));

0 commit comments

Comments
 (0)