# Is There a Shorter Way of Doing This?

15 messages
Open this post in threaded view
|

## Is There a Shorter Way of Doing This?

 Very often in my matrix work, a statistic will require multiplication Matrix A by Vector V n times, which is equal to the number of columns or rows matrix A. Typically I use the syntax below, which creates Matrix B of size equal to Matrix A. In this case Matrix A is 3x3, Vector V is a column vector of 3 rows, and Matrix B is 3x3 with the columns of Vector V repeated 3 times. Then I simply multiply the matrices. Is there a simpler way of creating Matrix  B than the syntax below? Thanks. Brian DATA LIST FREE/x. BEGIN DATA 1 1 1 1 2  3 1 3  1 1  END DATA. /* Start matrix and make an nx3 matrix of vector x.*/ matrix . get x/file=*/var=x . compute xmatrix=make(nrow(x),3,0) . loop #j=1 to ncol(xmatrix) .     loop #i=1 to nrow(xmatrix) .         loop #k=1 to nrow(x) .             do if #k=#i .                 compute xmatrix(#i,#j)=x(#k,1) .             end if .         end loop .     end loop . end loop . print xmatrix . end matrix . ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 This is called an outer product or vector propagation. matrix . get x /file=* /var=x . print x. comp xmatrix= x*make(1,3,1). /*A) Propagation of a column in pleats print xmatrix. comp y= t(x). print y. comp ymatrix= make(3,1,1)*y. /*B) Propagation of a row in pile print ymatrix. comp ymatrix= y(make(3,1,1),:). /*B2) This is a faster (on big data) alternative to (B) print ymatrix. end matrix. 17.01.2019 21:09, Dates, Brian пишет: Very often in my matrix work, a statistic will require multiplication Matrix A by Vector V n times, which is equal to the number of columns or rows matrix A. Typically I use the syntax below, which creates Matrix B of size equal to Matrix A. In this case Matrix A is 3x3, Vector V is a column vector of 3 rows, and Matrix B is 3x3 with the columns of Vector V repeated 3 times. Then I simply multiply the matrices. Is there a simpler way of creating Matrix  B than the syntax below? Thanks. Brian DATA LIST FREE/x. BEGIN DATA 1 1 1 1 2  3 1 3  1 1  END DATA. /* Start matrix and make an nx3 matrix of vector x.*/ matrix . get x/file=*/var=x . compute xmatrix=make(nrow(x),3,0) . loop #j=1 to ncol(xmatrix) .     loop #i=1 to nrow(xmatrix) .         loop #k=1 to nrow(x) .             do if #k=#i .                 compute xmatrix(#i,#j)=x(#k,1) .             end if .         end loop .     end loop . end loop . print xmatrix . end matrix . ===================== 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 ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 Thanks, Kirill! I knew I was missing something. Brian From: Kirill Orlov <[hidden email]> Sent: Thursday, January 17, 2019 1:25:11 PM To: Dates, Brian; [hidden email] Subject: Re: Is There a Shorter Way of Doing This?   This is called an outer product or vector propagation. matrix . get x /file=* /var=x . print x. comp xmatrix= x*make(1,3,1). /*A) Propagation of a column in pleats print xmatrix. comp y= t(x). print y. comp ymatrix= make(3,1,1)*y. /*B) Propagation of a row in pile print ymatrix. comp ymatrix= y(make(3,1,1),:). /*B2) This is a faster (on big data) alternative to (B) print ymatrix. end matrix. 17.01.2019 21:09, Dates, Brian пишет: Very often in my matrix work, a statistic will require multiplication Matrix A by Vector V n times, which is equal to the number of columns or rows matrix A. Typically I use the syntax below, which creates Matrix B of size equal to Matrix A. In this case Matrix A is 3x3, Vector V is a column vector of 3 rows, and Matrix B is 3x3 with the columns of Vector V repeated 3 times. Then I simply multiply the matrices. Is there a simpler way of creating Matrix  B than the syntax below? Thanks. Brian DATA LIST FREE/x. BEGIN DATA 1 1 1 1 2  3 1 3  1 1  END DATA. /* Start matrix and make an nx3 matrix of vector x.*/ matrix . get x/file=*/var=x . compute xmatrix=make(nrow(x),3,0) . loop #j=1 to ncol(xmatrix) .     loop #i=1 to nrow(xmatrix) .         loop #k=1 to nrow(x) .             do if #k=#i .                 compute xmatrix(#i,#j)=x(#k,1) .             end if .         end loop .     end loop . end loop . print xmatrix . end matrix . ===================== 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 ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 In reply to this post by bdates I am intrigued by B2.  Can you elaborate? ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 David, B2 is simply as if extracting a submatrix; in this instance, the "submatrix" is bigger than the parental matrix (the vector). The row indexation is {1,1,1} i.e. row number 1 (the only one in the vector) is "extracted" 3 times to form the result. Note that this way is really the fastest (on big data) only to propagate a row vector, not a column vector. If you compose an analogous A2 trick, it will be slower than A. This is because in MATRIX, some rowwise and columnwise operations are internally not the same speed (it is normal, see https://en.wikipedia.org/wiki/Row-_and_column-major_order). 20.01.2019 9:02, David Marso пишет: ```I am intrigued by B2. Can you elaborate? ``` ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 In reply to this post by bdates It appears to be using a vector as a row subscript.  I don't understand this from a notional perspective.  I am not sure how MATRIX works with this.  Can you point me to the place in the FM where such is documented? "David, B2 is simply as if extracting a submatrix; in this instance, the "submatrix" is bigger than the parental matrix (the vector). The row indexation is {1,1,1} i.e. row number 1 (the only one in the vector) is "extracted" 3 times to form the result. Note that this way is really the fastest (on big data) only to propagate a row vector, not a column vector. If you compose an analogous A2 trick, it will be slower than A. This is because in MATRIX, some rowwise and columnwise operations are internally not the same speed (it is normal, see https://en.wikipedia.org/wiki/Row-_and_column-major_order). 20.01.2019 9:02, David Marso пишет: I am intrigued by B2.  Can you elaborate?" ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 I don't now where it is documented and if documented at all. The solution, as I described it, is very straightforward. comp ymatrix= y(make(3,1,1),:). or comp ymatrix= y(make(1,3,1),:). (which yields the same result) uses vector 1 1 1 as a row subscript. Consider matrix X of size say 4 x p. You extract rows say 1 and 3 to form matrix of size 2 x p, writing comp Y= X({1,3},:) Don't you? You could as well extract rows 1, 3 and again 1 to form the 3 x p matrix (two rows are duplicates) comp Y= X({1,3,1},:) Why not? An likewise, to continue the logic, you could extract only one specific row whatever many times you like. comp Y= X({2,2,2,2},:) Here row number 2 of X is propagated 4 times to form Y If X is just a 1 x p matrix, it has only row number 1. You could propagate it likewise. comp Y= X({1,1,1},:) or equivalently comp Y= X(make(1,3,1),:) 21.01.2019 5:14, David Marso пишет: ```It appears to be using a vector as a row subscript. I don't understand this from a notional perspective. I am not sure how MATRIX works with this. Can you point me to the place in the FM where such is documented? "David, B2 is simply as if extracting a submatrix; in this instance, the "submatrix" is bigger than the parental matrix (the vector). The row indexation is {1,1,1} i.e. row number 1 (the only one in the vector) is "extracted" 3 times to form the result. Note that this way is really the fastest (on big data) only to propagate a row vector, not a column vector. If you compose an analogous A2 trick, it will be slower than A. This is because in MATRIX, some rowwise and columnwise operations are internally not the same speed (it is normal, see https://en.wikipedia.org/wiki/Row-_and_column-major_order). 20.01.2019 9:02, David Marso пишет: I am intrigued by B2. Can you elaborate?" ``` ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 In reply to this post by David Marso-2 David, Subscripting is implicitly making a vector of integers. comp Y= X(1:3,:) amounts actually to comp rowindx= 1:3. comp colindx= 1:ncol(X). comp Y= X(rowindx,colindx). so you are using vectors as subscripts in fact. ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 In reply to this post by bdates Thanks Kiril. I have never thought of it in that way before. MATRIX never ceases to boggle my mind. "David, Subscripting is implicitly making a vector of integers. comp Y= X(1:3,:) amounts actually to comp rowindx= 1:3. comp colindx= 1:ncol(X). comp Y= X(rowindx,colindx). so you are using vectors as subscripts in fact." ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 In reply to this post by David Marso David, Appending, growing of (big) arrays bit by bit is inefficient. In most real tasks it will be faster to create an empty matrix first and then fill it in. This is just a general remark, for in this instance your example is simple and acceptible. 22.01.2019 0:43, David Marso пишет: ```OTOH: Here is a less arcane method which is less likely to cause your head to explode ;-) Probably less efficient than Kirill's technique but more accessible to mere mortals. Face it. I'm very experienced with MATRIX but had a bit of difficulty groking Kirill's solution. MATRIX. GET x /FILE =*/var=x . COMPUTE xMatrix={x}. LOOP #=2 TO 3. COMPUTE xMatrix={xMatrix,x}. END LOOP. PRINT xMatrix. END MATRIX. ``` ===================== 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
Open this post in threaded view
|

## Re: Is There a Shorter Way of Doing This?

 In reply to this post by bdates Brian, See also my matrix function PROPAGATE ROWS (!PROPAG) in collection "MATRIX - END MATRIX functions" on my web page http://www.spsstools.net/en/KO-spssmacros. 17.01.2019 21:40, Dates, Brian пишет: Thanks, Kirill! I knew I was missing something. ===================== 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