MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Mapping to a specific column or row in a matrix

  • To: mathgroup at smc.vnet.net
  • Subject: [mg103012] Re: [mg102985] Mapping to a specific column or row in a matrix
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Thu, 3 Sep 2009 19:56:49 -0400 (EDT)
  • References: <200909031110.HAA24167@smc.vnet.net>

Hi Peter,

I would define my own function:

In[1] =

ClearAll[mapAt,MappedListable];
Protect[MappedListable];
Options[mapAt] = {MappedListable -> False};
mapAt[f_, expr_, {pseq : (All | _Integer) ..}, OptionsPattern[]] :=
  Module[{copy = expr},
   copy[[pseq]] =
    If[TrueQ[OptionValue[MappedListable]] && Head[expr] === List,
      f[copy[[pseq]]],
     f /@ copy[[pseq]]
     ];
   copy];
mapAt[f_, expr_, poslist_List] := MapAt[f, expr, poslist];


This will do what you want:

In[2] =
mat = ConstantArray[1, {10, 5}];

In[3] = mapAt[#/10 &, mat, {All, 3}]

Out[3] =
{{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1},{1,1,1/10,1,1}}

In[4] = mapAt[#/10 &, mat, {3, All}]

Out[4] =
{{1,1,1,1,1},{1,1,1,1,1},{1/10,1/10,1/10,1/10,1/10},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}}

Also, it can take advantage of listability of some built-in functions:

In[5] = largemat = ConstantArray[1, {50000, 5}];

In[6] = mapAt[#/10 &, largemat, {All, 3}]; // Timing

Out[6] = {0.062, Null}

In[7] = mapAt[#/10 &, largemat, {All, 3}, MappedListable -> True]; // Timing

Out[7] = {0.016, Null}


Regards,
Leonid


On Thu, Sep 3, 2009 at 3:10 PM, pfalloon <pfalloon at gmail.com> wrote:

> Hi,
> I'm wondering if there is a more simple/elegant way to Map a function
> to a specific row or column of a matrix. The best I can come up
> requires both Map and MapAt, but it feels like there should be
> something more succinct (I suspect I may be overlooking something
> obvious).
>
> Example: suppose I want to divide entries in the 3rd column by 10.
>
> (* my clunky solution *)
> mat = ConstantArray[1, {10,5}];
> res = Map[MapAt[#/10 &, #, 3] &, mat]
>
>
> Note that the desired output is the entire matrix, so that rules out
> something like:
>
> mat[[All,3]]/10
>
>
> One thing that would seem natural would be to allow "All" as an
> element specification in the MapAt function. Thus, what I'm trying to
> do would be expressed as:
>
> (* doesn't work, but would be nice *)
> MapAt[#/10 &, mat, {All,3}]
>
> and if I wanted to do it to a specific row (say, the 3rd) it would be:
>
> (* doesn't work, but would be nice *)
> MapAt[#/10 &, mat, {3, All}]
>
>
> Any thoughts/suggestions?
>
> Thanks,
> Peter.
>
>


  • Prev by Date: Re: Re: Simplifying If expressions
  • Next by Date: Re: Can I do this faster?
  • Previous by thread: Re: Mapping to a specific column or row in a matrix
  • Next by thread: Re: Mapping to a specific column or row in a matrix