HP Forums

Full Version: Syntax Problems with map() and apply()
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I want to use the map() or apply() function to stream over a list or vector but I keep getting a syntax error, even when I enter the example from the User Guide or Help! Here is the first example from Help for apply():

apply( x->x^3, [1 2 3] )

results in a syntax error message. The cursor is left after the first occurrence of x.

I use these functions in other languages all the time. I kind of think of solutions in terms of them - very useful! Please help me how to properly call them in HP PPL.

This is a CAS function that will operate as advertised from the CAS view (button below the Esc key). To use this or any other CAS command from the Home view try

CAS.apply ("x->x^3, [1 2 3]")
Putting the expression in quotes will keep the Prime from trying to evaluate the expression first and throwing a syntax error.

Try this format:

[HOME] command line entry: CAS.apply("x→x^3",[1,2,3]);

[CAS] command line entry: apply((x)->x^3,[1,2,3]);

Thanks so much for your help. It has been some time since I programmed a calculator. I used the HP-41 extensively through chemistry graduate school and beyond, and later the HP-42 and HP-48 through HP-50 as well. I am getting back to it now with the HP Prime, but it is a very different machine in so many ways.

I was using Mark Power's blog to help. One of his early posts about the Prime involved programming a card game. His approach to shuffling used explicit loops. I am used to other computer languages that support data structures such as lists and vectors with functions like apply() and map() so I thought I might apply one of my usual techniques for randomization. We try to 'vectorize' operations for the sake of concise code and algorithm performance. In the case of the card deck, you generate a vector of 52 uniformly random variables, sort them into another vector, then find their position in the original, random vector. The positions (index) becomes a random index. You essentially transfer the randomness to the positions. This way is usually much simpler and cheaper than other methods. I thought I would try it out.

Here is my program, with your help, just for this aspect of the game:

f(l1,l2) := apply('x->POS(l1,x),l2);

L1 := MAKELIST(RANDOM(),X,1,52);
L2 := SORT(L1);
RETURN f(L1,L2);

The RANDOMIZE program returned these timings using Eddie's TIMESHUFFLE() program to time the shuffling of a 52-card deck:

HP Prime:
iPad Pro app:
HP Prime Virtual Calculator (Windows):
HP Prime Virtual Calculator (Macintosh):

I am surprised that the vectorization approach performed so poorly versus the explicit looping approach, but there you have it. For an 'apples to apples' comparison, it took only 0.02s for Mark's original solution. It took mine more than three times as long!

So I have a lot to learn about this machine and programming it, but many thanks already for getting me started down the right path!
Very interesting trick! Really like it, I'll have to remember it and use it sometime.

Perhaps the timing difference lies in the time required to search a list versus a vector. Could using MAKEMAT in place of MAKELIST change the results? Those familiar with the implementation could weigh in, or you could try the experiment and see.

~ Mark
apply and map are CAS commands, if you are using them with HOME commands and from HOME programs you have to pay all the conversion penalties.
Alternative method for generating a shuffled deck of 52 cards:

rand(52,1,52)►L1 [Note: rand must be spelled in lowercase]

One step. No looping. TEVAL reports that this method takes 0.001 seconds in Home. That's pretty fast. Smile
(05-27-2016 04:21 AM)Joe Horn Wrote: [ -> ]Alternative method for generating a shuffled deck of 52 cards:

rand(52,1,52)►L1 [Note: rand must be spelled in lowercase]

One step. No looping. TEVAL reports that this method takes 0.001 seconds in Home. That's pretty fast. Smile

thank you Joe, very nice!
I wonder why rand() hasn't an item in the Catalog of the Prime (Help)...

Perhaps you'd rather deal with a vector:

ranm(52,1,52)►M0 // Col Vector


rand(52,1,52)►M1; // Row vector

There's a slight difference between them when stored in a list variable, (L0, etc.), instead of a matrix variable, (M0, etc.). But you can deal with them that way, too!

I never found the rand() function so I created my own. The built-in function is very nice.

BTW, what is the method for generating the pseudo-random numbers on the HP Prime? Is it still the linear congruential generator? The standard now is the Mersenne Twister.

The HP Prime capability (memory and speed) lend itself to serious applications beyond education and having a superior, modern RNG would be a big step forward.

Thanks again for the help with the original question. I'm learning a lot!
The undocumented rand() function appears to return a shuffling of the items when used with three arguments as Joe introduced it. (It has other behavior with 0, 1, or 2 arguments). On the other hand, ranm() appears to use sampling with replacement, so it can't be used for shuffling.
I don't understand the "shuffling" distinction, do you mean the method of element (card) extraction?

L0:=MAKELIST(ranm(52,1,52),X,1,4); // Deck shuffled 4 times:




L1:=MAKELIST(rand(52,1,52),X,1,4); // Deck shuffled 4 times:




Element selection:
L0(1,2,1) ==> 12
L1(1,2) ==> 1

Matrix, vector, and list representations enable a wide variety of additional toolbox commands, (for further processing).

On the Prime, rand is using the following congruence
r = unsigned ((1664525*ulonglong(r)+1013904223)%(ulonglong(1)<<31))
Inside Giac, it's a Mersenne twister.
I don't have documentation for rand() or ranm() so it is 'trial and error.' (I don't care about the difference between a row or column vector depending on how it is stored yet.) When I use simple cases of ranm(n,1,n), I see 'sample with replacement,' not shuffling. For example, i run ranm(5,1,5) and I get [4 5 2 3 5], so it is not shuffling but sampling with replacement.

I might be mis-using this function but I have no documentation and I am following the posted pattern of ranm(n,1,n) to experiment.
Parisse, thanks for clarifying algorithm for RNG. Is 'inside Giac' the same as CAS?
DrD, in your example of four repeated shuffling, I see index 31 appear thrice:


So it is a case of sampling with replacement using ranm() and not shuffling as with rand().
ranm() see help description for randMat <== note spelling!
(05-28-2016 08:46 PM)mark4flies Wrote: [ -> ]Parisse, thanks for clarifying algorithm for RNG. Is 'inside Giac' the same as CAS?

No, rand is a CAS command. Inside Giac means for Xcas.
Reference URL's