裏 RjpWiki

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

算額(その769)

2024年03月10日 | Julia

算額(その769)

神壁算法 天明5年乙巳 秋九月 第二術 關流四傅藤田権平定資六弟子 奧州一關 梶山主水次俊
藤田貞資(1789):神壁算法巻上

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

大円,小円,甲円,乙円がある。上下の二線(上線,下線)と斜線を引く。
記述が重複するが正確を期すため,これらは以下のように接する。
大円は二線,斜線,小円,甲円,乙円に接する。
小円は二線,大円に接する。
甲円は上線,斜線,大円に接する。
乙円は下線,斜線,大円に接する。
大円,小円,甲円の直径がそれぞれ 245寸,196寸,25寸のとき,乙円の直径はいかほどか。

大円の半径と中心座標を r1, (x1, r1)
小円の半径と中心座標を r2, (0, r2)
甲円の半径と中心座標を r3, (x3, y3)
乙円の半径と中心座標を r4, (x4, r4)
上線は二点 (x02, y02), (x03, y03) を通る
下線は二点 (x02, y02), (x01, 0) を通る
とおき,以下の連立方程式を解く。

include("julia-source.txt");

using SymPy
@syms r1::positive, x1::positive, r2::positive,
     r3::positive, x3::positive, y3::positive,
     r4::positive, x4::positive,
     x01::positive, x02::positive, y02::positive,
     x03::positive, y03::positive
eq1 = dist(x02, y02, x03, y03, x1, r1) - r1^2
eq2 = dist(x02, y02, x03, y03, 0, r2) - r2^2
eq3 = dist(x02, y02, x03, y03, x3, y3) - r3^2
eq4 = dist(x01, 0, x02, y02, x1, r1) - r1^2
eq5 = dist(x01, 0, x02, y02, x3, y3) - r3^2
eq6 = dist(x01, 0, x02, y02, x4, r4) - r4^2
eq7 = sqrt((x02 - x03)^2 + (y02 - y03)^2) - x1
eq8 = x1^2 + (r1 - r2)^2 - (r1 + r2)^2
eq9 = (x1 - x3)^2 + (y3 - r1)^2 - (r1 + r3)^2
eq10 = (x1 - x4)^2 + (r1 - r4)^2 - (r1 + r4)^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 Float64.(v), r.f_converged
end;

function H(u)
   (x1, x3, y3, r4, x4, x01, x02, y02, x03, y03) = u
   return [
       -r1^2 + (r1 - y02 - (-y02 + y03)*((r1 - y02)*(-y02 + y03) + (-x02 + x03)*(-x02 + x1))/((-x02 + x03)^2 + (-y02 + y03)^2))^2 + (-x02 + x1 - (-x02 + x03)*((r1 - y02)*(-y02 + y03) + (-x02 + x03)*(-x02 + x1))/((-x02 + x03)^2 + (-y02 + y03)^2))^2,  # eq1
       -r2^2 + (-x02 - (-x02 + x03)*(-x02*(-x02 + x03) + (r2 - y02)*(-y02 + y03))/((-x02 + x03)^2 + (-y02 + y03)^2))^2 + (r2 - y02 - (-y02 + y03)*(-x02*(-x02 + x03) + (r2 - y02)*(-y02 + y03))/((-x02 + x03)^2 + (-y02 + y03)^2))^2,  # eq2
       -r3^2 + (-x02 + x3 - (-x02 + x03)*((-x02 + x03)*(-x02 + x3) + (-y02 + y03)*(-y02 + y3))/((-x02 + x03)^2 + (-y02 + y03)^2))^2 + (-y02 + y3 - (-y02 + y03)*((-x02 + x03)*(-x02 + x3) + (-y02 + y03)*(-y02 + y3))/((-x02 + x03)^2 + (-y02 + y03)^2))^2,  # eq3
       -r1^2 + (r1 - y02*(r1*y02 + (-x01 + x02)*(-x01 + x1))/(y02^2 + (-x01 + x02)^2))^2 + (-x01 + x1 - (-x01 + x02)*(r1*y02 + (-x01 + x02)*(-x01 + x1))/(y02^2 + (-x01 + x02)^2))^2,  # eq4
       -r3^2 + (-y02*(y02*y3 + (-x01 + x02)*(-x01 + x3))/(y02^2 + (-x01 + x02)^2) + y3)^2 + (-x01 + x3 - (-x01 + x02)*(y02*y3 + (-x01 + x02)*(-x01 + x3))/(y02^2 + (-x01 + x02)^2))^2,  # eq5
       -r4^2 + (r4 - y02*(r4*y02 + (-x01 + x02)*(-x01 + x4))/(y02^2 + (-x01 + x02)^2))^2 + (-x01 + x4 - (-x01 + x02)*(r4*y02 + (-x01 + x02)*(-x01 + x4))/(y02^2 + (-x01 + x02)^2))^2,  # eq6
       -x1 + sqrt((x02 - x03)^2 + (y02 - y03)^2),  # eq7
       x1^2 + (r1 - r2)^2 - (r1 + r2)^2,  # eq8
       (-r1 + y3)^2 - (r1 + r3)^2 + (x1 - x3)^2,  # eq9
       (r1 - r4)^2 - (r1 + r4)^2 + (x1 - x4)^2,  # eq10
   ]
end;

(r1, r2, r3) = (245, 196, 25) .// 2
iniv = BigFloat[219.13, 118.51, 212.5, 24.5, 109.57, 82.18, 107.08, 222.73, -106.65, 174.33]
res = nls(H, ini=iniv)

   ([219.1346617949794, 118.51160280748886, 212.5, 24.5, 109.5673308974897, 82.17549817311728, 107.0771642861831, 222.72727272727272, -106.6467651187968, 174.33221099887766], true)

乙円の半径は 24.5寸 である(直径 49寸)。

その他のパラメータは以下のとおり。

r1 = 122.5;  r2 = 98;  r3 = 12.5;  x1 = 219.135;  x3 = 118.512;  y3 = 212.5;  r4 = 24.5;  x4 = 109.567;  x01 = 82.1755;  x02 = 107.077;  y02 = 222.727;  x03 = -106.647;  y03 = 174.332

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r1, r2, r3) = (245, 196, 25) .// 2
   (x1, x3, y3, r4, x4, x01, x02, y02, x03, y03) = res[1]
   @printf("大円,小円,甲円の直径がそれぞれ %g寸, %g寸, %g寸 のとき,乙円の直径は %g寸\n", 2r1, 2r2, 2r3, 2r4)
   @printf("r1 = %g;  r2 = %g;  r3 = %g;  x1 = %g;  x3 = %g;  y3 = %g;  r4 = %g;  x4 = %g;  x01 = %g;  x02 = %g;  y02 = %g;  x03 = %g;  y03 = %g\n", r1, r2, r3, x1, x3, y3, r4, x4, x01, x02, y02, x03, y03)
   plot()
   circle(x1, r1, r1)
   circle(0, r2, r2, :blue)
   circle(x3, y3, r3, :green)
   circle(x4, r4, r4, :magenta)
   segment(x01, 0, x02, y02)
   y04 = (y02 - y03)/(x02 - x03)*(1.25x1 - x03) + y03
   segment(x03, y03, 1.25x1, y04)
   if more
       delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3  # size[2] * fontsize * 2
       hline!([0], color=:gray80, lw=0.5)
       vline!([0], color=:gray80, lw=0.5)
       point(x01, 0, "x01 ", :black, :right, :bottom, delta=delta)
       point(x02, y02, "(x02,y02)", :black, :right, :bottom, delta=delta)
       point(x03, y03, "(x03,y03)", :black, :left, :bottom, delta=4delta)
       point(x1, r1, " 大円:r1,(x1,r1)", :red, :center, delta=-delta)
       point(0, r2, " 小円:r2,(0,r2)", :blue, :center, delta=-delta)
       point(x3, y3, "   甲円:r3,(x3,y3)", :green, :left, :vcenter)
       point(x4, r4, "      乙円:r4,(x4,r4)", :magenta, :left, :vcenter)
       segment(x03, 0, 1.4x1, 0)
   end
end;


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

コメントを投稿

Julia」カテゴリの最新記事