hp 28s - creating nested lists
02-16-2015, 04:33 PM (This post was last modified: 02-16-2015 04:41 PM by mbrethen.)
Post: #1
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
hp 28s - creating nested lists
I need a program that will initialize a nested list filled with a value. For example:

Stack:
0
{3 4}

Output: {{0 0 0 0} {0 0 0 0} {0 0 0 0}}

Stack:
1
{2 3 4}

Output: {{{1 1 1 1} {1 1 1 1} {1 1 1 1}} {{1 1 1 1} {1 1 1 1} {1 1 1 1}}}

Is this possible? I've thought about it, but can't figure out how to accommodate the levels of nesting (i.e. multiple For/Next loops).
02-16-2015, 06:51 PM
Post: #2
 Christoph Giesselink Member Posts: 245 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 04:33 PM)mbrethen Wrote:  I need a program that will initialize a nested list filled with a value. For example:

Stack:
0
{3 4}

Output: {{0 0 0 0} {0 0 0 0} {0 0 0 0}}

Stack:
1
{2 3 4}

Output: {{{1 1 1 1} {1 1 1 1} {1 1 1 1}} {{1 1 1 1} {1 1 1 1} {1 1 1 1}}}

Following my first solution using SysRPL code for the inner loop. Be careful, using non or negative numbers inside the dimension list will crash your calculator with MEMORY LOST!

For secure testing use a HP28S emulator instead. You are warned!

Code:
 NLIST <<   WHILE DUP SIZE 0 >   REPEAT LIST->     IF DUP 0 >     THEN 1 - SWAP -> n       << ->LIST SWAP n       >> # C53Bh SYSEVAL # 3ACB5h SYSEVAL # 3EFFh SYSEVAL SWAP     END   END DROP >>

The SYSEVAL sequence is standing for COERCE NDUPN {}N.

This is a quick shot variant in pure UserRPL (for list elements > 0):

Code:
 NLIST <<   WHILE DUP SIZE 0 >   REPEAT LIST->     IF DUP 0 >     THEN 1 - SWAP -> n       << ->LIST SWAP n         WHILE 1 - DUP 0 >         REPEAT OVER SWAP         END DROP n ->LIST       >> SWAP     END   END DROP >>

Christoph
02-16-2015, 08:06 PM
Post: #3
 Thomas Klemm Senior Member Posts: 1,882 Joined: Dec 2013
RE: hp 28s - creating nested lists
Here's another solution that works with the HP-48:

Code:
\<<   REVLIST   WHILE DUP SIZE   REPEAT DUP TAIL     SWAP HEAD     ROT 1 \->LIST     { } ROT     1 SWAP START       OVER +     NEXT     SWAP DROP SWAP   END DROP \>>

But maybe you can still use the idea for the HP-28.
Since it's not possible to append a list as an element to another list I had to wrap it into a list: 1 \->LIST

Cheers
Thomas
02-16-2015, 08:35 PM
Post: #4
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 06:51 PM)Christoph Giesselink Wrote:  Following my first solution using SysRPL code for the inner loop. Be careful, using non or negative numbers inside the dimension list will crash your calculator with MEMORY LOST!

<snip>

Christoph

Is there an advantage to using the SYSEVAL sequence? To be safe, one could check for zero or negative numbers and abort.

Thanks.
02-16-2015, 08:40 PM
Post: #5
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 08:06 PM)Thomas Klemm Wrote:  <snip>
But maybe you can still use the idea for the HP-28.
Since it's not possible to append a list as an element to another list I had to wrap it into a list: 1 \->LIST

Cheers
Thomas

I don't recognize "TAIL" or "HEAD" commands, they must not be supported on its predecessor?
02-16-2015, 09:38 PM
Post: #6
 Thomas Klemm Senior Member Posts: 1,882 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 08:40 PM)mbrethen Wrote:  they must not be supported on its predecessor?

It appears that only the following LIST operations were supported:
Code:
\->LIST LIST\-> PUT GET PUTI GETI POS SUB SIZE

HEAD and TAIL are basically the same as CAR and CDR in Lisp.

When I compare my program to Christoph's 2nd solution I notice that they do essentially the same:
• get the last element of the control-list
• create a new list by adding the previous result n times

He uses LIST\-> to access the last element and then recreates the list with \->LIST while I use HEAD to get the 1st element. That's why I had to reverse the list in the first step.
Then he DUPs the previous result n times which is once too much. That's why he has to DROP the last one. In my program the previous result is added repeatedly to an ever growing list that started with an empty list {}.

Not sure about that but the statements 0 > could probably be omitted in his program as well. Furthermore I assume that his solution is faster than mine on a HP-48 as list-operations are rather slow. As I wasn't sure whether local variables were already supported I avoided their usage.

Kind regards
Thomas
02-16-2015, 10:35 PM (This post was last modified: 02-16-2015 10:41 PM by mbrethen.)
Post: #7
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 09:38 PM)Thomas Klemm Wrote:  <snip>
As I wasn't sure whether local variables were already supported I avoided their usage.

Kind regards
Thomas

Local variables are supported.

Assuming 'a' is the list; 'a SIZE -> s'; 'a 1 GET' (HEAD) and 'a s GET' (TAIL).
02-16-2015, 10:57 PM
Post: #8
 Thomas Klemm Senior Member Posts: 1,882 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 10:35 PM)mbrethen Wrote:  'a s GET' (TAIL).
Not exactly: TAIL is the list without its HEAD and not only the last element.
02-16-2015, 11:24 PM
Post: #9
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 10:57 PM)Thomas Klemm Wrote:  Not exactly: TAIL is the list without its HEAD and not only the last element.

Then I need 'SUB' which returns elements n1 through n2 of the original list.

Example: {2 3 4}

'2 3 SUB' returns {3 4}
02-17-2015, 07:56 AM
Post: #10
 Thomas Klemm Senior Member Posts: 1,882 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-16-2015 11:24 PM)mbrethen Wrote:  Then I need 'SUB'

Correct.

You could also use a mix of both programs to avoid HEAD and TAIL:
Code:
\<<   WHILE DUP SIZE   REPEAT     LIST\-> 1 -     SWAP \-> n     \<<       \->LIST SWAP       1 \->LIST { }       1 n START         OVER +       NEXT     \>>     SWAP DROP SWAP   END DROP \>>

Cheers
Thomas
02-17-2015, 10:35 AM
Post: #11
 Werner Senior Member Posts: 832 Joined: Dec 2013
RE: hp 28s - creating nested lists
Somewhat simpler:
Code:
\<<   LIST\-> DUP 2. + ROLL   1. ROT START     OVER 1. SWAP START SWAP OVER NEXT     DROP \->LIST   NEXT \>>

Cheers, Werner

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L
02-17-2015, 02:31 PM
Post: #12
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-17-2015 10:35 AM)Werner Wrote:  Somewhat simpler:
<snip>

Thanks, Werner.

Its simple, but I will have to study this one to understand how it works
02-17-2015, 07:55 PM
Post: #13
 Christoph Giesselink Member Posts: 245 Joined: Dec 2013
RE: hp 28s - creating nested lists
Hi Thomas, Hi Werner,

this reminds me to the late 80'ies and early 90'ies where a colleague and I optimized first our HP28S and later our HP48SX UserRPL programs from week to week: "Do you know that I was able to save another 2.5 bytes in the program ...". A time we don't know why a "normal" RPL command takes exact 2.5 bytes and further information was ~4000 miles away from Germany or costs ~6 D-Mark per minute for calling a BBS in the US.

A time we were glad for every new SYSEVAL address, especially for the one reading the internal 8192Hz counter content to write a clock program for the HP28S. The good old times... ;-)

Quote:Is there an advantage to using the SYSEVAL sequence?

I wanted to use the NDUPN secondary, which is only available on SysRPL level, to simplify the inner loop. The commmand duplicates the object at stack level2 n times and leave the n times no. at stack level1. In general the execution of a SysRPL object is faster than the equivalent UserRPL object, in our case maybe only for large numbers because of the additional time for decoding the SYSEVAL.

Christoph
02-17-2015, 09:23 PM
Post: #14
 Thomas Klemm Senior Member Posts: 1,882 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-17-2015 02:31 PM)mbrethen Wrote:  I will have to study this one to understand how it works

May I recommend to use the debugger to single-step through the program? Cf. HP-28S Owner's Manual pp. 250.

Cheers
Thomas
02-18-2015, 10:30 AM
Post: #15
 Werner Senior Member Posts: 832 Joined: Dec 2013
RE: hp 28s - creating nested lists
If you have NDUPN at your disposal, it can be further simplified to:
Code:
\<<   LIST\->   DUP 2. + ROLL   1. ROT START     SWAP NDUPN \->LIST   NEXT \>>

For NDUPN, take any of the following:

Code:
NDUPN \<< SWAP OVER 1. SWAP START SWAP OVER NEXT DROP \>> \<< \-> N \<< 1. N START DUP NEXT DROP N \>> \>> \<<   -> n   \<<     1 2 n     FOR i       DUPN i DUP     STEP     n - DUP 0 <     { NEG DUPN }     { DROPN }     IFTE     n   \>> \>>
The last one outperforms even the builtin SYSEVAL for large N

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L
02-18-2015, 06:06 PM
Post: #16
 Christoph Giesselink Member Posts: 245 Joined: Dec 2013
RE: hp 28s - creating nested lists
For those who don't know how the original NDUPN code looks like, this is the code of the HP28S (the HP28C source code, not byte code is equal):
Code:
3ACB5 =NDUPN 3ACB5 76C20  :: 3ACBA A4020    DUP 3ACBF 71E60    #0= 3ACC4 F5CD3    case 3ACC9 C16D3    SWAPDROP 3ACCE A4020    DUP 3ACD3 F7F60    #1- 3ACD8 A4020    DUP 3ACDD 71E60    #0= 3ACE2 F5CD3    case 3ACE7 60120    DROP 3ACEC 9A170    ZERO 3ACF1 8C850    DO 3ACF6 48120    OVER 3ACFB 5E020    SWAP 3AD00 50850    LOOP 3AD05 09F20  ;

A special feature is the valid 0 argument for N.

Christoph
02-19-2015, 12:13 AM
Post: #17
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
Let me see if I understand this.
Code:
# C53Bh SYSEVAL # 3ACB5h SYSEVAL # 3EFFh SYSEVAL

equivalent to:
Code:
\<< SWAP OVER 1. SWAP START SWAP OVER NEXT DROP \>>

equivalent to:
Code:
\<< \-> N \<< 1. N START DUP NEXT DROP N \>> \>>

equivalent to:
Code:
\<<   -> n   \<<     1 2 n     FOR i       DUPN i DUP     STEP     n - DUP 0 <     { NEG DUPN }     { DROPN }     IFTE     n   \>> \>>

Correct?
02-19-2015, 08:19 AM
Post: #18
 Werner Senior Member Posts: 832 Joined: Dec 2013
RE: hp 28s - creating nested lists
Not quite ;-)
Only my last code is 100% correct as it works for N=0.
The other two should be:
Code:
NDUPN \<< 0. OVER START OVER SWAP NEXT ROT ROT DROP2 \>>
and
Code:
NDUPN \<< \-> N \<< 0. N START DUP NEXT DROP2 N \>> \>>

Cheers, Werner

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L
02-19-2015, 08:53 PM
Post: #19
 Christoph Giesselink Member Posts: 245 Joined: Dec 2013
RE: hp 28s - creating nested lists
(02-19-2015 12:13 AM)mbrethen Wrote:  Let me see if I understand this.
Code:
# C53Bh SYSEVAL # 3ACB5h SYSEVAL # 3EFFh SYSEVAL

equivalent to:
Code:
\<< SWAP OVER 1. SWAP START SWAP OVER NEXT DROP \>>

...

No, this isn't equal.

Code:
#  C53Bh SYSEVAL = COERCE # 3ACB5h SYSEVAL = NDUPN #  3EFFh SYSEVAL = {}N

Stack diagrams from RPLMAN.DOC:
Code:
COERCE          ( % --> # ) NDUPN           ( ob #n --> ob ... ob #n ) {}N             ( obn ... ob1 #n --> {list} )

simply duplicates the object n-times and put the objects into a list object.

As entry into the SysRPL world you may begin reading the RPLMAN.DOC document, available as separate file or as part of the orginal HPTOOLS package.
02-20-2015, 02:16 AM (This post was last modified: 02-20-2015 03:26 AM by mbrethen.)
Post: #20
 mbrethen Junior Member Posts: 40 Joined: Dec 2013
RE: hp 28s - creating nested lists
Werner,

This code has errors:
Code:
NDUPN \<<   -> n   \<<     1 2 n     FOR i       DUPN i DUP     STEP     n - DUP 0 <     { NEG DUPN }     { DROPN }     IFTE     n   \>> \>>

Initially the error traces back to the FOR statement, so I removed the '2'. Then it gives an error on DUPN. I gave up at this point.

This does work:
Code:
NDUPN \<< 0. OVER START OVER SWAP NEXT ROT ROT DROP2 \>>
But why create a separate program when your original code works? What is the advantage (other than calling it from multiple programs)?
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)