47 views (last 30 days)

Show older comments

Star Strider
on 25 Sep 2015

Without actually seeing your data and the analysis you did, I cannot provide a definitive response.

arich82
on 25 Sep 2015

There's a paper by Prof. Boyd from the University of Michigan that appears to address this:

"Computing the zeros, maxima and inflection points of Chebyshev, Legendre and Fourier series: solving transcendental equations by spectral interpolation and polynomial rootfinding" http://link.springer.com/article/10.1007%2Fs10665-006-9087-5#page-1

A summary seems to be given here: http://math.stackexchange.com/questions/370996/roots-of-a-finite-fourier-series

I think this does what you want (not that the roots of the fourier series are given in the variable t):

% fourier coefficients

% (dummy data)

a = [1, 1, 1, 1];

b = [0, 0, 1, 0];

% Note:

% a(1) corresponds to a_0 in the reference

% a(2:end) corresponds to a(1:N) in the reference;

N = numel(a) - 1;

h = [a(end:-1:2) + 1i*b(end:-1:2), 2*a(1), (a(2:end) - 1i*b(2:end))];

B = diag(ones(2*N - 1, 1), 1);

B(end, :) = -h(1:end - 1)/(a(end) - 1i*b(end));

z = eig(B);

t = angle(z);

% note: duplicate t's are imgaginary roots

% eliminate duplicates within tolerance

tol = 10*eps;

t = sort(t);

ind = find(diff(t)./abs(t(2:end)) < tol);

ind = [ind; ind + 1];

t(ind(:)) = [];

% plot results

% f = ugly inline fourier series anonymous function

f = @(x, a, b) sum(bsxfun(@times, a(:).', cos(x(:)*(0:numel(a) - 1))) + bsxfun(@times, b(:).', sin(x(:)*(0:numel(b)-1))), 2);

x = linspace(-pi, pi, 128 + 1);

hf = figure;

ha = axes;

axis([-pi, pi, -sum(a+b)-0.5, sum(a+b)+0.5]);

hold(ha, 'on');

plot(x, f(x, a, b));

plot(t, f(t, a, b), 'o');

plot([-pi, pi], [0, 0], '--c');

I probably won't be around much in the next two days, but feel free to leave a comment, and I'll try to get back to you.

Matt J
on 25 Sep 2015

Edited: Matt J
on 25 Sep 2015

fnzeros only appears to work with spline fits, which makes sense. That's the only way the zeros will have an analytical closed form solution. However, one option would be to sample your Fourier series fit at a finely spaced selection of points. Then, you can fit a spline to those points and use fnzeros on the spline fit to approximate the zeros of the Fourier fit.

If needed, you can refine further by using fzero() on the Fourier fit to do a numerical search. The result of fnzeros from above will give you a list of the initial seed points or search intervals that you would loop over, applying fzero() to each one.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!