Back to the main page.

Bug 2562 - time axes numerical imprecision with ft_redefinetrial overlap option

Reported 2014-05-05 23:28:00 +0200
Modified 2014-05-15 18:17:53 +0200
Product: FieldTrip
Component: core
Version: unspecified
Hardware: PC
Operating System: Linux
Importance: P5 normal
Assigned to: Diego Lozano Soldevilla
Depends on:
See also:

Diego Lozano Soldevilla - 2014-05-05 23:28:55 +0200

When using ft_redefinetrial to make overlaping time windows, offset2time produces a time axes with different numerical imprecision in "some" pieces of the time vector. Here one example: % create raw structure n = 100000; data = []; data.fsample = 1000; data.label{1} = '1'; data.trial{1} = randn(1,n); data.time{1} = (0:1:size(n,2)-1)./data.fsample; % make pieces of 1sec with 50% overlaping cfg = []; cfg.length = 1; cfg.overlap = 0.5; dat = ft_redefinetrial(cfg, data); First trial seem OK: 1./mean(diff(dat.time{1})) ans = 1000 But other trials have different numerical precision >> 1./mean(diff(dat.time{8})) ans = 1.0000e+03 This produces errors in ft_specest* functions because the sampling frequency is computed by 1./mean(diff(time)) No clue why sometimes happens with high offset values: >> 1./mean(diff(offset2time(1, data.fsample, cfg.length*data.fsample))) ans = 1000 >> 1./mean(diff(offset2time(100, data.fsample, cfg.length*data.fsample))) ans = 1000 >> 1./mean(diff(offset2time(10000, data.fsample, cfg.length*data.fsample))) ans = 1.0000e+03 Could somebody replicate it?

Diego Lozano Soldevilla - 2014-05-15 18:17:53 +0200

After a long discussion/tests together with Robert, here some conclusions: - The core of the problem is related to the numerical precision to represent a long time vector. At some limit of preciosion (type "eps" in matlab), numerical precision results no longer accurate: >> (1+eps) ans = 1.0000 >> (1+eps)-1 ans = 2.2204e-16 Now lets illustrate it with a time axes: % create raw structure n = 100000; dat = randn(1,n); data = []; data.fsample = 1000; data.label{1} = '1'; data.trial{1} = dat; data.time{1} = (0:1:size(dat,2)-1)./data.fsample; >> 1./mean(diff(data.time{1})) ans = 1000 >> 1./mean(diff(data.time{1}(1,3500:6000))) ans = 1.0000e+03 The above example shows clearly the problem. The time inaccuracy exists in the time axes because it's very long. When we compute the sampling frequency as 1./mean(diff(data.time{1})), the inaccuracy "disappear" because the "mean" average. However, if the compute shorter periods, we can detect it. In the following figure you can see the complex pattern of the inaccuracy: time4000 = 4000/fsample + (0:(nsamples-1))/fsample; figure;plot(diff(time4000)-1/1000, '.'); To put it stronger, let's redefine the data in multiple shorter epochs: % make pieces of 1sec with 50% overlaping cfg = []; cfg.length = 1; cfg.overlap = 0.5; dataover = ft_redefinetrial(cfg, data); allfsample = zeros(1, length(dataover.time)); for i=1:length(dataover.time) allfsample(i) = 1./mean(diff(dataover.time{i})); end figure;plot(allfsample-1000, '.') Now you can see that the numerical imprecision is jumping in a range close to the eps. BOTTOM-LINE: As fixetimeaxes function failed to fix the problem, I'll try to use the "find" solution Martin proposed