Need to Automate multiple sinwave regressions of a dataset

1 view (last 30 days)
I have a data set of 501 days with a sample rate of 1 day. After doing a spectral analysis of the data I want to generate a sinwave for each identified cycle and then best fit that sin wave to my plotted data set.
the variable "sincos" is a vector column of all the values of the identified cycles that I want to multiply sin and cosine with
For example: my data set identifies 5 cycles. In the example code below I have manually typed and retyped the commands in order to generate successive X,X1,X2...etc
betahat,betahat1,...etc
yhat,yhat1,yhat2...etc
and have manually typed in the location of data in my sincos variable. sincos(1), sincos(2), sincos(3)....etc.
I know there is a better way to do this!! Code to automate this process is MOST appreciated!!
>> X = ones(501,3);
X(:,2) = cos(2*pi*(sincos(1))*n)';
X(:,3) = sin(2*pi*(sincos(1))*n)';
betahat = X\y;
yhat = betahat(1)+betahat(2)*cos(2*pi*(sincos(1))*n)+betahat(3)*sin(2*pi*(sincos(1))*n);
>> X1 = ones(501,3);
X1(:,2) = cos(2*pi*(sincos(2))*n)';
X1(:,3) = sin(2*pi*(sincos(2))*n)';
betahat1 = X1\y;
yhat1 = betahat1(1)+betahat1(2)*cos(2*pi(sincos(2))*n)+betahat1(3)*sin(2*pi*(sincos(2))*n);
>> X2 = ones(501,3);
X2(:,2) = cos(2*pi*(sincos(3))*n)';
X2(:,3) = sin(2*pi*(sincos(3))*n)';
betahat2 = X2\y;
yhat2 = betahat2(1)+betahat2(2)*cos(2*pi(sincos(3))*n)+betahat2(3)*sin(2*pi*(sincos(3))*n);
>> X3 = ones(501,3);
X3(:,2) = cos(2*pi*(sincos(4))*n)';
X3(:,3) = sin(2*pi*(sincos(4))*n)';
betahat3 = X3\y;
yhat3 = betahat3(1)+betahat3(2)*cos(2*pi(sincos(4))*n)+betahat3(3)*sin(2*pi*(sincos(4))*n);
>> X4 = ones(501,3);
X4(:,2) = cos(2*pi*(sincos(5))*n)';
X4(:,3) = sin(2*pi*(sincos(5))*n)';
betahat4 = X4\y;
yhat4 = betahat4(1)+betahat4(2)*cos(2*pi(sincos(5))*n)+betahat4(3)*sin(2*pi*(sincos(5))*n);
Thanks for all the assistance! and Wayne.. you are the MAN!

Accepted Answer

Oleg Komarov
Oleg Komarov on 1 May 2012
I suggest to use non-scalar structures:
% Some random inputs
y = rand(501,1);
sincos = rand(5,1);
n = 10;
% Preallocate structure
data(1:5) = struct('X',NaN(501,3),'bhat',NaN(3,1),'yhat',NaN);
% LOOP
for ii = 1:5
tmp = 2*pi*(sincos(ii))*n;
data(ii).X = rand(501,3);
data(ii).X(:,2) = cos(tmp)';
data(ii).X(:,3) = sin(tmp)';
data(ii).bhat = data(ii).X\y;
data(ii).yhat = data(ii).bhat(1)+ data(ii).bhat(2)*cos(tmp) + data(ii).bhat(3)*sin(tmp);
end
Now, each element of the structure array has the same fields but correspond to a different regression. You don't need to hardcode or play around with different names, just remember that the 5th element of the structure has the the 5th regression.
Also, another advantage of this way of organizing data is that you can "collect" the data in the same fields in a very easy way:
[data.bhat]
will concatenate horizontally the estimated coefficients. Each column represents a different regression. With the preallocation you can mix different models (with different number of regressors) and still be able to concatenate results (you can also place them in the right position by hardcoding a vector with positions).
  2 Comments
Clifford Shelton
Clifford Shelton on 3 May 2012
I get an error when I cut and paste your example code:
Warning: Rank deficient, rank = 2, tol = 2.3788e-012.
Warning: Rank deficient, rank = 2, tol = 2.3863e-012.
Warning: Rank deficient, rank = 2, tol = 2.2571e-012.
Warning: Rank deficient, rank = 2, tol = 2.3891e-012.
Warning: Rank deficient, rank = 2, tol = 2.4900e-012.
I also notice that the variables X, yhat, or bhat are not created at all. I'm not understanding why this isn't working. Help is most appreciated!
Oleg Komarov
Oleg Komarov on 3 May 2012
You have to substitute the RHS of
data(ii).X = rand(501,3);
with your "real" data.
Same consideration applies to
% Some random inputs
y = rand(501,1);
sincos = rand(5,1);
n = 10;

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!