Is There a Shorter Way of Doing This?

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

Is There a Shorter Way of Doing This?

bdates

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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

Kirill Orlov
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

bdates

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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

David Marso-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

Kirill Orlov
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

David Marso-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

Kirill Orlov
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

Kirill Orlov
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

David Marso-2
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

David Marso
Administrator
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.





David Marso-2 wrote

> Thanks Kirill.
> 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

> 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: Is There a Shorter Way of Doing This?

Bruce Weaver
Administrator
You have no idea how much better that makes the rest of us feel, David.  ;-)  



David Marso wrote
> Face it.  I'm very experienced with MATRIX but had a bit of difficulty
> groking Kirill's solution.





-----
--
Bruce Weaver
[hidden email]
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

NOTE: My Hotmail account is not monitored regularly.
To send me an e-mail, please use the address shown above.

--
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
--
Bruce Weaver
bweaver@lakeheadu.ca
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

NOTE: My Hotmail account is not monitored regularly.
To send me an e-mail, please use the address shown above.
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

Kirill Orlov
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

Kirill Orlov
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

bdates

Thanks, Kirill! I've been playing with all this and think I grasp it. There's lots you can do with the approach. BTW, I noticed that this last syntax propagates row by row. Very important if row by row matrix algebra or manipulation is necessary for computation or further restructuring. Take care.


Brian

From: Kirill Orlov <[hidden email]>
Sent: Tuesday, January 22, 2019 5:34:52 AM
To: Dates, Brian; [hidden email]
Subject: Re: Is There a Shorter Way of Doing This?
 
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
Reply | Threaded
Open this post in threaded view
|

Re: Is There a Shorter Way of Doing This?

David Marso
Administrator
I too have been pondering this and it indeed makes complete sense.  I had
just never extracted parts of a matrix with the intent to build multiple
copies of a given submatrix.  Quite elegant in a rather devilish sort of
way.


bdates wrote

> Thanks, Kirill! I've been playing with all this and think I grasp it.
> There's lots you can do with the approach. BTW, I noticed that this last
> syntax propagates row by row. Very important if row by row matrix algebra
> or manipulation is necessary for computation or further restructuring.
> Take care.
>
>
> Brian
> ________________________________
> From: Kirill Orlov &lt;

> kior@

> &gt;
> Sent: Tuesday, January 22, 2019 5:34:52 AM
> To: Dates, Brian;

> SPSSX-L@.UGA

> Subject: Re: Is There a Shorter Way of Doing This?
>
> 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

> 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?"