Closure in RPL
|
11-19-2022, 10:29 AM
Post: #1
|
|||
|
|||
Closure in RPL
I can create the following program for the HP-48G:
Code: \<< \-> a 5 MKADDR It returns: Code: \<< \-> b However when I try to use this with 8: 2: 8 1: \<< \-> b \<< a b + \>> \>> EVAL I get the following: Error: Undefined Local Name This comes at no surprise as apparently the code object hasn't been closed over the local variable a as I had hoped. Otherwise the result would have been: Code: \<< \-> b Which then would lead to: 2: 8 1: \<< \-> b \<< 5 b + \>> \>> EVAL 1: 13 For those familiar with JavaScript, I'm trying to do something similar to: Code: const mkaddr = (a) => (b) => a + b I came up with a solution using the code of the closure in strings that are concatenated with the local variable a. But I consider that an ugly hack. Are there better ways to do that in UserRPL? Or then maybe in SysRPL? |
|||
11-19-2022, 01:42 PM
Post: #2
|
|||
|
|||
RE: Closure in RPL
This may be a situation where using an algebraic makes sense. Placing 5 on the stack, then running the following:
Code: \<< \-> a There's other approaches, of course, that simply depend on your workflow. It's a bit unclear to me what the sequence of operations would be for your data entry with something like you've described. You could, for example, prompt for data entry using something like INPUT if you want it to be more interactive, or simply place the variables on the stack before running the program. If the latter is desired, simply place b and a (in that order) on the stack, then run your original program with an EVAL inserted strategically: Code: \<< \-> a The gist of it is that, in your original code, local 'a' becomes out-of-scope as soon as that penultimate \>> is encountered. This happens when you first run the program, so any subsequent reference to 'a' is invalid. |
|||
11-19-2022, 04:31 PM
(This post was last modified: 11-19-2022 04:35 PM by Thomas Klemm.)
Post: #3
|
|||
|
|||
RE: Closure in RPL
I was goofing around with a filter I could use with DOSUBS to remove all multiples of a number n.
So I tried to write a program that creates it based on that number as input. Since that didn't work, I moved this part into a program that does it: Code: \<< \-> p n Let's say we call this program SIEVE. Then we start with a list of numbers: K ENTER ENTER 2 887 1 SEQ { 2 3 4 5 6 7 8 9 10 … 887 } Now we can remove all multiples of primes with: 2 SIEVE { 2 3 5 7 9 11 13 15 17 … 887 } 3 SIEVE { 2 3 5 7 11 13 17 19 23 … 887 } 5 SIEVE { 2 3 5 7 11 13 17 19 23 … 887 } Just continue with the next prime in the list. … We can stop at \(31\) since \(31^2 > 887\). 31 SIEVE { 2 3 5 7 11 13 17 19 23 … 887 } This list of primes can then be reversed and transformed into an array: [ 887 883 881 877 … 7 5 3 2 ] It is the input for the following program: Code: \<< PROOT OBJ\-> OBJ\-> DROP \->LIST .806513599261 Thanks for your reply and your suggestions. As you can see I could still solve the problem. I was just wondering if maybe I missed an obvious solution. |
|||
11-19-2022, 08:53 PM
(This post was last modified: 11-19-2022 08:54 PM by John Keith.)
Post: #4
|
|||
|
|||
RE: Closure in RPL
Maybe I'm missing something, but wouldn't something like this be simpler for SIEVE?
Code:
|
|||
11-19-2022, 09:50 PM
Post: #5
|
|||
|
|||
RE: Closure in RPL
Since the object of your program was to solve Valentin's ROOT challenge, here is a version of the complete program for the 50g with ListExt and LSORT.
Code:
Takes 635 seconds on my 50g. My apologies for hijacking your thread, your original question about closure is interesting to me as well. |
|||
11-20-2022, 02:29 AM
Post: #6
|
|||
|
|||
RE: Closure in RPL
(11-19-2022 08:53 PM)John Keith Wrote: Maybe I'm missing something, but wouldn't something like this be simpler for SIEVE? What exactly do you consider simpler?
From my perspective both programs are on about the same level of complexity. First I was a bit puzzled by your program as it uses p instead of n for the number while I used p for the list of primes. (11-19-2022 09:50 PM)John Keith Wrote: Takes 635 seconds on my 50g. The 2nd part (i.e. after the list of prime numbers is created) takes maybe 2-3 seconds with an emulator on a slightly outdated smartphone. We've come a long way … (11-19-2022 09:50 PM)John Keith Wrote: My apologies for hijacking your thread No worries, I do this all the time. (11-19-2022 09:50 PM)John Keith Wrote: Couldn't we use AXL instead? (11-19-2022 09:50 PM)John Keith Wrote: Doesn't ABS work on a list with an HP-50g? (11-19-2022 09:50 PM)John Keith Wrote: Using MAX on a list is \(\mathcal{O}(n)\) while LSORT is probably \(\mathcal{O}(n\log{}n)\). But I don't think it matters in this case. |
|||
11-20-2022, 06:48 PM
Post: #7
|
|||
|
|||
RE: Closure in RPL
A few explanatory notes for my programs:
Either DOLIST and DOSUBS will work in this case, and I probably should have used DOSUBS since it is usually a bit faster than DOLIST. SAME is faster than ==. AXL creates a symbolic array. I guessed that a symbolic array would be slower for PROOT but I did not actually test it. All arithmetic functions are listable on the 50g but using the ListExt function LMAP is faster in almost all cases. LSORT is incredibly fast, and LSORT HEAD is significantly faster than STREAM. I am aware that emulators are much faster than physical calculators but I posted the timing for the physical calculator for comparison, since emulator speed is dependent on which emulator is used and what system it runs on. |
|||
11-20-2022, 08:18 PM
Post: #8
|
|||
|
|||
RE: Closure in RPL
Thank you for your explanations.
I can always learn something from you all. |
|||
11-20-2022, 09:11 PM
Post: #9
|
|||
|
|||
RE: Closure in RPL
(11-20-2022 02:29 AM)Thomas Klemm Wrote: Using MAX on a list is \(\mathcal{O}(n)\) while LSORT is probably \(\mathcal{O}(n\log{}n)\). I think the bottleneck is PROOT. What is its time complexity? For example, below trick will reduce primes needed. How much time will it save? Primes grow slower than any geometric series. Asymptotically, pn ≈ n*ln(n) Let M = minimum absolute root function M(2+3x+5x^2+...+887*x^153) ≈ M((2+3x+5x^2+...+683*x^123) + 683*x^124/(1-x)) Last term assumed primes stop growing after p124 = 683, thus the factor 1/(1-x) Multiply by (1-x), we have another polynomial that contains the same min abs root, but with less terms. 2 + (3-2)*x + (5-3)*x^2 + (7-5)*x^3 + ... + (683-677)*x^123 |
|||
11-20-2022, 10:51 PM
Post: #10
|
|||
|
|||
RE: Closure in RPL
I get the following:
.806513599262 And it takes about the same time: 2-3 seconds. |
|||
11-22-2022, 10:41 AM
Post: #11
|
|||
|
|||
RE: Closure in RPL
My mistake. It take 125 primes to reach 12 digits accuracy.
XCas> M(n) := Mp(makelist(ithprime,n+1,1,-1)); XCas> Mp(p) := min(abs(proot(p-p[1:]))); // n-degree prime-gap polynomial min abs root XCas> M(20) → 0.809455733629 XCas> M(30) → 0.807108146818 XCas> M(40) → 0.806549211933 XCas> M(50) → 0.806513445127 XCas> M(123) → 0.806513599262 XCas> M(124) → 0.806513599261 XCas> M(125) → 0.806513599261 XCas> M(126) → 0.806513599261 |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 6 Guest(s)