Programming Challenge: a classic trigonometry problem
|
03-20-2023, 02:25 AM
(This post was last modified: 03-21-2023 09:19 PM by Albert Chan.)
Post: #40
|
|||
|
|||
RE: Programming Challenge: a classic trigonometry problem
We could solve for s = (v/c), then v = c*s, then y = b^2 - v^2
c/u + c/v = c/c ±1/√(k+s²) + 1/s = 1 // ± to cover extend-line crossed solution ±s/√(k+s²) + 1 = s // scaled to make it more linear |s-1| - s/√(k+s²) = 0 // formula V shaped, very straight for s≥1 (*) This setup does not have secant's root overshoot problem. It will not be hit with square root of negative number. q ≤ -1 → s = (v/c) = (1+1/q) = 0 .. 1 q ≥ 1 → s = (v/c) = (1+1/q) = 1 .. 2 We can simply use guess [1±0.3, 1±0.7], instead of [(1-c/±a)^-1, (1+b/±a)] Formula is concave up (2nd derivative > 0), it will not accidentally solve the "wrong" root. CAS> factor(diff(abs(s-1) - s/sqrt(k+s*s), s, 2)) → \(\displaystyle \frac{3\,k\,s}{(k+s^2)^{5 \over 2}}\) (**) lua> a,b,c = 40,30,15 lua> k = (a+b)*(a-b)/(c*c) lua> S1 = fn's: abs(s-1) - s/sqrt(k+s*s)' lua> eps = -1e-9 -- swap worse point as first lua> S = require'solver' lua> S.secant(S1, 1.3, 1.7, eps, true) 1.3 1.7 1.6919260149527686 1.692328847882308 1.692329202531022 1.6923292025145777 1.6923292025145775 lua> v = c * _ lua> y = (b+v) * (b-v) lua> y, sqrt(y) -- ladders crossed width 255.6049208211842 15.98764900856859 lua> S.secant(S1, 0.3, 0.7, eps, true) 0.3 0.7 0.6541746293109201 0.6528669490148099 0.6528724368426823 0.6528724362121412 0.6528724362121409 lua> v = c * _ lua> y = (b+v) * (b-v) lua> y, sqrt(y) -- extended line crossed width 804.0954559577455 28.356576943590095 (*) s ≤ 1 side is not as straight, especially around s ≈ 0. To reduce iterations, for s < 1 root with tiny k, use 3 point quadratic fit solver. (**) there is a discontinuity at s=1. It should have another term, +abs(s-1)'' For our purpose of checking concave behavior, this subtlety can be ignored. (03-17-2023 03:12 PM)Albert Chan Wrote: lua> R = fn'r,s: s=r/(1+r); r*s - k/(r+s)' I named s = (v/c) because I had used it previously, solving for r = -(1+q) s = r/(1+r) = -(1+q)/(-q) = 1+1/q = (v/c) We can rephrase R of r, in terms of s instead. R guesses = cbrt(k/2) .. sqrt(k+1), can be carried over. lua> S2 = fn's,r: r=s/(1-s); r*s - k/(r+s)' S2 can accidentally shoot to "wrong" root, thus not recommended. Unless with good guesses ... but S1 can use them too! |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 1 Guest(s)