裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

算額(その650)

2024年01月23日 | Julia

算額(その650)

神壁算法 東都麹町 橘田彌曾八元克 天明九年
藤田貞資(1789):神壁算法巻上

http://www.wasan.jp/jinpeki/jinpekisanpo1.pdf

全円内に 2 本の弦と 2 個の等円が入っている。全円,等円の直径がそれぞれ 697寸,272寸のとき水平の弦の長さはいかほどか。

全円の半径と中心座標を R, (0, 0)
等円の半径と中心座標を r, (x1, y1), (x2, y + r)
水平な弦と y 軸の交点座標を (0, y)
とおき,以下の連立方程式を解く。

include("julia-source.txt");
# julia-source.txt ソース https://blog.goo.ne.jp/r-de-r/e/ad3a427b84bb416c4f5b73089ae813cf

using SymPy
@syms R, r, x1, y1, x2::negative, x::negative, y::negative
eq1 = x1^2 + y1^2 - (R - r)^2
eq2 = x2^2 + (y + r)^2 - (R - r)^2
eq3 = y1/x1 * (sqrt(R^2 - x^2) - y)/(x -sqrt(R^2 - y^2)) + 1
eq4 = distance(x, sqrt(R^2- x^2), sqrt(R^2 - y^2), y, x1, y1) - r^2
eq5 = distance(x, sqrt(R^2- x^2), sqrt(R^2 - y^2), y, x2, y + r) - r^2;

using NLsolve

function nls(func, params...; ini = [0.0])
   if typeof(ini) <: Number
       r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]), ftol=big"1e-40")
       v = r.zero[1]
   else
       r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=big"1e-40")
       v = r.zero
   end
   return v, r.f_converged
end;

function H(u)
   (x1, y1, x2, x, y) = u
   dy = sqrt(R^2 - x^2)
   dx = sqrt(R^2 - y^2)
   return [
       x1^2 + y1^2 - (R - r)^2,  # eq1
       x2^2 - (R - r)^2 + (r + y)^2,  # eq2
       1 + y1*(dy - y)/(x1*(-dx + x)),  # eq3
       -r^2 + (x1 - (x1*(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2) + (dy - y)*(dx*dy - dx*y1 - dy*x1 - x*y + x*y1 + x1*y))/(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2))^2 + (y1 - (y1*(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2) + (dx - x)*(dx*dy - dx*y1 - dy*x1 - x*y + x*y1 + x1*y))/(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2))^2,  # eq4
       -r^2 + (x2 - (x2*(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2) + (dy - y)*(dx*dy - dx*r - dx*y - dy*x2 + r*x + x2*y))/(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2))^2 + (r + y - ((dx - x)*(dx*dy - dx*r - dx*y - dy*x2 + r*x + x2*y) + (r + y)*(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2))/(dx^2 - 2*dx*x + dy^2 - 2*dy*y + x^2 + y^2))^2,  # eq5
   ]
end;

(R, r) = (697, 272) .// 2
iniv = BigFloat[110, 180, -200, -250, -90]
res = nls(H, ini=iniv)

   (BigFloat[99.9999999999999999999999999999999999999999999999999999999999999999999970530364, 187.5000000000000000000000000000000000000000000000000000000000000000000016344705, -208.0000000000000000000000000000000000000000000000000000000000000000000319742255, -264.0000000000000000000000000000000000000000000000000000000000000000000687439946, -92.5000000000000000000000000000000000000000000000000000000000000000000529196718], true)

水平な弦の長さは 672 寸である。

その他のパラメータは以下の通り。
x1 = 100;  y1 = 187.5;  x2 = -208;  x = -264;  y = -92.5

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (R, r) = (697, 272) .// 2
   (x1, y1, x2, x, y) = res[1]
   弦 = 2sqrt(R^2 - y^2)
   @printf("弦 = %g;  x1 = %g;  y1 = %g;  x2 = %g;  x = %g;  y = %g\n",
       弦, x1, y1, x2, x, y)
   plot()
   circle(0, 0, R, :magenta)
   circle(x1, y1, r)
   circle(x2, y + r, r)
   segment(x, sqrt(R^2 - x^2), sqrt(R^2 - y^2), y, :green)
   segment(-sqrt(R^2 - y^2), y, sqrt(R^2 - y^2), y, :blue)
   if more
       delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3  # size[2] * fontsize * 2
       vline!([0], color=:black, lw=0.5)
       hline!([0], color=:black, lw=0.5)
       point(R, 0, " R", :magenta, :left, :bottom, delta=delta/2)
       point(x1, y1, " 等円:r\n (x1,y1)", :red, :left, :vcenter)
       point(x2, y + r, " (x2,y+r)", :red, :left, :vcenter)
       point(0, y, " y", :blue, :left, delta=-delta/2)
       point(x, sqrt(R^2-x^2), " (x,sqrt(R^2-x^2)", :green, :left, :bottom, delta=-delta/2)
       point(sqrt(R^2-y^2), y, "(sqrt(R^2-y^2),y) ", :blue, :right, :top, delta=-delta/2)
   end
end;


コメント    この記事についてブログを書く
  • Twitterでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 算額(その649) | トップ | 算額(その651) »
最新の画像もっと見る

コメントを投稿

Julia」カテゴリの最新記事