tseriesinterp.m 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. function m = tseriesinterp(m,trorig,trnew,dim,numsamples,fakeout,wantreplicate,interpmethod)
  2. % function m = tseriesinterp(m,trorig,trnew,dim,numsamples,fakeout,wantreplicate,interpmethod)
  3. %
  4. % <m> is a matrix with time-series data along some dimension.
  5. % can also be a cell vector of things like that.
  6. % <trorig> is the sampling time of <m> (e.g. 1 second)
  7. % <trnew> is the new desired sampling time
  8. % <dim> (optional) is the dimension of <m> with time-series data.
  9. % default to 2 if <m> is a row vector and to 1 otherwise.
  10. % <numsamples> (optional) is the number of desired samples.
  11. % default to the number of samples that makes the duration of the new
  12. % data match or minimally exceed the duration of the original data.
  13. % <fakeout> (optional) is a duration in seconds. If supplied,
  14. % we act as if the time-series data was delayed by <fakeout>,
  15. % and we obtain time points that correspond to going back in time
  16. % by <fakeout> seconds. Default: 0.
  17. % <wantreplicate> (optional) is whether to repeat the first and last
  18. % data points 3 times (e.g. 1 1 1 1 2 3 4 ... ) before performing
  19. % interpolation. The rationale is to try to avoid crazy extrapolation
  20. % values. Default: 0.
  21. % <interpmethod> (optional) is the interpolation method, like 'pchip'.
  22. % Default: 'pchip'.
  23. %
  24. % Use interp1 to interpolate <m> (with extrapolation) such that
  25. % the new version of <m> coincides with the original version of <m>
  26. % at the first time point. (If <fakeout> is used, the new version
  27. % of <m> is actually shifted by <fakeout> seconds earlier than the
  28. % original version of <m>.)
  29. %
  30. % Note that <m> can be complex-valued; the real and imaginary parts
  31. % are separately analyzed. This inherits from interp1's behavior.
  32. %
  33. % example:
  34. % x0 = 0:.1:10;
  35. % y0 = sin(x0);
  36. % y1 = tseriesinterp(y0,.1,.23);
  37. % figure; hold on;
  38. % plot(x0,y0,'r.-');
  39. % plot(0:.23:.23*(length(y1)-1),y1,'go');
  40. %
  41. % another example (complex data):
  42. % x = (rand(1,100)*2*pi)/4 + pi;
  43. % x2 = ang2complex(x);
  44. % y = tseriesinterp(x2,1,.1,[],[],[],1);
  45. % y2 = mod(angle(y),2*pi);
  46. % figure; hold on;
  47. % plot(1:length(x),x,'ro');
  48. % plot(linspacefixeddiff(1,.1,length(y2)),y2,'b-');
  49. % internal constants
  50. numchunks = 20;
  51. % input
  52. if ~exist('dim','var') || isempty(dim)
  53. dim = choose(isrowvector(m),2,1);
  54. end
  55. if ~exist('numsamples','var') || isempty(numsamples)
  56. numsamples = [];
  57. end
  58. if ~exist('fakeout','var') || isempty(fakeout)
  59. fakeout = 0;
  60. end
  61. if ~exist('wantreplicate','var') || isempty(wantreplicate)
  62. wantreplicate = 0;
  63. end
  64. if ~exist('interpmethod','var') || isempty(interpmethod)
  65. interpmethod = 'pchip';
  66. end
  67. % prep
  68. if iscell(m)
  69. leaveascell = 1;
  70. else
  71. leaveascell = 0;
  72. m = {m};
  73. end
  74. % do it
  75. for p=1:length(m)
  76. % prep 2D
  77. msize = size(m{p});
  78. m{p} = reshape2D(m{p},dim);
  79. % calc
  80. if isempty(numsamples)
  81. numsamples = ceil((size(m{p},1)*trorig)/trnew);
  82. end
  83. % do it
  84. if wantreplicate
  85. timeorig = [[-3 -2 -1]*trorig linspacefixeddiff(0,trorig,size(m{p},1)) [(size(m{p},1)-1)*trorig+[1 2 3]*trorig]];
  86. else
  87. timeorig = linspacefixeddiff(0,trorig,size(m{p},1));
  88. end
  89. timenew = linspacefixeddiff(0,trnew,numsamples) - fakeout;
  90. % do in chunks
  91. chunks = chunking(1:size(m{p},2),ceil(size(m{p},2)/numchunks));
  92. temp = {};
  93. mtemp = m{p};
  94. parfor q=1:length(chunks)
  95. if wantreplicate
  96. temp{q} = interp1(timeorig, ...
  97. cat(1,repmat(mtemp(1,chunks{q}),[3 1]), ...
  98. mtemp(:,chunks{q}), ...
  99. repmat(mtemp(end,chunks{q}),[3 1])), ...
  100. timenew,interpmethod,'extrap');
  101. else
  102. temp{q} = interp1(timeorig,mtemp(:,chunks{q}),timenew,interpmethod,'extrap');
  103. end
  104. end
  105. m{p} = catcell(2,temp);
  106. clear temp mtemp;
  107. % prepare output
  108. msize(dim) = numsamples;
  109. m{p} = reshape2D_undo(m{p},dim,msize);
  110. end
  111. % prepare output
  112. if ~leaveascell
  113. m = m{1};
  114. end