HP42s first major program (Double Integral) Best way to approach?
|
06-02-2020, 08:31 AM
Post: #41
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Question: wouldn't the formula need to be
bore hole volume = hv(b,c) - hv(max(a,c),min(a,c)) so that it would work for a<c as well? Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
06-02-2020, 04:02 PM
Post: #42
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
(06-02-2020 08:23 AM)Werner Wrote: Continuous improvement.. when I rewrite agm as ... My version tried to avoid last sqrt(), but your version had last sqrt() evaluated. You might as well return that instead of arithmetic mean. function agm2(a, b) local t = -1 local s1 = a*a repeat local s = s1 local k = (b-a)/2 t = t + t b = sqrt(a*b) a = a + k s1 = s + t*k*k until s == s1 return b, s1 end (06-02-2020 08:31 AM)Werner Wrote: Question: wouldn't the formula need to be Same reasoning goes for b<c A simple fix is to sort the hv arguments, such that hv(a,c) = hv(c,a) |
|||
06-02-2020, 05:01 PM
Post: #43
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
okay, final update then:
will now work when b<c and/or a<c, as well; and a few more optimisations. Code: 00 { 185-Byte Prgm } Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
06-02-2020, 07:12 PM
Post: #44
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
When a = 48, b = 58, and c = 48
BORE (Integration) Answer = (one side) 10,613 * 2 => (both sides) 21,226.76 units^3 BORE (Werners final program) I get a Divde by 0 error on Line 59. Shouldn't this only return an error (non-real result) when c > a? HP48GX, HP42s and DM42. |
|||
06-02-2020, 07:47 PM
Post: #45
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
48 is not RPN. Try again.
SCNR... Greetings, Massimo -+×÷ ↔ left is right and right is wrong |
|||
06-02-2020, 08:02 PM
Post: #46
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Hi, DM48
HV(c,c) involve calculating K(1) = ∞, thus Divide by 0 error. The fix required another rule: HV(c,c) = 2/3*c^3 For a=48, b=58, c=48: HV(58,48) ≈ 94954.7588409 HV(48,48) = 2/3*48^3 = 73728 Difference ≈ 21226.7588409 |
|||
06-03-2020, 05:31 AM
Post: #47
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Easy fix
Code: 00 { 197-Byte Prgm } Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
06-03-2020, 01:05 PM
Post: #48
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
(06-03-2020 05:31 AM)Werner Wrote: Easy fix Werner, testing the fix, it does work at c = 48. Since I only need half the volume, I use to slide in a 2 / after line 43 in this program. That returns a large negative result. Do you have a suggestion where I should place 2 / so it performs the division on the final result? HP48GX, HP42s and DM42. |
|||
06-03-2020, 02:55 PM
Post: #49
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Yes, between lines 13 and 14.
Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
06-03-2020, 06:45 PM
(This post was last modified: 06-06-2020 11:30 AM by Albert Chan.)
Post: #50
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Hi, Werner
I made some improvements to BORE program ... Code: 00 { 176-Byte Prgm } First, I followed Mathematica EllipticE, EllipticK, using parameter m instead of modulus k, m = k^2 With this change, for ellipse_perimeter(10,50), a = 50, e^2 = 1-0.2^2 = 0.96 0.96 XEQ "EK" 200 × → 210.100445397 We can do the same calculation with a = 10, e^2 = 1-5^2 = -24 (previous version can do this too, but with imaginary e) -24 XEQ "EK" 40 × → 210.100445397 I noticed K(m) is relatively slow growing, when m approach 1. Example: K(m = 1 - 1e-85) ≈ 99 Instead of adding the rule HV(c,c) = 2/3*c^3, I do E(1)=1, K(1)=99 (see LBL 00) This kill 2 birds with 1 stone I also removed the menu, with "BORE" getting a,b,c, directly from the stack. To avoid catastrophic cancellation problems without knowing it, I leave HV values on the stack. 48 Enter 58 Enter 48 XEQ "BORE" → Y=94954.7588409, X=73728 − → I=21226.7588409 This allowed removal of HV label: Example, for HV(29,12) 29 Enter 12 Enter XEQ "BORE" → 3208.03490414 I also removed the assumption SIGN giving 1, and add 1 explicitly. This allowed the code to run correctly with complex numbers. 3 XEQ "EK" → E ≈ 0.47522 + 1.0130j, K ≈ 1.0011 - 1.1714j -1 SQRT XEQ "EK" → E ≈ 1.6324 - 0.36922j, K ≈ 1.4213 + 0.29538j There is still an issue of AGM convergence. For complex numbers, AGM might not converge *exactly*. For example, on Free42, 2 XEQ "EK" crash with "Out-of-Range" |
|||
06-04-2020, 02:00 PM
Post: #51
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Just one more thing:
EK has to test for input 1 and (1,0), so it has to be (never mind the step numbers): Code: 42▸LBL "EK" I added my start of AGM as well, shorter, and works for B=0 Cheers, Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
06-04-2020, 05:07 PM
Post: #52
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Are these lines meant to replace lines 38 - 67 of Albert's code?
(06-04-2020 02:00 PM)Werner Wrote: Just one more thing: HP48GX, HP42s and DM42. |
|||
06-04-2020, 07:06 PM
(This post was last modified: 06-09-2020 01:25 PM by Albert Chan.)
Post: #53
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Hi, Werner
I added your suggested changes. Thanks. (06-03-2020 06:45 PM)Albert Chan Wrote: There is still an issue of AGM convergence. For EK(2), this involved calculating: b = sqrt(1-m) = 1j x1, y1 = agm2(1+b, 2*sqrt(b)) = agm2(1+1j, sqrt(2)*(1+1j)) We can scale away 1+1j, and get x1,y1, like this: x2, y2 = agm2(1, sqrt(2)) ≈ (1.1981, 0.91389) x1 = (1+1j) * x2 ≈ 1.1981 + 1.1981j y1 = (1+1j)**2 * y2 = 2j * y2 ≈ 1.8278j → K(2) = pi / x1 ≈ 1.3110 - 1.3110j → E(2) = K(2) * y1/4 ≈ 0.59907 + 0.59907j We have y1 as purely imaginary complex number. However, with rounding errors, directly go for y1 might have tiny real part. Since we test for ACC equality, going directly for y1 might not work. This is my idea ... by going up the agm2 chain. x0, y0 = agm2(1,b), b ≠ 0 x0 = agm(1,b) = agm((1+b)/2, sqrt(b)) = x1 / 2 y1 = (1+b)^2 - 2*((1+b)/2 - sqrt(b))^2 - 4*gap2^2 - 8*gap3^2 - ... 2 y0 = 2*1^2 - (1-b)^2 - 2*((1+b)/2 - sqrt(b))^2 - 4*gap2^2 - 8*gap3^2 - ... → y1 - 2 y0 = (1+b)^2 - 2 + (1-b)^2 = 2 b^2 → y1 = 2*(y0 + b^2) x0, y0 = agm2(1, 1j) ≈ (0.59907 + 0.59907j, 1.0000 + 0.91389j) → K(2) = pi / (2*x0) ≈ 1.3110 - 1.3110j → E(2) = K(2) * (y0 + b^2)/2 ≈ 0.59907 + 0.59907j This is my new version, getting EK(m) using AGM(1,b), b = sqrt(1-m) Code: 00 { 181-Byte Prgm } 2 XEQ "EK" → E ≈ 0.59907 + 0.59907i, K ≈ 1.3110 - 1.3110i Update: replace EK(m = (d/D)^2) as EK(m = d^2/D^2) Possibly more accurate m, and saved 1 byte of code. |
|||
06-06-2020, 08:33 PM
(This post was last modified: 06-08-2020 05:41 PM by Albert Chan.)
Post: #54
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
(06-02-2020 08:31 AM)Werner Wrote: Question: wouldn't the formula need to be Amazingly, the answer is NO ! Example: a, b, c = 48, 58, 68 The drill bit is bigger than the pipe, and will cut it off. 48 Enter 58 Enter 68 XEQ "BORE" → HV(c,b) = 161316.6882015429652660165715495419 → HV(c,a) = 114811.9333705716751263443462068749 Difference = 46504.754830971290139672225342667 My latest code update should handle complex numbers. Now, remove the HV arguments sorting steps 14, 15, and redo above example → HV(c,b) = 161316.688201542965266016571549542 + 4944.10953174134265265013475228068i → HV(c,a) = 114811.9333705716751263443462068748 + 18153.27669892468194546755520844514i Difference = 46504.7548309712901396722253426672 - 13209.16716718333929281742045616446i The real part returns the same volume ! Bonus: imaginery part warned the user that pipe is cut off |
|||
06-08-2020, 12:11 AM
(This post was last modified: 06-23-2020 12:20 PM by Albert Chan.)
Post: #55
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
This version uses my implementation of EKmc(m) = E(m) - c, K(m) - c, where c = Pi/2
I added HV(d,D) on top of EKmc(m) to test its accuracy. HV(d, D) = D/3 (d^2 (E+K) + D^2 (E-K)) = D/3 (d^2 ((E-c)+(K-c) + Pi) + D^2 ((E-c)-(K-c))) Note: this is a recursive algorithm, requiring Free42 LSTO command. Code: 00 { 167-Byte Prgm } Let's try HV(1,1000): HV(1,1000) = 785.3980652226656130844841050849260, error = -2 ULP BORE = 785.3980652226656130844841051786603, error = -937345 ULP Mathemtaica: 785.3980652226656130844841050849257781988463583655713086050... * Mathematica: HV = Pi/4 d^2 D Hypergeometric2F1[-1/2,1/2,2,(d/D)^2] /. {d->1, D->1000} Update: HV now has same functionality of BORE, and better accuracy. Formula changed to avoid subtraction cancellation, when m = (d/D)² ≈ 1 HV(d, D) = D/3*((dd+DD)*(e-c) + (dd-DD)*(k-c) + dd*(2c)) → HV1(m) = 1/3*((m+1)*(e-c) + (m-1)*(k-c) + m*pi) First 2 terms both negative, with -sum less than 1/2 of the third. We know this because 2/3 ≤ HV1/m ≤ pi/4, and (third term)/m = pi/3 → (third term)/HV1 = [4/3, pi/2] ≈ [1.3333, 1.5708] → -(sum of first 2 terms)/(third term) ≈ [0.25000, 0.36338] |
|||
06-08-2020, 03:35 PM
Post: #56
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Here is EKmc() non-recursive Python code.
Note: code preceded by "from math import sqrt, pi", for complex number support, use cmath. Code: def EKmc(m, verbal=False, c=pi/2): Try HV(1,1000) again. With d=1, we can simplify the HV formula. >>> D = 1000 >>> e, k = EKmc(1/(D*D), verbal=True) m = 2.44141113282e-28 E(m)-c = -9.58739909907e-29 K(m)-c = 9.58739909907e-29 m = 6.25000625001e-14 E(m)-c = -2.45437171499e-14 K(m)-c = 2.45437171499e-14 >>> e, k # m = 1e-6 (-3.9269915532983253e-07, 3.9269930259211089e-07) >>> D/3 * ((e+k) + D*D*(e-k) + pi) # = HV(1,D) 785.39806522266554 EKmc has the speed of AGM2 method, but avoided catastrophic cancellation issue. It also avoided AGM2 (complex number) convergence issue. With K(m), we can recover AGM's: AGM(1, b) * K(1-b*b) = pi/2 |
|||
06-09-2020, 12:18 AM
Post: #57
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Impressive Albert. I'll be chewing through this for a while. I need to get my programming skills up to speed.
HP48GX, HP42s and DM42. |
|||
06-13-2020, 10:16 PM
(This post was last modified: 06-14-2020 10:20 PM by Albert Chan.)
Post: #58
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
Inspired by Werner's AGM code thread, I fixed my AGM2 convergence issue.
It now test convergence of sucessive GM's, eliminated convergence issue of AGM(x,0). Test for EK(m) for abs(m-1)=0 is now shifted to test returns of AGM2. To simplify further , I make this version dimensionless, m = (d/D)^2 → HV(d,D) = HV1(m) * D³ Code: 00 { 128-Byte Prgm } |
|||
06-15-2020, 12:25 AM
Post: #59
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
(05-27-2020 08:27 PM)DM48 Wrote: I am looking to make this the fastest calculation possible with at least five, preferably six decimals. Previous post HV1(m), if you plot it (m = 0 to 1), it look like a straight line, HV1 ≈ 2/3*m Using a trick I learned earlier, for asinc(x), using Mathematica: In[1]:= <<Calculus`Pade` In[2]:= hv1[m_] := ((m+1) EllipticE[m] + (m-1) EllipticK[m]) / 3 In[3]:= EconomizedRationalApproximation[hv1[m]/m, {m,{0,0.75},2,2}] Results coded in Lua, for m ≤ 0.7, this get about 6 digits accuracy. Code: function hv1(m) Adding back dimensions to test the result: lua> function hv(d,D) return D^3 * hv1((d/D)^2) end lua> v2 = hv(24, 58) lua> v1 = hv(24, 48) lua> print(v2, v1, v2-v1) 25664.275659138966 21013.02544172724 4651.250217411725 For reference, this is EKmc HV version Free42: 48 Enter 58 Enter 24 XEQ "HV" - 25664.27923311925502790987133042097 − 21013.03279650214793028432717211253 = 4651.24643661710709762554415830844 |
|||
06-19-2020, 01:01 AM
Post: #60
|
|||
|
|||
RE: HP42s first major program (Double Integral) Best way to approach?
In Werner's program below, is there anyway to make LBL "FX" into a local label? I keep trying to turn FX into 11 but this gives an error.
My goal is not to see FX in the list of programs, make BORE self contained if you will. I assume this has to do with the XEQ or PGMINT call? (05-28-2020 07:28 AM)Werner Wrote: Or you could use this, and use it interactively: HP48GX, HP42s and DM42. |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 10 Guest(s)