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}]