How to simulate log-normal data and fit a power-law model to each simulation?
105 views (last 30 days)
Show older comments
Hi,
I have lognormally distributed data, which is a sensory-evoked response to repetitive stimulation, that is why it is lognormally distributed over time.
I attached std_spk_avg (400 spikes with different values) distributed along std_time (100 s).
%% Visualization of sensory-evoked response prior to interpolation and power-law fitting
figure
plot(std_time, std_spk_avg)
grid
title('STD')
I power-fit this response and obtain the following a (initial response), b ("decay velocity") and c (steady-state) coefficient values:
% fit a power-law model
ft = fittype( 'power2' ); % y = a*x^b+c
opts = fitoptions(ft);
opts.StartPoint = [1 -1 0];
opts.Lower = [0 -Inf -Inf];
opts.Upper = [Inf 0 Inf];
[xData, yData] = prepareCurveData( S.std.time, S.std.spk );
[fitresult, gof] = fit( xData, yData, ft, opts );
S.std.fitmodel = fitresult;
S.std.gof = gof;
Coefficient_c_STD=fitresult.c;
Which are: a 0.5292; b -0.6258; and c 1.108
Now, I need x400 simulations of my original sensory-evoked response to perform x400 power-fit models and, thus, obtain x400 a, x400 b, and x400 c coefficients. I need the median values of the x400 a, x400 b and x400 c to be as close as possible to the original ones described above (prior to statistical analysis with other data, just to clarify).
I tried this, but as you see, the median values for the three coefficients are not close to the original a, b and c values. How can I fix it?
%% Original sensory-evoked response
figure
plot(std_time, std_spk_avg)
grid
title('STD')
%% Define new time and new spk_avg
new_std_time = linspace(min(std_time), max(std_time), 400*400); % 400 simulations
new_std_spikes = interp1(std_time, std_spk_avg, new_std_time);
figure
plot(new_std_time, new_std_spikes)
grid
title('Interpolated STD')
%% Reshape
time_std_mtx = reshape(new_std_time, 10, []).'
spikes_std_mtx = reshape(new_std_spikes, 10, []).' % Only keep spikes_mtx to perform power fit
%% Figure reshaped sensory-evoked response
figure
plot(std_time, spikes_std_mtx)
title('Ensemble STD Plots')
xlabel('Time (s)')
ylabel('Spike count')
ylim([0 5])
%% Fit power-law model to reshaped sensory-evoked response
ft = fittype( 'power2' ); % Power Fit: y = a*x^b+c
opts = fitoptions(ft); % Power fit options
opts.StartPoint = [1 -1 0];
opts.Lower = [0 -Inf -Inf];
opts.Upper = [Inf 0 Inf];
for i=1:size(spikes_std_mtx,2) % choose spikes_std_mtx; spikes_dev_mtx; spikes_ctr_mtx
[xData, yData] = prepareCurveData(std_time,spikes_std_mtx(:,i)); % choose std; dev (canonical time); ctr (canonical time)
[fitresult, gof] = fit( xData, yData, ft, opts ); % Goodnes of the Fit R^2
results_a(i,:)=fitresult.a;
results_b(i,:)=fitresult.b;
results_c(i,:)=fitresult.c;
results_sse(i,:)=gof.sse;
results_rsquare(i,:)=gof.rsquare;
results_dfe(i,:)=gof.dfe;
results_adjrsquare(i,:)=gof.adjrsquare;
results_rmse(i,:)=gof.rmse;
end
Results_std_coeff = table(results_a,results_b,results_c,results_sse,results_rsquare,results_dfe,results_adjrsquare,results_rmse)
Thank you all so much!
15 Comments
Steven Lord
on 11 Dec 2024 at 18:58
Okay, I think I understand what you're trying to do. But now let me ask: what is your ultimate goal? How are you planning to use the median of those collections of coefficients? Are you trying to somehow present those medians as "the best" coefficients for your data? If so what is your criterion for deciding one set of coefficients is better than another?
If you want "as close as possible" to the coefficient value from your data set, I'm reminded of a quote from Norbert Wiener: "[T]he best material model of a cat is another, or preferably the same cat." Why not just use the coefficients from your original fit? The median of a vector with one element is that element, after all.
Answers (0)
See Also
Categories
Find more on Linear and Nonlinear Regression in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!