Skip to content

2nd (actually nth) order clock offset correction? #16

@dmedine

Description

@dmedine

Has anyone ever evaluated the accuracy of load_xdf's drift correction algorithm? It is a non-standard algorithm (i.e. not part of Matlab) for fitting a first order curve to correct for clock drift between sending and receiving devices

https://github.com/xdf-modules/xdf-Matlab/blob/master/load_xdf.m#L505-L516

xdf-Matlab/load_xdf.m

Lines 773 to 815 in 0cdf054

function x = robust_fit(A,y,rho,iters)
% Perform a robust linear regression using the Huber loss function.
% x = robust_fit(A,y,rho,iters)
%
% Input:
% A : design matrix
% y : target variable
% rho : augmented Lagrangian variable (default: 1)
% iters : number of iterations to perform (default: 1000)
%
% Output:
% x : solution for x
%
% Notes:
% solves the following problem via ADMM for x:
% minimize 1/2*sum(huber(A*x - y))
%
% Based on the ADMM Matlab codes also found at:
% https://web.stanford.edu/~boyd/papers/admm_distr_stats.html
%
% Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
% 2013-03-04
if ~exist('rho','var')
rho = 1; end
if ~exist('iters','var')
iters = 1000; end
x_offset = min(A(:, 2));
A(:, 2) = A(:, 2) - x_offset;
Aty = A'*y;
L = chol( A'*A, 'lower' );
L = sparse(L);
U = sparse(L');
z = zeros(size(y)); u = z;
for k = 1:iters
x = U \ (L \ (Aty + A'*(z - u)));
d = A*x - y + u;
z = rho/(1+rho)*d + 1/(1+rho)*max(0,(1-(1+1/rho)./abs(d))).*d;
u = d - z;
end
x(1) = x(1) - x(2)*x_offset;
end

The reason I ask is that it has come to my attention that 1st order curves may not be appropriate for typical drift. For example, Here is the difference between LSL Markers and a screen flip signal recorded via an EEG device.

drift

The total marker/EEG drift changes from about 27 to 23 ms over the course of several hours. This is definitely enough to muck up ERP/ERSP analysis. Such second order curves are pretty typical but an nth order curve is probably what is best.

If I were to rewrite this, I would use polyfit and do away with the ADMM method using the Huber loss function as minimization criteria but maybe there is a compelling reason for using such a robust tool. I confess that the main reason I would choose polyfit is that I don't fully understand how to adapt the code to return an nth order set of mapping coefficients. scipy has analogs to polyfit but I don't know quite what to do in C++, but there must a be a good lib out there for that stuff.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions