まずSASの公式に乗ってる例から
y = 1 / √x
でy=20となるxの値を求めてみます
グラフにすると
proc fcmp outlib=work.common.solve ;
/*解きたい式を定義*/
function f1(x);
y = 1/sqrt(x);
return(y);
endsub;
/*yを指定して、xを求めて戻すルーチン*/
subroutine solver(y,x);
outargs x ;
x=solve("f1",{.}, y , .);
endsub ;
run;
options cmplib=work.common;
data wk1;
call missing(x);
call solver(20,x);
run;
proc print data=wk1;
run;
👆
と,このように,あらかじめ解きたい式をFCMPで指定し,
FCMP.SOLVE関数の第一引数に 解きたい関数名,第三引数に目標値(ここでいうところの左辺,y)を指定します,
第二引数には計算のための5つのパラメータを配列で与えるのですが,{.}とするとデフォルト設定になります
最後の引数は,第一引数にとった関数に追加引数をここで与えることができます
つぎに3次方程式
を解いてみます
グラフにすると
👆どうも実数解は3つありそうです.ぱっとみ,交点は1,2,3らへん
この場合,初期値の設定によって,収束する解が異なるので,コールルーチンをちょっと改造して,パラメータを細かく指定できるようにして実行してみます
グラフから,おそらくx=1,2,3あたりに解がありそうなので
初期値(initial_value)を,0.001,1.9, 2.9として回してみると
👆
やはり x=1,2,3が解でした.solve_status=0は収束していることを示します
👆
と,このように,あらかじめ解きたい式をFCMPで指定し,
FCMP.SOLVE関数の第一引数に 解きたい関数名,第三引数に目標値(ここでいうところの左辺,y)を指定します,
第二引数には計算のための5つのパラメータを配列で与えるのですが,{.}とするとデフォルト設定になります
最後の引数は,第一引数にとった関数に追加引数をここで与えることができます
つぎに3次方程式
を解いてみます
グラフにすると
👆どうも実数解は3つありそうです.ぱっとみ,交点は1,2,3らへん
この場合,初期値の設定によって,収束する解が異なるので,コールルーチンをちょっと改造して,パラメータを細かく指定できるようにして実行してみます
proc fcmp outlib=work.common.solve ;
/*解きたい式を定義*/
function f1(x);
return(x**3 -6*x**2 + 11*x -6);
endsub;
/*yを指定して、xを求めて戻すルーチン*/
subroutine solver(y,x,initial_value,absolute_criterion,relative_criterion,maximum_iterations,solve_status);
/*設定パラメータ */
array opts[5] initial_value absolute_criterion relative_criterion maximum_iterations solve_status;
outargs x ,solve_status,y ;
x=solve("f1"
,opts
, 0
, .);
put x= solve_status=;
endsub ;
run;
options cmplib=work.common;
data wk1;
call missing(of x);
absolute_criterion=1.0e-12;
relative_criterion=1.0e-6;
maximum_iterations=100;
solve_status=.;
y=0;
initial_value=0.001;
call solver(20,x,initial_value,absolute_criterion,relative_criterion,maximum_iterations,solve_status);
output;
initial_value=1.9;
call solver(20,x,initial_value,absolute_criterion,relative_criterion,maximum_iterations,solve_status);
output;
initial_value=2.9;
call solver(20,x,initial_value,absolute_criterion,relative_criterion,maximum_iterations,solve_status);
output;
run;
proc print data=wk1;
run;
グラフから,おそらくx=1,2,3あたりに解がありそうなので
初期値(initial_value)を,0.001,1.9, 2.9として回してみると
👆
やはり x=1,2,3が解でした.solve_status=0は収束していることを示します
0 件のコメント:
コメントを投稿