MATLAB Answers

domo137
0

lsqnonlinで​同じ評価関数・変数・​入力に対して,普通に​使用した場合と分割し​て使用した場合とで結​果が違うのは何故なの​でしょうか.

domo137
さんによって質問されました 2019 年 10 月 14 日
最新アクティビティ domo137
さんによって コメントされました 2019 年 10 月 18 日
lsqnonlinにおいて,評価関数として次の関数
fuction values = funcOpt(num,r,X,Y)
values = [];
for i=1:1:num
Y_ = Y(3*i-2+3*i,:); % 3*1ベクトル
r_ = r(7*i-6+7*i);
A = setA(r_(1:2)); % 3*3行列
B = setB(r_(3:4)); % 3*4行列
value = reshape(Y_-A*B*X,[],1);
values = [values;value];
end
end
を用いるとき,変数と入力の組み合わせnum個に対して,
下記のコードA・コードBのように使用しました.
% コードA:普通に使用した場合
myfun = ...
@(r) ( funcOpt(num,r,X,Y) );
[optr,optresnorm,optresidual,optexitflag,optoutput] ...
= lsqnonlin(myfun,rini,rlow,rup,optoptions);
%コードB:分割して使用した場合
r_ =[];
optresidual_ =[];
for i=1:1:num
Y_ = Y(3*i-2+3*i,:);
rini_ = rini(7*i-6+7*i);
rlow_ = rlow(7*i-6+7*i);
rup_ = rup(7*i-6+7*i);
%%%
myfun = ...
@(r) ( funcOpt(1,r,X,Y) );
[optr,optresnorm,optresidual,optexitflag,optoutput] ...
= lsqnonlin(myfun,rini_,rlow_,rup_,optoptions);
%%%
r_ = [r_;optr];
optresidual_ = [optresidual_;optresidual];
end
optr = r_;
optresidual = optresidual_;
このとき,optrとoptresidualがコードA・コードBで違いました.
そして,optresidualのノルムはコードBの方が小さかったです.
これは何故なのでしょうか.
恐らく,optoptionsの設定によってoptrとoptresidualが限りなく近くなるように設定できると思うのですが,
どうするのがよいのでしょうか.
ご回答よろしくお願い致します.

  0 件のコメント

サインイン to comment.

1 件の回答

michio
回答者: michio
2019 年 10 月 14 日
 採用された回答

問題設定を完全には把握できていませんが、
case1:num 個分のデータ組み合わせすべてに対して、まとめて非線形最小二乗問題を解く
case2:小分けにされた1つ1つに対して、個別に非線形最小二乗問題を解く
の2つだと、そもそも解いている問題が別のものになっており、後者の方がノルム(誤差)は小さくなりそうな気がしました。直感的にですが。num 個の組み合わせ、それぞれが同じデータであれば case 1 と case 2 は同値・・でしょうか?

  3 件のコメント

domo137
2019 年 10 月 15 日
ご回答ありがとうございます.
> case1:num 個分のデータ組み合わせすべてに対して、まとめて非線形最小二乗問題を解く
> case2:小分けにされた1つ1つに対して、個別に非線形最小二乗問題を解く
こちらの内容で間違いありません.
> num 個の組み合わせ、それぞれが同じデータであれば case 1 と case 2 は同値・・でしょうか?
前者と後者で同じデータを使用しているので,同値あるいは同値に近しい解が得られるような工夫はないでしょうか.
> そもそも解いている問題が別のものになっており、後者の方がノルム(誤差)は小さくなりそうな気がしました。
おっしゃる通り,下記のように表せる違う問題です.
コードA(case 1) 
コードB(case 2)
ですが,変数A_i・B_iと入力Y_iの組が他の組に対して独立な変数ですので,
前者のノルム値を後者のノルム値ぐらいまで下げる方法はあるのではないかと直感的に思ったのですが,いかがでしょうか.
michio
2019 年 10 月 15 日
原理的に違う問題、、というところが引っかかってよい方法が思いつきません。。申し訳ありません。
できれば case 1 の方でまとめて実行したいということかと想像していますが、その理由としては、、そちらの方が実行速度が速いからでしょうか?
num の値の大きさにもよりますが、
r_ = [r_;optr];
optresidual_ = [optresidual_;optresidual];
で、r_, optresidual_ 両変数の配列サイズが動的に変わっています。ここを事前確保しておくだけで処理速度は向上すると思います。
domo137
2019 年 10 月 18 日
続けてご対応ありがとうございます,返信遅くなってしまい申し訳ありません.
"原理的に違う問題"であるということがまだ理解できておらず,そこを理解したいと考えています.
最初case2として問題を設定していたのですが,評価関数に他の組の変数を使った項目を追加したいため,case1の方で問題を解きたいのです.

サインイン to comment.