Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

David Marso
Administrator
Hope you all have had copious amounts of caffeinated beverages or at least
pounded a few cold ones.
It is past beer o'clock after all somewhere.
Two threads which I instigated in the past and led to interesting
discussion.
Have fun and safety first this Labor Day.
---
Cartesian Product.
There are several threads about.  Here are a few.
http://spssx-discussion.1045642.n5.nabble.com/TIP-Cartesian-product-using-MATRIX-td5719597.html
http://spssx-discussion.1045642.n5.nabble.com/Cartesian-product-in-SPSS-td1091169.html#a1091174
http://spssx-discussion.1045642.n5.nabble.com/Kroneker-Cartesian-Product-Mny2Mny-Unroll-td5729195.html#a5729199

Recursion
Spark:
http://spssx-discussion.1045642.n5.nabble.com/Computing-variables-based-on-multiple-rows-in-a-tall-format-file-td5723431i20.html#a5723777
Fire:
http://spssx-discussion.1045642.n5.nabble.com/Recursion-with-Macro-td5723537.html

Gasoline:
/* Our old friend */.
DEFINE !CartesianProduct (!POS !TOKENS (1)/!POS !TOKENS (1)/ !POS !TOKENS
(1) )
COMPUTE
!1={KRONEKER(!2,MAKE(NROW(!3),1,1)),KRONEKER(MAKE(NROW(!2),1,1),!3)}.      
!ENDDEFINE.

/* Brand new method to build CP of several vectors */.
DEFINE !RecursiveCartProd ( !POS !CHAREND ("|" ) /!POS !CMDEND )
!IF (!2 !NE !NULL ) !THEN
!CartesianProduct !HEAD(!2) !HEAD(!1) !HEAD (!TAIL (!1)).
!RecursiveCartProd !HEAD(!2)  !TAIL(!TAIL(!1)) | !TAIL(!2)
!IFEND
!ENDDEFINE.

/* Recursive loading method */.
DEFINE !Load (!POS !CHAREND("|" ) / !POS !CMDEND )
!IF (!1 !NE !NULL ) !THEN
COMPUTE !HEAD(!1)=!UNQUOTE(!HEAD(!2)).
!Load !TAIL(!1) |  !TAIL(!2).
!IFEND
!ENDDEFINE.


/* Different ways to call into the beast */.
OUTPUT CLOSE ALL.
MATRIX.
!Load A B C D E   | 'T({1:10}/10)' 'T({1:10}/20)' 'T({1:10}/30)'
'T({1:10}/40)' 'T({1:10}/50)' .
!RecursiveCartProd A B C D E  | W X Y Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.


DEFINE !A ()  'T({1:10}/10)' !ENDDEFINE.
DEFINE !B ()  'T({1:10}/20)' !ENDDEFINE.
DEFINE !C ()  'T({1:10}/30)' !ENDDEFINE.
DEFINE !D ()  'T({1:10}/40)' !ENDDEFINE.
DEFINE !E ()  'T({1:10}/50)' !ENDDEFINE.

/* You didn't grock this previously */.
DEFINE !Mx (!POS !ENCLOSE("(",")") )
!CONCAT('!',!1)
!ENDDEFINE.

OUTPUT CLOSE ALL.
MATRIX.
!Load A B C D E  | !Mx(A) !Mx(B) !Mx(C) !Mx(D) !Mx(E) .
!RecursiveCartProd A B C D E  | W X Y Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.



OUTPUT CLOSE ALL.
MATRIX.
!Load A B C D E   | !A !B  !C !D !E .
!RecursiveCartProd A B C D E  | W X Y Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.


OUTPUT CLOSE ALL.
MATRIX.
COMPUTE A={1;2;3;4;5;6}.
COMPUTE B={7;8;9}.
COMPUTE C={10;20;30;40}.
COMPUTE D={-1;-2;-3;-4}.
COMPUTE E={1;2;3;4;5;6}.
!RecursiveCartProd A B C D E  | W X Y Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.





-----
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
--
Sent from: http://spssx-discussion.1045642.n5.nabble.com/

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

David Marso
Administrator
This set is a bit cleaner.
Using the fact that in MATRIX you can do things like.
COMPUTE x=f(x).
I use the result of previous iteration and replace it with the new
calculation.
Didn't make sense to have a single line of code in the worker macro so I
stuffed it into the recursive function.
Makes more sense memory wise since only one result matrix is retained.
Consequently makes it less confusing to call.
---

DEFINE !RecursiveCartesianProduct ( !POS !CHAREND ("|" ) /!POS !CMDEND )
!IF (!TAIL(!1) !NE !NULL ) !THEN
COMPUTE !2={KRONEKER(!HEAD(!1),MAKE(NROW(!HEAD(!TAIL (!1))),1,1)),
            KRONEKER(MAKE(NROW(!HEAD(!1)),1,1),!HEAD(!TAIL (!1)))}.      
!RecursiveCartesianProduct !2  !TAIL(!TAIL(!1)) | !2.
!IFEND
!ENDDEFINE.

/* Recursive loading method */.
DEFINE !Load (!POS !CHAREND("|" ) / !POS !CMDEND )
!IF (!1 !NE !NULL ) !THEN
COMPUTE !HEAD(!1)=!UNQUOTE(!HEAD(!2)).
!Load !TAIL(!1) |  !TAIL(!2).
!IFEND
!ENDDEFINE.


/* Different ways to call into the beast */.
SET MPRINT ON PRINTBACK ON.
OUTPUT CLOSE ALL.
MATRIX.
!Load A B C D E   | 'T({1:10}/10)' 'T({1:10}/20)' 'T({1:10}/30)'
'T({1:10}/40)' 'T({1:10}/50)' .
!RecursiveCartesianProduct A B C D E  | Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.


DEFINE !A ()  'T({1:10}/10)' !ENDDEFINE.
DEFINE !B ()  'T({1:10}/20)' !ENDDEFINE.
DEFINE !C ()  'T({1:10}/30)' !ENDDEFINE.
DEFINE !D ()  'T({1:10}/40)' !ENDDEFINE.
DEFINE !E ()  'T({1:10}/50)' !ENDDEFINE.

/* You didn't grock this previously */.
DEFINE !Mx (!POS !ENCLOSE("(",")") )
!CONCAT('!',!1)
!ENDDEFINE.

OUTPUT CLOSE ALL.
MATRIX.
!Load A B C D E  | !Mx(A) !Mx(B) !Mx(C) !Mx(D) !Mx(E) .
!RecursiveCartesianProduct A B C D E  | Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.



OUTPUT CLOSE ALL.
MATRIX.
!Load A B C D E   | !A !B  !C !D !E .
!RecursiveCartesianProduct A B C D E  | Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.


OUTPUT CLOSE ALL.
MATRIX.
COMPUTE A={1;2;3;4;5;6}.
COMPUTE B={7;8;9}.
COMPUTE C={10;20;30;40}.
COMPUTE D={-1;-2;-3;-4}.
COMPUTE E={1;2;3;4;5;6}.
!RecursiveCartesianProduct A B C D E  | Z .
PRINT NROW(Z).
PRINT Z.
END MATRIX.




-----
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
--
Sent from: http://spssx-discussion.1045642.n5.nabble.com/

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

Kirill Orlov
David, did you ever attempted to answer these two questions:
1) What are situations/tasks a recursive SPSS macro can help when a usual macro cannot?
2) If a task can be coded in both recursive and not recursive manner, does resursive version have any advantage in terms of speed or flexibility?

I'm asking because you are seemingly the pioneer (or at least a proponent) of recursion. Then it is logical that you ought to demonstrate advantages which a non-recursuive macro lacks. Without advantages it is but a graceful trifle, isn't it.

===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

David Marso
Administrator
I challenge you to rewrite the two macros in my second post without
recursion.

The CP gets tricky because the first pass uses a,b -> z the second and
subsequent z,xi->z
With the !Load macro there are two parallel lists.  
That typically involves making a copy of one list, running a !DO over one
list and reducing the copy using !TAIL.
That is ugly IMNSHO. Much more elegant/clean to just pass the !TAILS of the
lists back and do a null check.
I don't believe one will find any performance differences between a
recursive and non recursive implementation.




Kirill Orlov wrote

> David, did you ever attempted to answer these two questions:
> 1) What are situations/tasks a recursive SPSS macro can help when a
> usual macro cannot?
> 2) If a task can be coded in both recursive and not recursive manner,
> does resursive version have any advantage in terms of speed or
> flexibility?
>
> I'm asking because you are seemingly the pioneer (or at least a
> proponent) of recursion. Then it is logical that *you* ought to
> demonstrate advantages which a non-recursuive macro lacks. Without
> advantages it is but a graceful trifle, isn't it.
>
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (not to SPSSX-L), with no body text except the
> command. To leave the list, send the command
> SIGNOFF SPSSX-L
> For a list of commands to manage subscriptions, send the command
> INFO REFCARD





-----
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
--
Sent from: http://spssx-discussion.1045642.n5.nabble.com/

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

David Marso
Administrator
OK, steopping up to my own challenge it turns out to be somewhat easy.
I was blocking on the first pass business.  
SIMPLE, just have first result be {1}.
---

DEFINE !VectorCartesianProduct ( !POS !CHAREND ("|" ) /!POS !CMDEND )
COMPUTE !2={1}.
!DO !tx !IN (!1)
COMPUTE
!2={KRONEKER(!2,MAKE(NROW(!tx),1,1)),KRONEKER(MAKE(NROW(!2),1,1),!tx)}.                  
!DOEND
COMPUTE !2=!2(:, 2:NCOL(!2)).
!ENDDEFINE.

call as

!VectorCartesianProduct  A B C D E | Z .

as before.

David Marso wrote

> I challenge you to rewrite the two macros in my second post without
> recursion.
>
> The CP gets tricky because the first pass uses a,b -> z the second and
> subsequent z,xi->z
> With the !Load macro there are two parallel lists.  
> That typically involves making a copy of one list, running a !DO over one
> list and reducing the copy using !TAIL.
> That is ugly IMNSHO. Much more elegant/clean to just pass the !TAILS of
> the
> lists back and do a null check.
> I don't believe one will find any performance differences between a
> recursive and non recursive implementation.
>
>
>
>
> Kirill Orlov wrote
>> David, did you ever attempted to answer these two questions:
>> 1) What are situations/tasks a recursive SPSS macro can help when a
>> usual macro cannot?
>> 2) If a task can be coded in both recursive and not recursive manner,
>> does resursive version have any advantage in terms of speed or
>> flexibility?
>>
>> I'm asking because you are seemingly the pioneer (or at least a
>> proponent) of recursion. Then it is logical that *you* ought to
>> demonstrate advantages which a non-recursuive macro lacks. Without
>> advantages it is but a graceful trifle, isn't it.
>>
>>
>> =====================
>> To manage your subscription to SPSSX-L, send a message to
>
>> LISTSERV@.UGA
>
>>  (not to SPSSX-L), with no body text except the
>> command. To leave the list, send the command
>> SIGNOFF SPSSX-L
>> For a list of commands to manage subscriptions, send the command
>> INFO REFCARD
>
>
>
>
>
> -----
> Please reply to the list and not to my personal email.
> Those desiring my consulting or training services please feel free to
> email me.
> ---
> "Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos
> ne forte conculcent eas pedibus suis."
> Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in
> abyssum?"
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (not to SPSSX-L), with no body text except the
> command. To leave the list, send the command
> SIGNOFF SPSSX-L
> For a list of commands to manage subscriptions, send the command
> INFO REFCARD





-----
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
--
Sent from: http://spssx-discussion.1045642.n5.nabble.com/

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: Recursive Macros for Multi Vector Cartesian Product: Fun for a late Friday.

Jon Peck
Any algorithm could be written in either iterative or recursive style, but, once you understand recursion, in many cases the recursive implementation will be simpler and clearer.  Using SPSS Statistics, a recursive implementation is likely to be slower than an iterative one, because it does not analyze and optimize the recursion structure, but in most cases I would expect the difference to be small.  I have not tested this belief, however.

On Tue, Sep 5, 2017 at 10:57 PM, David Marso <[hidden email]> wrote:
OK, steopping up to my own challenge it turns out to be somewhat easy.
I was blocking on the first pass business.
SIMPLE, just have first result be {1}.
---

DEFINE !VectorCartesianProduct ( !POS !CHAREND ("|" ) /!POS !CMDEND )
COMPUTE !2={1}.
!DO !tx !IN (!1)
COMPUTE
!2={KRONEKER(!2,MAKE(NROW(!tx),1,1)),KRONEKER(MAKE(NROW(!2),1,1),!tx)}.
!DOEND
COMPUTE !2=!2(:, 2:NCOL(!2)).
!ENDDEFINE.

call as

!VectorCartesianProduct  A B C D E | Z .

as before.

David Marso wrote
> I challenge you to rewrite the two macros in my second post without
> recursion.
>
> The CP gets tricky because the first pass uses a,b -> z the second and
> subsequent z,xi->z
> With the !Load macro there are two parallel lists.
> That typically involves making a copy of one list, running a !DO over one
> list and reducing the copy using !TAIL.
> That is ugly IMNSHO. Much more elegant/clean to just pass the !TAILS of
> the
> lists back and do a null check.
> I don't believe one will find any performance differences between a
> recursive and non recursive implementation.
>
>
>
>
> Kirill Orlov wrote
>> David, did you ever attempted to answer these two questions:
>> 1) What are situations/tasks a recursive SPSS macro can help when a
>> usual macro cannot?
>> 2) If a task can be coded in both recursive and not recursive manner,
>> does resursive version have any advantage in terms of speed or
>> flexibility?
>>
>> I'm asking because you are seemingly the pioneer (or at least a
>> proponent) of recursion. Then it is logical that *you* ought to
>> demonstrate advantages which a non-recursuive macro lacks. Without
>> advantages it is but a graceful trifle, isn't it.
>>
>>
>> =====================
>> To manage your subscription to SPSSX-L, send a message to
>
>> LISTSERV@.UGA
>
>>  (not to SPSSX-L), with no body text except the
>> command. To leave the list, send the command
>> SIGNOFF SPSSX-L
>> For a list of commands to manage subscriptions, send the command
>> INFO REFCARD
>
>
>
>
>
> -----
> Please reply to the list and not to my personal email.
> Those desiring my consulting or training services please feel free to
> email me.
> ---
> "Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos
> ne forte conculcent eas pedibus suis."
> Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in
> abyssum?"
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (not to SPSSX-L), with no body text except the
> command. To leave the list, send the command
> SIGNOFF SPSSX-L
> For a list of commands to manage subscriptions, send the command
> INFO REFCARD





-----
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
--
Sent from: http://spssx-discussion.1045642.n5.nabble.com/

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD



--
Jon K Peck
[hidden email]

===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD