I'm trying to calculate the mean square displacement of a time series.
This is the following function when I consider that the time intervals in the time series are equal:
function [msdpts, sem] = msd_2D(x,y,N)
r = sqrt(x.^2 + y.^2);
sem = zeros(N, 1);
msdpts = zeros(N, 1);
for i = 1:N
sqdisp = (r(1+i:end) - r(1:end-i)).^2;
sem(i) = std(sqdisp)/sqrt(N);
msdpts(i) = mean(sqdisp);
end
end
How can this code can be written when the time intervals in the time series are random (not equal)?
Note: Linearizing the time series in this case is not an option.
Related
The formula for the discrete double Fourier series that I'm attempting to code in MATLAB is:
The coefficient in front of the trigonometric sum (Fourier amplitude) is what I'm trying to extract from the fitting of the data through the double Fourier series seen above. Using my current code, the original function is not reconstructed, therefore my coefficients cannot be correct. I'm not certain if this is of any significance or insight, but the second term for the A coefficients (Akn(1))) is 13 orders of magnitude larger than any other coefficient.
Any suggestions, modifications, or comments about my program would be greatly appreciated.
%data = csvread('digitized_plot_data.csv',1);
%xdata = data(:,1);
%ydata = data(:,2);
%x0 = xdata(1);
lambda = 20; %km
tau = 20; %s
vs = 7.6; %k/s (velocity of CHAMP satellite)
L = 4; %S
% Number of terms to use:
N = 100;
% set up matrices:
M = zeros(length(xdata),1+2*N);
M(:,1) = 1;
for k=1:N
for n=1:N %error using *, inner matrix dimensions must agree...
M(:,2*n) = cos(2*pi/lambda*k*vs*xdata).*cos(2*pi/tau*n*xdata);
M(:,2*n+1) = sin(2*pi/lambda*k*vs*xdata).*sin(2*pi/tau*n*xdata);
end
end
C = M\ydata;
%least squares coefficients:
A0 = C(1);
Akn = C(2:2:end);
Bkn = C(3:2:end);
% reconstruct original function values (verification check):
y = A0;
for k=1:length(Akn)
y = y + Akn(k)*cos(2*pi/lambda*k*vs*xdata).*cos(2*pi/tau*n*xdata) + Bkn(k)*sin(2*pi/lambda*k*vs*xdata).*sin(2*pi/tau*n*xdata);
end
% plotting
hold on
plot(xdata,ydata,'ko')
plot(xdata,yk,'b--')
legend('Data','Least Squares','location','northeast')
xlabel('Centered Time Event [s]'); ylabel('J[\muA/m^2]'); title('Single FAC Event (50 Hz)')
I'm trying to create a 3d plot to show the amplitude of adding 3 sinusoids of varying phase. The three axes would be: time, frequency and magnitude. I'm just not sure how I can convert what I have into something that the function 3dplot can use. New to this, thanks!
clear;
clc;
inc = 100;
i = 1;
i2 = 1;
for t = 0:(2.413E-9)/inc:2.413E-9 %time range to view signals
for f = 56E9:(64E9-56E9)/inc:64E9 %frequencies from 56ghz - 64ghz
w = 2*pi*f;
wave1 = 0.5*sin(w.*t + (0.25*2));%sinusoids of varying distances, arbitrary amplitude
wave2 = 0.5*sin(w.*t);
wave3 = 0.5*sin(w.*t - (0.25*2));
mag = wave1 + wave2 + wave3;%combining waves
combined(i,i2,i) = mag;
%f,time,magnitude
i = i + 1;%changing frequency index
end
i = 1;
i2 = i2 + 1;%changing time index
end
EDIT: Thanks everyone, I think I have what I was looking for.
Here are some suggestions:
You probably want to replace combined(i,i2,i) = mag; by combined(i,i2) = mag;. That will create combined as a matrix (2D array) giving magnitude as a function of time and frequency
To plot that, use something like surf or imagesc.
The code can be vectorized. This makes it more compact, arguably more readable, and faster.
The figure changes significantly if you change inc. This may be a sign that the current inc is causing aliasing in the representation. You may want to increase that parameter.
You may want to avoid using i as variable name.
Code:
clear;
clc;
inc = 100;
t = 0:(2.413E-9)/inc:2.413E-9; %time range to view signals
f = 56E9:(64E9-56E9)/inc:64E9 %frequencies from 56ghz - 64ghz
w = 2*pi*f;
wave1 = 0.5*sin(bsxfun(#times, w.', t) + (0.25*2));%sinusoidsdistances
wave2 = 0.5*sin(bsxfun(#times, w.', t));
wave3 = 0.5*sin(bsxfun(#times, w.', t) - (0.25*2));
combined = wave1 + wave2 + wave3;%combining waves
%f,time,magnitude
surf(t, f, combined, 'edgecolor', 'none')
xlabel time
ylabel frequency
I have a function that plots the magnitude of an fft function from a signal.
For every iteration I want to determine the x-value of the two peaks below 2000. I thought this was relatively simple using the function findpeaks however it has not given me the correct output.
I do not intend to plot the ouput, but just for illustration purposes here is a plot. I only want to know the peaks for the data below 2000 (the first set of peaks)
Example of one iteration:
Here is a bit of my code. B is a vector containing the starting indices for every segment of data that needs to be analysed.
function [number] = fourir_(data,sampling_rate)
%Finds the approximate starting index of every peak segment
%B is a vector containing the indeces
[A,B] = findpeaks(double(abs(data) > 0.6), 'MinPeakDistance', 2500);
Fs = sampling_rate;
t = 0:1/Fs:0.25;
C = zeros(size(B),2)
for i = 1:numel(B)
new_data = data(B(i):(B(i)+200))
y = double(new_data)/max(abs(new_data));
n = length(y);
p = abs(fft(y));
f = (0:n-1)*(Fs/n);
end
Example data: https://www.dropbox.com/s/zxypn3axoqwo2g0/signal%20%281%29.mat?dl=0
Here is your answer, this is exactly what #Ed Smith suggested in his first comment. You can just add a threshold in order to distinguish the major peak.
%Finds the approximate starting index of every peak segment
%B is a vector containing the indeces
[A,B] = findpeaks(double(abs(data) > 0.6), 'MinPeakDistance', 2500);
Fs = sampling_rate;
t = 0:1/Fs:0.25;
C = zeros(size(B),2)
for i = 1:numel(B)
new_data = data(B(i):(B(i)+200))
y = double(new_data)/max(abs(new_data));
n = length(y);
p = abs(fft(y));
f = (0:n-1)*(Fs/n);
p1 = p(1:round(length(p)/2));
p1(p1<10) = 0; %add a threshold
[~,ind] = findpeaks(p1); %index of where are the peaks
C(i,:) = f(ind);
hold on
plot(f,p,'b',C(i,:),p(ind),'ro')
end
The following may help, which seems to get the peaks from one fft of your signal data,
clear all
close all
%load sample data from https://www.dropbox.com/s/zxypn3axoqwo2g0/signal%20%281%29.mat?dl=0
load('./signal (1).mat')
%get an FFT and take half
p = abs(fft(signal));
p = p(1:length(p)/2);
%find peaks and plot
[pk, loc] = findpeaks(p,'MINPEAKHEIGHT',100,'MINPEAKDISTANCE',100);
plot(p,'k-')
hold all
plot(loc, pk, 'rx')
which looks like,
Where some of the peaks are isolated...
I am trying to use a finite difference method to solve the heat equation for a given function u0. I want to evolve it in time using plots to see each frame change but when I run it all I see is the same frame over and over. I am aware of the error at the ends due to me not giving "u" a first or last index which will cause more overall error in the solution. I am not very good at matlab so I am not sure if I am writing my nested piece correctly.
% set up domain in time and space
t_step = .1;
tspan = [0 :t_step:1000];
L = 10; %length of domain
n = 64;
dx = 2*pi/(n-1); %spacing
x = 0:dx:2*pi;
x = x'; %make x vertical vector
% initial conditions for the function
u0 = sin(2*pi*x/L)+0*cos(3*2*pi*x/L) + 0.2*(cos(5*2*pi*x/L))+0*randn(size(x));
plot(x,u0);title('initial condition');pause;
t = 0;
for m = 1:tspan(end)
u = u0;
t = t + t_step;
for j= 2:n-1
u(j,m) = u0(j-1) - 2*u0(j) + u0(j+1)/dx^2; %u(1) and n left out
end
plot(x,u(:,m))
pause(0.01);
end
I have a rather simple question that I need some advice on. If I have a time series
t = 1:365;
raw = 10+(10-2).*rand(1,length(t)); % generate random time series
signal_1 = 10*sin(2*pi*t/12)+20; % create a signal with a period of 24
signal_2 = 10*sin(2*pi*t/32)+20; % create a signal with a period of 32
y = raw + signal_1 + signal_2; % combine the signals
and I can make the signal to have zero mean and unit variance by
y2 = (y - nanmean(y))./nanstd(y); % zero mean with unit variance
How would I convert this back to the same magnitude as the original series i.e. convert back to be the same as 'y'?
Record the mean and stddev before you do the transformation, so that you can reapply in the opposite direction:
mu = nanmean(y);
sd = nanstd(y);
y2 = (y - mu) / sd;
...
y3 = y2 * sd + mu;