GSL Shell:非線形2変数方程式の求解モジュール自作

2017-06-24 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-06-23)の記事「GSL Shell 学習:Solve(Findroot)2変数関数版」では、
  ・・・・・
  ・・・・・
  つまり、
    求めたい方程式(2つ)と、それの偏微分関数(4つ)と、初期推定値(2つ)
  で始まり、
    漸化式を順次計算し、収束を判定して、
  終了する。
と云ったソルバーのコードが出来た。


そこで、
いろいろ改良を加えて、モジュール化してみた。


改良点は:
 解きたい方程式と、初期推定値のみを与えて、
 偏導関数は、モジュール内部で 差分による近似で置き換える。
 また、マトリックス演算を展開した四則演算に置き換える。
と云うもの。

で、
(仮称だが)NL_solve_2var.luaモジュールは:
----- NL_solve_2var.lua -----
local M = {}

function M.solve2(f,g,i)
local delta = 10^-8; local D2 = delta^2

local dfx = |x,y| (f(x+delta,y)-f(x,y))/delta --偏導関数の代わり
local dfy = |x,y| (f(x,y+delta)-f(x,y))/delta
local dgx = |x,y| (g(x+delta,y)-g(x,y))/delta
local dgy = |x,y| (g(x,y+delta)-g(x,y))/delta

local x, y = i[1], i[2]; local a, b, c, d, p, q, D, x2, y2, nn
for n=1,100 do
nn=n
a, b, c, d = dfx(x,y), dfy(x,y), dgx(x,y), dgy(x,y)
p, q = -f(x,y), -g(x,y)
D = a*d-b*c; x2 = (d*p-b*q)/D; y2 = (a*q-c*p)/D
if x2^2+y2^2 < D2 then break end -- 収束判定
x, y = x+x2, y+y2
end
return x, y, nn
end

return M
で良い?
反復回数は、最大 100 回で十分だと思う。
収束判定用の微少値は 10^-8 で十分ダ。

このモジュールを使うテストメイン:
----- test_Main_NL_solve_2var.gsl -----
f = |x,y| 2*x^2 + 3*y^2 - 10 -- 対象関数
g = |x,y| y - 4*x - 1
x,y = 1,1 -- 初期推定値

----------------------------
NL = require'NL_solve_2var'

x, y, n = NL.solve2( f, g, {x,y} ) -- 根、反復回数

print( n, x, y ) -- 6, 0.20452221541786, 1.8180888616714
これで?

OKですネ。


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170507,11
関連記事
スポンサーサイト

コメントの投稿

管理者にだけ表示を許可する

おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク