Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions Ex01_testPCA.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
% Principal component analysis
% Wenjing Ma ([email protected])
%
% BMI500 Course
% Lecture: An Introduction to Blind Source Separation and Independent Component Analysis
Expand Down Expand Up @@ -36,3 +37,67 @@
N = size(x, 1); % The number of channels
T = size(x, 2); % The number of samples per channel

%PlotECG(x, 4, 'b', fs, 'Raw data channels');

% remove mean
x_demeaned = x - mean(x, 2) * ones(1, size(x, 2));

% covariance matrix of the input
Cx = cov(x_demeaned');

% eigen value decomposition
[V, D] = eig(Cx, "vector"); % in vector form, eigenvalues in reversed form

figure
subplot(121)
plot(D(end:-1:1));
grid
xlabel('Index');
ylabel('Eigenvalue');
title('Eigenvalues in linear scale');
subplot(122)
plot(10*log10(D(end:-1:1)/D(end))); % log-normalize, see the decimal
grid
xlabel('Index');
ylabel('Eigenvalue ratios in dB');
title('Normalized eigenvalues in log scale');

% use eigenvalues to observe the energy (-> subset of eigenvalues)

% check variance
x_var = var(x_demeaned, [], 2);
x_var2 = diag(Cx); % the variance

% Decorrelate the channels
y = V' * x_demeaned;
Cy = cov(y');
y_var = diag(Cy);

% check total engegy match
x_total_energy = sum(x_var);
Cx_trace = trace(Cx);
eigenvalue_sum = sum(D);
Cy_trace = trace(Cy);

% did not scale, just rotating, so the variances do not change

% partial energy
x_partial_energy = 100.0 * cumsum(D(end:-1:1))./x_total_energy;

% set a cut off
th = 99.9;
N_eigs_to_keep = find(x_partial_energy <= th, 1, 'last');

% find a compressed version of x
x_compressed = V(:, N-N_eigs_to_keep+1:N) * y(N-N_eigs_to_keep+1:N, :);
% eig(cov(x_compressed'))

t = (0: T-1)/fs;
for ch = 1:N
figure
hold on
plot(t, x(ch, :));
plot(t, x_compressed(ch, :));
legend(['channel' num2str(ch)], 'compressed');
grid
end
8 changes: 8 additions & 0 deletions Ex02_testEigenAnalysisPowerMethod.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
% The power method for eigenvalue decomposition
% Wenjing Ma ([email protected])
%
% BMI500 Course
% Lecture: An Introduction to Blind Source Separation and Independent Component Analysis
Expand All @@ -24,3 +25,10 @@
% Cx = x * x';
Cx = cov(x');

% HW, power method to calculate eigenvalue decomposition
% eigs function, for high-dimensional data
% the algorithm is in the slides (power method for EVD)




38 changes: 37 additions & 1 deletion Ex03_testICAmethods.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
clear
close all

example = 3;
example = 1;
switch example
case 1 % A sample EEG from the OSET package
load EEGdata textdata data % Load a sample EEG signal
Expand Down Expand Up @@ -46,3 +46,39 @@
N = size(x, 1); % The number of channels
T = size(x, 2); % The number of samples per channel

% test-ICA procedure, fastica, JADE, SOBI
%PlotECG(x, 4, 'b', fs, 'Raw data channels');

% fastica
approach = "symm"; % defl: extract component one by one
g = "tanh";
lastEigfastica = N; % PCA stage
numOfIC = N; % ICA stage
interactivePCA = 'off';
[s_fastica, A_fastica, W_fastica] = fastica(x, 'approach', approach, ...
'g', g, 'lastEig', lastEigfastica, 'numOfIC', numOfIC, ...
'interactivePCA', interactivePCA);

% JADE
lastEigJADE = N;
W_JADE = jadeR(x, lastEigJADE);
s_jade = W_JADE * x;

% SOBI
lastEigSOBI = N;
num_cov_matrices = 100;
[W_SOBI, s_sobi] = sobi(x, lastEigSOBI, num_cov_matrices);

% Plot
PlotECG(s_fastica, 4, 'r', fs, 'fastica');
PlotECG(s_jade, 4, 'k', fs, 'JADE');
PlotECG(s_sobi, 4, 'b', fs, 'SOBI');

% need domain knowledge to tell the channel and whether to trust the result







4 changes: 3 additions & 1 deletion Ex04_testEOGArtifactRemoval.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
% Removing EOG artifacts from EEG signals
%
% Wenjing Ma ([email protected])
% BMI500 Course
% Lecture: An Introduction to Blind Source Separation and Independent Component Analysis
% By: R. Sameni
Expand Down Expand Up @@ -32,3 +32,5 @@
T = size(x, 2); % The number of samples per channel
t = (0 : T - 1)/fs;



2 changes: 1 addition & 1 deletion Ex05_testFetalECGExtraction.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
% Extracting fetal ECG signals using various ICA algorithms
%
% Wenjing Ma ([email protected])
% BMI500 Course
% Lecture: An Introduction to Blind Source Separation and Independent Component Analysis
% By: R. Sameni
Expand Down