-
Notifications
You must be signed in to change notification settings - Fork 16
Description
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
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.
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.
