MapOverColumn[f_,mat_?MatrixQ,n_Integer]:= ....
- To: mathgroup at smc.vnet.net
- Subject: [mg17549] MapOverColumn[f_,mat_?MatrixQ,n_Integer]:= ....
- From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
- Date: Fri, 14 May 1999 01:13:14 -0400
- Sender: owner-wri-mathgroup at wolfram.com
Several weeks ago a user wanted to know how they could multiply a particular
column of a matrix by some number. A variety of solutions were given. This
question inspired me to write a function that would map a specified function
over each element in a given column of a matrix. I tried a variety of
methods and selected the fastest one I could find. I also let
'MapOverColumn' take a negative column, or a list of columns.
It seems Map[MapAt[f,#,n]&,mat]
is fastest for matrices without a lot of rows.
Then Transpose[MapAt[f,Thread[mat],n]]
seems best for matrices with lots of rows (starting at about 8000 rows).
However, I always have a hard time getting repeatable results from timing
tests, and I wonder if someone else can write a faster implementation.
Note:
you can compare the timing of methods on say
a 12000 x 10 matrix,
a 10 x 12000 matrix,
a 350 x 350 matrix,
etc.
I will send the final version to MathSource. In that version I will have
error messages posted for invalid input. Let me know if you have any other
ways to improve this program.
Regards,
Ted Ersek
--------------------------------
MapOverColumn::usage="MapOverColumn[f,m,n] applies f to each element in
column n of matrix m. If n is negative the function is mapped over the nth
column from the right. MapOverColumn[f,m,{n1,n2, ...}] maps f over several
columns.";
(*--------------*)
MapOverColumn[f_,mat_?MatrixQ,n_Integer]/;
(1<=n<=Part[Dimensions[mat],2]):=
If[Length[mat]<8000,
Map[MapAt[f,#,n]&,mat],
Transpose[MapAt[f,Thread[mat],n]]
]
(*---------------*)
MapOverColumn[f_,mat_?MatrixQ,n_Integer?Negative]:=
MapOverColumn[f,mat,1+n+Part[Dimensions[mat],2]]
(*__________*)
MapOverColumn[f_,mat_?MatrixQ,lst:{__Integer}]/;
ValidQ[mat,lst]:=
Fold[(MapOverColumn[f,#1,#2]&) ,mat,lst ]
(*___________*)
ValidQ[mat_,lst_]:=
With[{c=Part[Dimensions[mat],2]},
And@@(((-c<=#<=c)&&(#=!=0)&)/@ (Hold@@lst))]
(*----- Examples with output deleted are given below ------- *)
tst=Table[Random[],{8},{4}]
MapOverColumn[#+5&,tst,2]
MapOverColumn[#+5&, tst, -1]
MapOverColumn[#+5&,tst,{2,3}]