裏 RjpWiki

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

算額(その296)

2023年06月22日 | Julia

算額(その296)

中村信弥「算額への招待 追補2」
http://www.wasan.jp/syotai/syotai.html
長野県千曲市八幡 武水別神社(八幡神社) 天保8年(1837) 

天円,地円,人円が互いに外接し,三角形に内接している。天円と地円の直径がそれぞれ 8 寸,4.5 寸のとき,三角形の三辺の長さを求めよ。

図に示すように記号を定め,以下の連立方程式を nlsolve() により解く。

include("julia-source.txt");

using SymPy

@syms r1::positive, r2::positive, r3::positive,
     x1::positive, x2::positive, x3::positive, x32::positive,
     a::positive, b::positive, c::positive;

(r1, r2) = (8//2, 9//4)
eq1 = r3/x3 - r2/x2
eq2 = r3/x3 - r1/x1
eq3 = (x2 - x3)^2 + (r2 - r3)^2 - (r2 + r3)^2
eq4 = (x1 - x2)^2 + (r1 - r2)^2 - (r1 + r2)^2
eq5 = (x32 - x1)^2 + (r1 - r3)^2 - (r1 + r3)^2
eq6 = (a + sqrt((a - b)^2 + c^2) + sqrt(b^2 + c^2)) * r1 - a * c
eq7 = r3 / (a - x32) - r1 / (a - x1)
eq8 = distance(b, c, a, 0, x1, r1) - r1^2

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8, eq9])

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=1e-14)
       v = r.zero[1]
   else
       r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=1e-14)
       v = r.zero
   end
   return v, r.f_converged
end;

function H(u)
   (r3, x1, x2, x3, x32, a, b, c) = u
   return [
r3/x3 - 9/(4*x2),  # eq1
r3/x3 - 4/x1,  # eq2
(9/4 - r3)^2 - (r3 + 9/4)^2 + (x2 - x3)^2,  # eq3
(x1 - x2)^2 - 36,  # eq4
(4 - r3)^2 - (r3 + 4)^2 + (-x1 + x32)^2,  # eq5
-a*c + 4*a + 4*sqrt(b^2 + c^2) + 4*sqrt(c^2 + (a - b)^2),  # eq6
r3/(a - x32) - 4/(a - x1),  # eq7
(x1 - (a^2*x1 - 2*a*b*x1 + a*c^2 - 4*a*c + b^2*x1 + 4*b*c)/(a^2 - 2*a*b + b^2 + c^2))^2 + (-c*(a^2 - a*b - a*x1 + b*x1 + 4*c)/(a^2 - 2*a*b + b^2 + c^2) + 4)^2 - 16,  # eq8
      ]
end;

iniv = [big"1.3", 14, 8, 4, 18, 20, 15, 10]
res = nls(H, ini=iniv);

using Printf
names =  ("r3", "x1", "x2", "x3", "x32", "a", "b", "c")
for (i, name) in enumerate(names)
   @printf("%s = %.6f\n", name, res[1][i])
end
println(res[2])

   r3 = 1.265625
   x1 = 13.714286
   x2 = 7.714286
   x3 = 4.339286
   x32 = 18.214286
   a = 20.297143
   b = 15.250421
   c = 9.723228
   true

大斜 = a = 20.29714285714286
中斜 = sqrt(b^2 + c^2) = 18.08636238036625
小斜 = sqrt((a - b)^2 + c^2)) = 10.954933808937678

算額の答えは,大斜 = 41.427,中斜 = 29.533,小斜 = 15.534 であるが,これはありえない。図を描くとわかる。

中村信弥「算額への招待 追補2」では,大斜の式として,天地人の直径をそれぞれ a, x, b として
l = a/(a - b)*(sqrt(a*sqrt(a*b)) + sqrt(b*sqrt(a*b)) + sqrt(a*b))
を導いている。この式は正しいが,
「a = 8, b = 4.5 とすると l = 16*(6 + 7√3)/7 = 41.427097...」としているが,4.5 は地円の直径であり,人円の直径はこの時点では未知である。
実は,途中で x = sqrt(a*b) とあるので,既知の a, x から b を求めればよい。すなわち,b = x^2/a である。b = 4.5 を代入したために間違った解を求めてしまったのである。
上の式で,a = 8, b = 4.5^2/8 = 2.53125 を代入すれば,大斜 = 20.297142857142855 になる。元の算額の術も同じ間違いをおかしている。

a = 8
b = 4.5^2/8  # = 2.53125
l = a/(a - b)*(sqrt(a*sqrt(a*b)) + sqrt(b*sqrt(a*b)) + sqrt(a*b))

   20.297142857142855

using Plots

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r3, x1, x2, x3, x32, a, b, c) = res[1]
   println("r1 = $(Float64(r1));  r2 = $(Float64(r2))")
   println("大斜 = $(Float64(a));  中斜 = $(Float64(sqrt(b^2 + c^2)));  小斜 = $(Float64(sqrt((a - b)^2 + c^2)))")
   plot([0, a, b, 0], [0, 0, c, 0], color=:black, lw=0.5)
   circle(x1, r1, r1)
   circle(x2, r2, r2, :blue)
   circle(x3, r3, r3, :green)
   circle(x32, r3, r3, :green)
   if more
       point(x1, r1, "天:r1,(x1,r1)", :red, :center)
       point(x2, r2, "地:r2,(x2,r2)", :blue, :center)
       point(x3, r3, "人:r3,(x3,r3)", :green, :center)
       point(x32, r3, "人:r3,(x32,r3)", :green, :center)
       point(b, c, " (b,c)", :green, :left, :bottom)
       point(a, 0, " a", :green, :left, :bottom)
       vline!([0], color=:black, lw=0.5)
       hline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

算額(その295)

2023年06月22日 | Julia

算額(その295)

中村信弥「算額への招待 追補2」
http://www.wasan.jp/syotai/syotai.html
長野県千曲市八幡 武水別神社(八幡神社) 天保8年(1837) 

直角三角形(鉤股弦)の中に,天円,地円,人円それぞれ 1 個,小円 2 個が入っている。
天地人円の直径の和と大円の直径の積,および直角三角形の周の二乗の和が 46216 歩のとき,鉤および股を求めよ。

図に示すように記号を定め,以下の連立方程式を nlsolve() により解く。

include("julia-source.txt");

using SymPy

@syms r1::positive, r2::positive, r3::positive, r4::positive, r5::positive,
     x2::positive, x3::positive, x4::positive, x5::positive,
     鉤::positive, 股::positive, 弦::positive;

eq1 = 2(r2 + r3 + r4) * 2r1 + (鉤 + 股 + 弦)^2 - 46216
eq2 = 鉤 + 股 - 弦 - 2r1
eq3 = 鉤^2 + 股^2 - 弦^2
eq4 = 2(r1 - r5)^2 - (r1 + r5)^2
eq5 = r1 / (股 - r1) - r2 / (股 -x2)
eq6 = r1 / (股 - r1) - r3 / (股 -x3)
eq7 = r1 / (股 - r1) - r4 / (股 -x4)
eq8 = r1 / (股 - r1) - r5 / (股 -x5)
eq9 = (r1 - x2)^2 + (r1 - r2)^2 - (r1 + r2)^2
eq10 = (x2 - x3)^2 + (r2 - r3)^2 - (r2 + r3)^2
eq11 = (x3 - x4)^2 + (r3 - r4)^2 - (r3 + r4)^2
eq12 = (x4 - x5)^2 + (r4 - r5)^2 - (r4 + r5)^2;

# res = solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8, eq9])

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=1e-14)
       v = r.zero[1]
   else
       r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=1e-14)
       v = r.zero
   end
   return v, r.f_converged
end;

function H(u)
   (鉤, 股, 弦, r1, r2, r3, r4, r5, x2, x3, x4, x5) = u
   return [
       2*r1*(2*r2 + 2*r3 + 2*r4) + (弦 + 股 + 鉤)^2 - 46216,  # eq1
       -2*r1 - 弦 + 股 + 鉤,  # eq2
       -弦^2 + 股^2 + 鉤^2,  # eq3
       2*(r1 - r5)^2 - (r1 + r5)^2,  # eq4
       r1/(-r1 + 股) - r2/(-x2 + 股),  # eq5
       r1/(-r1 + 股) - r3/(-x3 + 股),  # eq6
       r1/(-r1 + 股) - r4/(-x4 + 股),  # eq7
       r1/(-r1 + 股) - r5/(-x5 + 股),  # eq8
       (r1 - r2)^2 - (r1 + r2)^2 + (r1 - x2)^2,  # eq9
       (r2 - r3)^2 - (r2 + r3)^2 + (x2 - x3)^2,  # eq10
       (r3 - r4)^2 - (r3 + r4)^2 + (x3 - x4)^2,  # eq11
       (r4 - r5)^2 - (r4 + r5)^2 + (x4 - x5)^2,  # eq12
      ]
end;

iniv = [big"39.0", 83, 91, 15, 10, 6, 4, 3, 39, 54, 63, 70]
res = nls(H, ini=iniv);

using Printf
names =  ("鉤", "股", "弦", "r1", "r2", "r3", "r4", "r5", "x2", "x3", "x4", "x5")
for (i, name) in enumerate(names)
   @printf("%s = %.6f\n", name, res[1][i])
end

   鉤 = 38.566769
   股 = 82.527544
   弦 = 91.094408
   r1 = 14.999953
   r2 = 9.653883
   r3 = 6.213184
   r4 = 3.998769
   r5 = 2.573585
   x2 = 39.067174
   x3 = 54.556700
   x4 = 64.525669
   x5 = 70.941641

using Plots

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (鉤, 股, 弦, r1, r2, r3, r4, r5, x2, x3, x4, x5) = res[1] 
   plot([0, 股, 0, 0], [0, 0, 鉤, 0], color=:black, lw=0.5)
   circle(r1, r1, r1)
   circle(x2, r2, r2, :blue)
   circle(x3, r3, r3, :green)
   circle(x4, r4, r4, :magenta)
   circle(x5, r5, r5, :brown)
   circle(r5, r5, r5, :brown)
   if more
       point(r1, r1, "大:r1\n(r1,r1)", :red)
       point(x2, r2, "天:r2\n(x2,r2)", :blue)
       point(x3, r3, "地:r3\n(x3,r3)", :green)
       point(x4, r4, "  人:r4,(x4,r4)\n", :magenta, :left, :bottom)
       point(x5, r5, "    小:r5,(x5,r5)", :brown, :left, :bottom)
       point(r5, r5, "小:r5,(r5,r5)", :brown, :left, :top)
       point(0, 鉤, " 鉤", :green, :left, :bottom)
       point(股, 0, " 股", :green, :left, :bottom)
       vline!([0], color=:black, lw=0.5)
       hline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

算額(その294)

2023年06月22日 | Julia

算額(その294)

中村信弥「算額への招待 追補2」
http://www.wasan.jp/syotai/syotai.html
長野県千曲市八幡 武水別神社(八幡神社) 天保8年(1837) 

大円内に互いに外接し大円に内接する 3 個の小円がある。3 個の小円の面積と,小円に囲まれる面積(水色)の和に小円の直径をかけた積に小円の直径の3倍の 3 乗を加えると 794050 立方寸になる。このとき,大円の直径を求めよ。

大円の半径を r0,小円の半径,中心座標を r1, (r1, y), (0, r1) として,以下の連立方程式を解く。

include("julia-source.txt");

using SymPy

@syms r0::positive, r1::positive, y::negative;
eq1 = r1^2 + (r0 - r1 - y)^2 - 4r1^2
eq2 = r1^2 + y^2 - (r0 - r1)^2
eq3 = (3PI*r1^2 + r1^2*sqrt(Sym(3)) - PI*r1^2/2)*2r1 + (6r1)^3 - 794050
res = solve([eq1, eq2, eq3], (r0, r1, y))

   1-element Vector{Tuple{Sym, Sym, Sym}}:
    (sqrt(3)*794050^(1/3)*((20*sqrt(3)*pi + 25*pi^2 + 864*sqrt(3) + 2160*pi + 46668)^(1/3)*(450*pi^2 + 125*sqrt(3)*pi^3 + 38880*pi + 16200*sqrt(3)*pi^2 + 839880 + 700020*sqrt(3)*pi + 10085472*sqrt(3)) + 2*(20*sqrt(3)*pi + 25*pi^2 + 864*sqrt(3) + 2160*pi + 46668)^(11/6))/(3*(20*sqrt(3)*pi + 25*pi^2 + 864*sqrt(3) + 2160*pi + 46668)^2), 794050^(1/3)*(2*sqrt(3) + 5*pi + 216)/(20*sqrt(3)*pi + 25*pi^2 + 864*sqrt(3) + 2160*pi + 46668)^(2/3), -794050^(1/3)/(540*sqrt(3)*pi + 675*pi^2 + 23328*sqrt(3) + 58320*pi + 1260036)^(1/6))

術では円周率を 3.162 として求めているが,pi の場合についても計算しておく。

f(pi0) = 2*(sqrt(3)*794050^(1/3)*((20*sqrt(3)*pi0 + 25*pi0^2 + 864*sqrt(3) + 2160*pi0 + 46668)^(1/3)*(450*pi0^2 + 125*sqrt(3)*pi0^3 + 38880*pi0 + 16200*sqrt(3)*pi0^2 + 839880 + 700020*sqrt(3)*pi0 + 10085472*sqrt(3)) + 2*(20*sqrt(3)*pi0 + 25*pi0^2 + 864*sqrt(3) + 2160*pi0 + 46668)^(11/6))/(3*(20*sqrt(3)*pi0 + 25*pi0^2 + 864*sqrt(3) + 2160*pi0 + 46668)^2))
f(3.162) |> println
f(pi) |> println

   64.64101362909618
   64.65036111699513

using Plots

function draw(more=false)
   pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
   (r0, r1, y) = res[1]
   plot([r1, 0, -r1, r1], [y, r0 - r1, y, y], linecolor=:red, linewidth=0.5, seriestype=:shape, fillcolor=:cyan)
   circle(0, 0, r0, :black)
   circlef(0, r0 - r1, r1)
   circlef(r1, y, r1)
   circlef(-r1, y, r1)
   if more
       point(r1, y, "(r1,y)", :yellow)
       point(0, r0 - r1, " r0-r1", :yellow)
       point(r0, 0, " r0")
       vline!([0], color=:black, lw=0.5)
       hline!([0], color=:black, lw=0.5)
   else
       plot!(showaxis=false)
   end
end;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村