Skip to content

Commit

Permalink
Added support for direct specification of the means and covariance ma…
Browse files Browse the repository at this point in the history
…trices.

Small bugfixes. Added citation textbox for the SSA Toolbox.
  • Loading branch information
Jan Saputra Mueller committed Apr 12, 2013
1 parent 66f4b47 commit d40a7a1
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 34 deletions.
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
version=1.3
version=1.4
73 changes: 58 additions & 15 deletions matlab/ssa.m
Expand Up @@ -9,6 +9,9 @@
% * D x n matrix with data in the columns
% * cell array where each X{i} is a D x n_i matrix
% and n_i the number of samples in epoch i
% * or an empty matrix, i.e. X = []. In this case, the
% means and covariances of the epochs have to be specified
% directly (see optional parameters 'means' and 'covs').
% d Dimensionality of stationary subspace
% <options> List of key-value pairs to set the following options.
% reps Number of restarts (the one with the lowest
Expand All @@ -28,6 +31,11 @@
% Default: false
% ignore_determinacy Set this to true, if the determinacy bounds should
% be ignored. Default: false
% means If X = [], this parameter has to be a D x N matrix,
% containing the means of the epochs in the columns.
% covs If X = [], this parameter has to be a cell array
% of length N, where the elements of the array are
% the D x D covariance matrices of the epochs.
%
%
%output
Expand All @@ -44,8 +52,8 @@
% This software is distributed under the BSD license. See COPYING for
% details.

% Copyright (c) 2010, Jan Saputra Müller, Paul von Bünau, Frank C. Meinecke,
% Franz J. Kiraly and Klaus-Robert Müller.
% Copyright (c) 2010, Jan Saputra Mueller, Paul von Buenau, Frank C. Meinecke,
% Franz J. Kiraly and Klaus-Robert Mueller.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without modification,
Expand All @@ -58,7 +66,7 @@
% list of conditions and the following disclaimer in the documentation and/or other
% materials provided with the distribution.
%
% * Neither the name of the Berlin Institute of Technology (Technische Universität
% * Neither the name of the Berlin Institute of Technology (Technische Universit??t
% Berlin) nor the names of its contributors may be used to endorse or promote
% products derived from this software without specific prior written permission.
%
Expand Down Expand Up @@ -86,7 +94,9 @@
'matrix_library', 'colt', ...
'random_seed', 0, ...
'quiet', false, ...
'ignore_determinacy', false ...
'ignore_determinacy', false, ...
'means', [], ...
'covs', [] ...
);

% instantiate classes
Expand Down Expand Up @@ -147,16 +157,47 @@
ssamain.data.setCustomEpochDefinition(epdef, epochs, min_ep_size, fakefile);
ssamain.data.setEpochType(ssamain.data.EPOCHS_CUSTOM);
else
% epochize equally
if ~opt.quiet, fprintf('No custom epochization found. Using equally sized epochs.\n'); end
Xdm = ssatoolbox.SSAMatrix(X);
ssamain.data.setTimeSeries(Xdm, []);
if opt.equal_epochs == 0
% use heuristic
ssamain.data.setEpochType(ssamain.data.EPOCHS_EQUALLY_HEURISTIC);
if isempty(X)
% means and covs are specified directly
fprintf('X is empty, means and covariances are specified directly...\n');
if isempty(opt.means) && opt.use_mean
error('Error: means should be used but variable means is not set.');
end
if isempty(opt.covs) && opt.use_covariance
error('Error: covariances should be used but variable covs is not set.');
end
if opt.use_mean && opt.use_covariance && length(opt.covs) ~= size(opt.means, 2)
error('Error: number of epochs in means and covs have to be the same.');
end
ssamain.data.setEpochType(ssamain.data.EPOCHS_SPECIFIED_MOMENTS);
if opt.use_covariance
epochs = length(opt.covs);
ssamain.data.customS = javaArray('ssatoolbox.SSAMatrix', epochs);
end
if opt.use_mean
epochs = length(opt.means);
ssamain.data.customMu = javaArray('ssatoolbox.SSAMatrix', epochs);
end
for i=1:epochs
if opt.use_covariance
ssamain.data.customS(i) = ssatoolbox.SSAMatrix(opt.covs{i});
end
if opt.use_mean
ssamain.data.customMu(i) = ssatoolbox.SSAMatrix(opt.means(:,i));
end
end
else
ssamain.data.setNumberOfEqualSizeEpochs(opt.equal_epochs);
ssamain.data.setEpochType(ssamain.data.EPOCHS_EQUALLY);
% epochize equally
if ~opt.quiet, fprintf('No custom epochization found. Using equally sized epochs.\n'); end
Xdm = ssatoolbox.SSAMatrix(X);
ssamain.data.setTimeSeries(Xdm, []);
if opt.equal_epochs == 0
% use heuristic
ssamain.data.setEpochType(ssamain.data.EPOCHS_EQUALLY_HEURISTIC);
else
ssamain.data.setNumberOfEqualSizeEpochs(opt.equal_epochs);
ssamain.data.setEpochType(ssamain.data.EPOCHS_EQUALLY);
end
end
end
catch
Expand Down Expand Up @@ -215,8 +256,10 @@
ssa_results.s_src = Ps * Xwoeps;
ssa_results.n_src = Pn * Xwoeps;
else
ssa_results.s_src = Ps * X;
ssa_results.n_src = Pn * X;
if ~isempty(X)
ssa_results.s_src = Ps * X;
ssa_results.n_src = Pn * X;
end
end
parameters = struct;
parameters.input_file = '';
Expand Down
6 changes: 3 additions & 3 deletions src/ssatoolbox/GUI.java
Expand Up @@ -487,7 +487,7 @@ private void initComponents() {
gridBagConstraints.weighty = 1.0;
jPanel2.add(jScrollPane2, gridBagConstraints);

/*

jLabel2.setText("Please cite the following paper for the SSA Toolbox.");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
Expand All @@ -501,7 +501,7 @@ private void initComponents() {
jTextArea2.setColumns(20);
jTextArea2.setFont(new java.awt.Font("Courier New", 0, 13));
jTextArea2.setRows(5);
jTextArea2.setText("@Article{JMLR:SSAToolbox:2009,\n author = {Jan Saputra M{\\\"uller} and\n Paul von B{\\\"u}nau and\n Frank C.~Meinecke and\n Franz J.~Kir\\'{a}ly and \n Klaus-Robert M{\\\"u}ller},\n title = {SSA Toolbox}, \n journal = {Journal of Machine Learning Research (accepted)},\n year = 2009\n}");
jTextArea2.setText("@Article{JMLR:SSAToolbox:2011,\n author = {Jan Saputra M{\\\"uller} and\n Paul von B{\\\"u}nau and\n Frank C.~Meinecke and\n Franz J.~Kir\\'{a}ly and \n Klaus-Robert M{\\\"u}ller},\n title = {The Stationary Subspace Analysis Toolbox}, \n journal = {Journal of Machine Learning Research},\n volume = {12}, \n year = {2011}, \n pages = {3065-3069} \n}");
jScrollPane3.setViewportView(jTextArea2);

gridBagConstraints = new java.awt.GridBagConstraints();
Expand All @@ -511,7 +511,7 @@ private void initComponents() {
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
jPanel2.add(jScrollPane3, gridBagConstraints);
*/


jButton1.setText("Close");
jButton1.addActionListener(new java.awt.event.ActionListener() {
Expand Down
2 changes: 1 addition & 1 deletion src/ssatoolbox/Main.java
Expand Up @@ -407,7 +407,7 @@ public boolean runSSA(boolean sepThread) {
{
gui.setGUIState(GUI.STATE_SSA_RUNNING);
}

if(sepThread)
{
(new Thread() {
Expand Down
40 changes: 26 additions & 14 deletions src/ssatoolbox/SSA.java
Expand Up @@ -119,7 +119,9 @@ else if( (par.isUseMean() && !par.isUseCovariance()) || (!par.isUseMean() && par
public Results optimizeOnce(SSAParameters par, Data data, boolean optNSources, SSAMatrix init)
{
SSAMatrix S[] = new SSAMatrix[data.S.length];
SSAMatrix mu[] = new SSAMatrix[data.mu.length];
SSAMatrix mu[] = null;
if(par.isUseMean())
mu = new SSAMatrix[data.mu.length];

int n = data.getNumberOfDimensions();
int d = optNSources ? (n - par.getNumberOfStationarySources()) : par.getNumberOfStationarySources();
Expand All @@ -140,7 +142,8 @@ public Results optimizeOnce(SSAParameters par, Data data, boolean optNSources, S
for(int i = 0; i < data.S.length; i++)
{
S[i] = B.mmul(data.S[i]).mmuli(B.transpose());
mu[i] = B.mmul(data.mu[i].sub(data.muall));
if(par.isUseMean())
mu[i] = B.mmul(data.mu[i].sub(data.muall));
}

int k; // degrees of freedom of chi^2 distribution
Expand All @@ -159,7 +162,6 @@ else if(par.isUseCovariance())
// use only means
k = S.length*d;
}

// Optimization loop
SSAMatrix grad, gradOld = null;
SSAMatrix alpha, alphaOld = null;
Expand Down Expand Up @@ -299,8 +301,11 @@ public Results optimize(SSAParameters par, Data data)
}

checkParameters(par, data);

appendToLog("Calculating covariance matrices and means...");

if(data.getEpochType() != data.EPOCHS_SPECIFIED_MOMENTS)
{
appendToLog("Calculating covariance matrices and means...");
}
data.epochize(par.isUseCovariance());

appendToLog("Running SSA...");
Expand Down Expand Up @@ -400,10 +405,11 @@ else if(par.isUseMean()) {

// prepare matrix H on which we want to solve the eigenvalue problem
SSAMatrix H = SSAMatrix.zeros(n, n);
for(int i = 0; i < data.S.length; i++)
for(int i = 0; i < data.mu.length; i++)
{
// whiten means
mu[i] = data.W.mmul(data.mu[i].sub(data.muall));
// whiten means; assume identity covariance matrix
//mu[i] = data.W.mmul(data.mu[i].sub(data.muall));
mu[i] = data.mu[i].sub(data.muall);
// add mu'*mu to H
H.addi(mu[i].mmul(mu[i].transpose()).muli(data.epochSizes[i]));
}
Expand All @@ -419,8 +425,8 @@ else if(par.isUseMean()) {
// loss_n is the sum of the eigenvalues for the non-stationary subspace
double loss_n = diag.getRange(d, n, 0, 1).sum();
// Now normalize losses
int k_s = data.S.length * d; // degrees of freedom of chi^2 distribution
int k_n = data.S.length * (n - d);
int k_s = data.mu.length * d; // degrees of freedom of chi^2 distribution
int k_n = data.mu.length * (n - d);
loss_s = normalizeObjectiveFunction(loss_s, k_s);
loss_n = normalizeObjectiveFunction(loss_n, k_n);

Expand Down Expand Up @@ -486,7 +492,8 @@ public SSAMatrix[] objectiveFunction( int n,

// rotated covariance matrices and means
Snew = new SSAMatrix[S.length];
munew = new SSAMatrix[mu.length];
if(useMean)
munew = new SSAMatrix[mu.length];

//int n = data.getNumberOfDimensions();

Expand Down Expand Up @@ -514,15 +521,20 @@ public SSAMatrix[] objectiveFunction( int n,
// rotate covariance matrix and mean vector in epoch i
SSAMatrix RScomplete = Rcomplete.mmul(S[i]); // R multiplied only from left side (needed for gradient)
SSAMatrix RSRtcomplete = RScomplete.mmul(Rtcomplete); // rotated covariance matrix
SSAMatrix Rmucomplete = Rcomplete.mmul(mu[i]); // rotated mean
SSAMatrix Rmucomplete = null;
if(useMean)
Rmucomplete = Rcomplete.mmul(mu[i]); // rotated mean

// truncate to the stationary subspace
SSAMatrix RS = RScomplete.getRange(0, d, 0, n);
SSAMatrix RSRt = RSRtcomplete.getRange(0, d, 0, d);
SSAMatrix Rmu = Rmucomplete.getRange(0, d, 0, 1);
SSAMatrix Rmu = null;
if(useMean)
Rmu = Rmucomplete.getRange(0, d, 0, 1);

Snew[i] = RSRtcomplete;
munew[i] = Rmucomplete;
if(useMean)
munew[i] = Rmucomplete;

double add = -Math.log(MathFunctions.det(RSRt));
//loss += -Math.log(MathFunctions.det(RSRt));
Expand Down

0 comments on commit d40a7a1

Please sign in to comment.