誤差を含む計測データ​をサインカーブにフィ​ッティングしたい!!​!

45 vues (au cours des 30 derniers jours)
雄大
雄大 le 28 Fév 2023
こんにちは,はじめて質問させていただきます.よろしくお願いいたします.
以下のようなデータをサインカーブにフィッティングしたいと考えてます.
x = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5];
y = [9.55386683640000e-09,9.16928041520000e-09,8.19770918880000e-09,8.32947430070000e-09,8.50579673860000e-09,9.03976940820000e-09,9.98143656190000e-09,1.11838458083000e-08,1.16689569371000e-08,1.13607976059000e-08,1.20669528900000e-08, 1.30015115402000e-08,1.30830855344000e-08,1.09558864261000e-08,1.12743819372000e-08,1.04811612118000e-08];
xは測定点の値.yは実際の計測値になります.
保有しいるTool Box は Optimaization ToolBox です.
現状ではデータから無理やり,フーリエ級数を求めプロットしているため,かくかくになってしまいます.もっと滑らかにしたいです.
Optimization ToolBoxをもちいてフィッティングを試みましたが,以下のような画像になっていしまいました.
実行したコードは
x = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5];
data = [9.55386683640000e-09,9.16928041520000e-09,8.19770918880000e-09,8.32947430070000e-09,8.50579673860000e-09,9.03976940820000e-09,9.98143656190000e-09,1.11838458083000e-08,1.16689569371000e-08,1.13607976059000e-08,1.20669528900000e-08,1.30015115402000e-08,1.30830855344000e-08,1.09558864261000e-08,1.12743819372000e-08,1.04811612118000e-08];
% サイン関数の式を定義する
sin_func = @(x, params) params(1) * sin(x * pi / 180 + params(2)) + params(3);
% 目的関数を定義する
objective_func = @(params) sum((sin_func(x, params) - data).^2);
% 初期値を設定する
init_params = [1e-8, 0, 1e-8];
% 最適化を実行する
options = optimoptions('fmincon', 'Display', 'iter', 'Algorithm', 'interior-point');
[opt_params, ~, ~, output] = fmincon(objective_func, init_params, [], [], [], [], [0, -pi/2, 0], [Inf, pi/2, Inf], [], options);
% フィッティング結果をプロットする
x_fit = linspace(0, 360, 1000);
y_fit = sin_func(x_fit, opt_params);
plot(x, data, 'o', x_fit, y_fit, '-')
なのですが,フィッテイングを適切に行うためにアドバイスをいただきたいと考えています.
何卒,よろしくお願いいたします.

Réponse acceptée

Tohru Kikawada
Tohru Kikawada le 28 Fév 2023
データの値のレンジが小さいため許容誤差を大きく下回っていて最適化が進んでいないように見受けられます。
ひとまず data のレンジを最大最小値でスケーリングすることで最適化が進むようになりました。
もしくは optimoptions の許容誤差のパラメータ値(例えば ConstraintTolerance)を下げることでも同様の効果があるかもしれません。
x = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5];
data = [9.55386683640000e-09,9.16928041520000e-09,8.19770918880000e-09,8.32947430070000e-09,8.50579673860000e-09,9.03976940820000e-09,9.98143656190000e-09,1.11838458083000e-08,1.16689569371000e-08,1.13607976059000e-08,1.20669528900000e-08,1.30015115402000e-08,1.30830855344000e-08,1.09558864261000e-08,1.12743819372000e-08,1.04811612118000e-08];
% データをスケーリング
scale_factor = max(data) - min(data);
data = data / scale_factor;
% サイン関数の式を定義する
sin_func = @(x, params) params(1) * sin(x * pi / 180 + params(2)) + params(3);
% 目的関数を定義する
objective_func = @(params) sum((sin_func(x, params) - data).^2);
% 初期値を設定する
init_params = [1, 0, 0];
% 最適化を実行する
options = optimoptions('fmincon', 'Display', 'iter', 'Algorithm', 'interior-point');
[opt_params, ~, ~, output] = fmincon(objective_func, init_params, [], [], [], [], [0, -pi, -inf], [inf, pi, inf], [], options);
First-order Norm of Iter F-count f(x) Feasibility optimality step 0 4 8.945939e+01 0.000e+00 6.872e+01 1 12 1.351582e+01 0.000e+00 1.470e+01 1.711e+00 2 16 2.111668e+00 0.000e+00 1.551e+01 1.839e+00 3 20 2.060642e+00 0.000e+00 6.120e+00 6.275e-01 4 24 8.738635e-01 0.000e+00 5.198e+00 9.986e-01 5 28 2.206055e-01 0.000e+00 1.691e+00 3.037e-01 6 33 1.524155e-01 0.000e+00 7.196e-01 3.815e-01 7 37 1.215848e-01 0.000e+00 1.144e-01 9.019e-02 8 41 1.229385e-01 0.000e+00 9.999e-02 5.813e-03 9 45 1.172419e-01 0.000e+00 2.539e-02 4.076e-02 10 49 1.167534e-01 0.000e+00 2.398e-03 1.569e-02 11 53 1.167512e-01 0.000e+00 2.016e-04 1.018e-03 12 57 1.167512e-01 0.000e+00 1.187e-05 1.420e-04 13 61 1.167512e-01 0.000e+00 2.000e-06 4.238e-07 14 65 1.167512e-01 0.000e+00 4.297e-08 1.311e-06 Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
opt_params
opt_params = 1×3
0.4284 -2.6660 2.1474
% フィッティング結果をプロットする
x_fit = linspace(0, 360, 1000);
y_fit = sin_func(x_fit, opt_params);
plot(x, data * scale_factor, 'o', x_fit, y_fit * scale_factor, '-')

Plus de réponses (0)

Catégories

En savoir plus sur 最小二乗法 dans Help Center et File Exchange

Produits


Version

R2022b

Community Treasure Hunt

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

Start Hunting!