Post Reply 
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
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).
Find all posts by this user
Quote this message in a reply
02-16-2015, 06:51 PM
Post: #2
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
Visit this user's website Find all posts by this user
Quote this message in a reply
02-16-2015, 08:06 PM
Post: #3
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
Find all posts by this user
Quote this message in a reply
02-16-2015, 08:35 PM
Post: #4
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.
Find all posts by this user
Quote this message in a reply
02-16-2015, 08:40 PM
Post: #5
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?
Find all posts by this user
Quote this message in a reply
02-16-2015, 09:38 PM
Post: #6
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
Find all posts by this user
Quote this message in a reply
02-16-2015, 10:35 PM (This post was last modified: 02-16-2015 10:41 PM by mbrethen.)
Post: #7
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).
Find all posts by this user
Quote this message in a reply
02-16-2015, 10:57 PM
Post: #8
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.
Find all posts by this user
Quote this message in a reply
02-16-2015, 11:24 PM
Post: #9
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}
Find all posts by this user
Quote this message in a reply
02-17-2015, 07:56 AM
Post: #10
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
Find all posts by this user
Quote this message in a reply
02-17-2015, 10:35 AM
Post: #11
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
Find all posts by this user
Quote this message in a reply
02-17-2015, 02:31 PM
Post: #12
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 Wink
Find all posts by this user
Quote this message in a reply
02-17-2015, 07:55 PM
Post: #13
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
Visit this user's website Find all posts by this user
Quote this message in a reply
02-17-2015, 09:23 PM
Post: #14
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 Wink

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

Cheers
Thomas
Find all posts by this user
Quote this message in a reply
02-18-2015, 10:30 AM
Post: #15
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
Find all posts by this user
Quote this message in a reply
02-18-2015, 06:06 PM
Post: #16
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
Visit this user's website Find all posts by this user
Quote this message in a reply
02-19-2015, 12:13 AM
Post: #17
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?
Find all posts by this user
Quote this message in a reply
02-19-2015, 08:19 AM
Post: #18
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
Find all posts by this user
Quote this message in a reply
02-19-2015, 08:53 PM
Post: #19
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.
Visit this user's website Find all posts by this user
Quote this message in a reply
02-20-2015, 02:16 AM (This post was last modified: 02-20-2015 03:26 AM by mbrethen.)
Post: #20
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)?
Find all posts by this user
Quote this message in a reply
Post Reply 




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