Fitting two curves with shared parameters to two datasets

조회 수: 2 (최근 30일)
Moosejr
Moosejr 2023년 11월 13일
편집: Torsten 2023년 11월 13일
I want to fit the two functions
to a dataset of the form . Here are a dimensionless distance and two angles (degrees) respectively.
I am trying to follow the procedure describe here.
I generate the dataset using the above functions with some Gaussian noise on top. The data generation seems to work fine.
Yet, the call "lsqcurvefit(fun, x0, alpha_data_tab, beta_data_tab);" gives me an error which indicates that there are some dimension mismatch. However, I do not see it. Can anyone help me with this issue?
clc
close all
clear all
set(0,'defaulttextinterpreter','latex')
set(0,'defaultAxesTickLabelInterpreter','latex');
set(0,'defaultLegendInterpreter','latex');
set(0, 'DefaultLineLineWidth', 2);
set(0,'defaultAxesFontSize',15)
%True parameters
Af0_true = -0.017767; %Fast initial amplitude
As0_true = 0.017767; %Slow initial amplitude
lambda_f_true = -4.0571e-04; %Fast damping parameter; 1/cm
lambda_s_true = 6.4718e-05; %Slow damping parameter; 1/cm
angular_vel_f_true = 0.0228; %Angular velocity; rad/cm
angular_vel_s_true = 0.0050; %Angular velocity; rad/cm
dx = 0.01; %cm
s_true = 0:dx:1000; %cm
std = 0.1; %deg
spacing = 4;
s_data1 = 275:spacing:300;
s_data2 = 350:spacing:375;
s_data3 = 425:spacing:450;
s_data4 = 500:spacing:525;
s_data = [s_data1, s_data2, s_data3, s_data4];
[s, alpha, beta, s_data, alpha_data, beta_data] = dataMaker(Af0_true, As0_true, lambda_f_true, lambda_s_true, angular_vel_f_true, angular_vel_s_true, s_true, s_data, std);
alpha_data_tab = [s_data(:), alpha_data(:)]; % Concatenate Vectors
beta_data_tab = [s_data(:), beta_data(:)]; % Concatenate Vectors
fun1 = @(v,s_data)v(1)*exp(v(3)*s_data).*cos(v(5)*s_data) + v(2)*exp(v(4)*s_data).*cos(v(6)*s_data);
fun2 = @(v,s_data)v(1)*exp(v(3)*s_data).*sin(v(5)*s_data) + v(2)*exp(v(4)*s_data).*sin(v(6)*s_data);
fun = @(v,s_data)[fun1(v,s_data)', fun2(v,s_data)']; % Composite Function
%initial guess
percent = 0.2; %Percent deviation
x0 = [Af0_true-percent*Af0_true, As0_true-percent*As0_true, lambda_f_true-percent*lambda_f_true, lambda_s_true-percent*lambda_s_true,...
angular_vel_f_true-percent*angular_vel_f_true, angular_vel_s_true-percent*angular_vel_s_true];
fun(x0, s_data)
ans = 28×2
0.0027 0.0253 0.0016 0.0250 0.0005 0.0247 -0.0005 0.0244 -0.0015 0.0240 -0.0025 0.0235 -0.0034 0.0229 -0.0102 0.0130 -0.0102 0.0121 -0.0103 0.0112
X = lsqcurvefit(fun, x0, alpha_data_tab, beta_data_tab);
Error using lsqcurvefit
Function value and YDATA sizes are not equal.
function [s_total, alpha_total, beta_total, s_data, alpha_data, beta_data] = dataMaker(Af0_true, As0_true, lambda_f_true, lambda_s_true, angular_vel_f_true, angular_vel_s_true, s_total, s_data, std_deg)
s_total = s_total;
std_rad = std_deg*(pi/180); %rad
%True parameter vector
v0 = [Af0_true, As0_true, lambda_f_true, lambda_s_true, angular_vel_f_true, angular_vel_s_true];
alpha_total = v0(1)*exp(v0(3)*s_total).*cos(v0(5)*s_total) + v0(2)*exp(v0(4)*s_total).*cos(v0(6)*s_total);
beta_total = v0(1)*exp(v0(3)*s_total).*sin(v0(5)*s_total) + v0(2)*exp(v0(4)*s_total).*sin(v0(6)*s_total);
s_data = s_data;
alpha_data = v0(1)*exp(v0(3)*s_data).*cos(v0(5)*s_data) + v0(2)*exp(v0(4)*s_data).*cos(v0(6)*s_data);
beta_data = v0(1)*exp(v0(3)*s_data).*sin(v0(5)*s_data) + v0(2)*exp(v0(4)*s_data).*sin(v0(6)*s_data);
alpha_noise = std_rad*randn(1,length(s_data));
beta_noise = std_rad*randn(1,length(s_data));
alpha_data = alpha_data + alpha_noise;
beta_data = beta_data + beta_noise;
end

채택된 답변

Torsten
Torsten 2023년 11월 13일
편집: Torsten 2023년 11월 13일
clc
close all
clear all
set(0,'defaulttextinterpreter','latex')
set(0,'defaultAxesTickLabelInterpreter','latex');
set(0,'defaultLegendInterpreter','latex');
set(0, 'DefaultLineLineWidth', 2);
set(0,'defaultAxesFontSize',15)
%True parameters
Af0_true = -0.017767; %Fast initial amplitude
As0_true = 0.017767; %Slow initial amplitude
lambda_f_true = -4.0571e-04; %Fast damping parameter; 1/cm
lambda_s_true = 6.4718e-05; %Slow damping parameter; 1/cm
angular_vel_f_true = 0.0228; %Angular velocity; rad/cm
angular_vel_s_true = 0.0050; %Angular velocity; rad/cm
dx = 0.01; %cm
s_true = 0:dx:1000; %cm
std = 0.1; %deg
spacing = 4;
s_data1 = 275:spacing:300;
s_data2 = 350:spacing:375;
s_data3 = 425:spacing:450;
s_data4 = 500:spacing:525;
s_data = [s_data1, s_data2, s_data3, s_data4];
[s, alpha, beta, s_data, alpha_data, beta_data] = dataMaker(Af0_true, As0_true, lambda_f_true, lambda_s_true, angular_vel_f_true, angular_vel_s_true, s_true, s_data, std);
%alpha_data_tab = [s_data(:), alpha_data(:)]; % Concatenate Vectors
%beta_data_tab = [s_data(:), beta_data(:)]; % Concatenate Vectors
xdata = s_data;
ydata = [alpha_data(:),beta_data(:)];
fun1 = @(v,s_data)v(1)*exp(v(3)*s_data).*cos(v(5)*s_data) + v(2)*exp(v(4)*s_data).*cos(v(6)*s_data);
fun2 = @(v,s_data)v(1)*exp(v(3)*s_data).*sin(v(5)*s_data) + v(2)*exp(v(4)*s_data).*sin(v(6)*s_data);
fun = @(v,s_data)[fun1(v,s_data)', fun2(v,s_data)']; % Composite Function
%initial guess
percent = 0.2; %Percent deviation
x0 = [Af0_true-percent*Af0_true, As0_true-percent*As0_true, lambda_f_true-percent*lambda_f_true, lambda_s_true-percent*lambda_s_true,...
angular_vel_f_true-percent*angular_vel_f_true, angular_vel_s_true-percent*angular_vel_s_true];
%X = lsqcurvefit(fun, x0, alpha_data_tab, beta_data_tab);
X = lsqcurvefit(fun, x0, xdata, ydata);
function [s_total, alpha_total, beta_total, s_data, alpha_data, beta_data] = dataMaker(Af0_true, As0_true, lambda_f_true, lambda_s_true, angular_vel_f_true, angular_vel_s_true, s_total, s_data, std_deg)
s_total = s_total;
std_rad = std_deg*(pi/180); %rad
%True parameter vector
v0 = [Af0_true, As0_true, lambda_f_true, lambda_s_true, angular_vel_f_true, angular_vel_s_true];
alpha_total = v0(1)*exp(v0(3)*s_total).*cos(v0(5)*s_total) + v0(2)*exp(v0(4)*s_total).*cos(v0(6)*s_total);
beta_total = v0(1)*exp(v0(3)*s_total).*sin(v0(5)*s_total) + v0(2)*exp(v0(4)*s_total).*sin(v0(6)*s_total);
s_data = s_data;
alpha_data = v0(1)*exp(v0(3)*s_data).*cos(v0(5)*s_data) + v0(2)*exp(v0(4)*s_data).*cos(v0(6)*s_data);
beta_data = v0(1)*exp(v0(3)*s_data).*sin(v0(5)*s_data) + v0(2)*exp(v0(4)*s_data).*sin(v0(6)*s_data);
alpha_noise = std_rad*randn(1,length(s_data));
beta_noise = std_rad*randn(1,length(s_data));
alpha_data = alpha_data + alpha_noise;
beta_data = beta_data + beta_noise;
end

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Design of Experiments (DOE)에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by