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

조회 수: 45 (최근 30일)
雄大
雄大 2023년 2월 28일
답변: Tohru Kikawada 2023년 2월 28일
こんにちは,はじめて質問させていただきます.よろしくお願いいたします.
以下のようなデータをサインカーブにフィッティングしたいと考えてます.
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, '-')
なのですが,フィッテイングを適切に行うためにアドバイスをいただきたいと考えています.
何卒,よろしくお願いいたします.

채택된 답변

Tohru Kikawada
Tohru Kikawada 2023년 2월 28일
データの値のレンジが小さいため許容誤差を大きく下回っていて最適化が進んでいないように見受けられます。
ひとまず 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, '-')

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 最小二乗法에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!