Post Reply 
RPL mini-challenge: Create an anti-Identity Matrix
05-14-2018, 07:12 PM (This post was last modified: 05-14-2018 09:55 PM by DavidM.)
Post: #32
RE: RPL mini-challenge: Create an anti-Identity Matrix
(05-13-2018 07:32 PM)pier4r Wrote:  Question: the code above, I believe, can get a further speed up if one could duplicate many objects on the stack at once. I do not know any command for this. Say I have 5 objects on the stack and I want to duplicate them, without using an explicit loop (surely the command internally will have a loop, like NDUPN). Is it possible?

As 3298 has mentioned, NDUP will duplicate a group of stack objects. But it only makes one copy, so you would have to loop the calls to NDUP to replicate a group of objects multiple times.

The SysRPL program listed below implements a command I've named "NMDUP", which does what I think you're referring to. It requires a 49g/49g+/50g/48gII, and its arguments are as follows:

N+2: object 1
...
3: object N
2: N (the count of discrete objects to replicate)
1: M (the number of duplicates of the above objects after replication)

So to make 4 sets of 1, 2, and 3:

5: 1
4: 2
3: 3
2: 3
1: 4
NMDUP

yields the following result
12: 1
11: 2
10: 3
9: 1
8: 2
7: 3
6: 1
5: 2
4: 3
3: 1
2: 2
1: 3

Code:
::
   ( stack on entry:
     n: anything
     ...
     2: group count [integer]
     1: repeat factor [integer]
   )

   CK2NOLASTWD                         ( stack must contain at least 2 objects )
   CK&DISPATCH1
   BINT17 ( ..., real, real ) ::       ( SL1/2 must contain numbers )
      COERCE2                          ( convert to BINTs )
      OVER #3+                         ( check stack depth )
      DEPTH #> case SETSTACKERR        ( error if stack not deep enough )

      ( special cases )
      DUP#0=case :: DROP NDROP ;       ( repeat factor of 0 )
      DUP#1= casedrop DROP             ( repeat factor of 1 )
      OVER#0= casedrop DROP            ( group count of 0 )

      ( otherwise )
      SWAP 1LAMBIND                    ( save group count in NULLLAM )
      ONE_DO (DO)                      ( loop repfactor - 1 times )
         1GETLAM NDUP                  ( NDUP the current group )
      LOOP
      ABND                             ( abandon NULLLAM )
   ;
;

(I've also attached the code object if you want to try it out)

Using a SysRPL component is outside the scope of this challenge Smile, but here's an example of how NMDUP might have been used:

Code:
\<<
  DUP \-> dim                     @ save the dimension
  \<<
    0. 1. ROT NDUPN               @ build the data to replicate
    DUP 1. +                      @ count of objects (N)
    SWAP 1. -                     @ total number of instances (M)
    NMDUP                         @ replicate!
    0.                            @ need final 0
    dim DUP 2. \->LIST \->ARRY    @ convert stack objects to final matrix
  \>>
\>>

Edit: changed the error that is thrown if the stack doesn't have enough objects for NMDUP, and clarified the compatible platforms.


Attached File(s)
.zip  NMDUP.zip (Size: 236 bytes / Downloads: 1)
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: RPL mini-challenge: Create an anti-Identity Matrix - DavidM - 05-14-2018 07:12 PM



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