Back to the main page.
Bug 2562 - time axes numerical imprecision with ft_redefinetrial overlap option
Status |
ASSIGNED |
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 |
URL: |
|
Tags: |
|
Depends on: |
|
Blocks: |
|
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 http://bugzilla.fcdonders.nl/show_bug.cgi?id=1943