誤差を含む計測データをサインカーブにフィッティングしたい!!!
45 views (last 30 days)
Show older comments
こんにちは,はじめて質問させていただきます.よろしくお願いいたします.
以下のようなデータをサインカーブにフィッティングしたいと考えてます.
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, '-')
なのですが,フィッテイングを適切に行うためにアドバイスをいただきたいと考えています.
何卒,よろしくお願いいたします.
0 Comments
Accepted Answer
Tohru Kikawada
on 28 Feb 2023
データの値のレンジが小さいため許容誤差を大きく下回っていて最適化が進んでいないように見受けられます。
ひとまず data のレンジを最大最小値でスケーリングすることで最適化が進むようになりました。
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);
opt_params
% フィッティング結果をプロットする
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 Comments
More Answers (0)
See Also
Categories
Find more on 最小二乗法 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!