MathGroup Archive 2001

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

Search the Archive

Re: exchanging 2 elements in a list (problem with Block)

  • To: mathgroup at smc.vnet.net
  • Subject: [mg27631] Re: exchanging 2 elements in a list (problem with Block)
  • From: "Allan Hayes" <hay at haystack.demon.co.uk>
  • Date: Fri, 9 Mar 2001 02:35:45 -0500 (EST)
  • References: <98505m$5h0@smc.vnet.net> <98722r$8rs@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Richard Fateman has pointed a bug out to me in my previous posting --

Block in

Swap1[m_,i_,j_]:=
 Block[{s=m},
     s[[{i,j}]]= s[[{j,i}]];s
    ]

causes

Swap1[{a,s},1,2];

$RecursionLimit::reclim: Recursion depth of 256 exceeded.

Replacing Block with Module corrects this.

*** However this example does point up a general problem with Block ***


--
Allan
---------------------
Allan Hayes
Mathematica Training and Consulting
Leicester UK
www.haystack.demon.co.uk
hay at haystack.demon.co.uk
Voice: +44 (0)116 271 4198
Fax: +44 (0)870 164 0565

"Allan Hayes" <hay at haystack.demon.co.uk> wrote in message
news:98722r$8rs at smc.vnet.net...
>
> Richard Fateman
>
> Richard,
> Two ways:
>
> Swap1[m_,i_,j_]:=
>   Block[{s=m},
>     s[[{i,j}]]= s[[{j,i}]];s
>     ]
>
> Swap1[{a,b,c,d,e,f},2,4]
>
> {a,d,c,b,e,f}
>
> Swap2[m_,i_,j_]:=
>   ReplacePart[m,m,{{i},{j}},{{j},{i}}]
>
> Swap2[{a,b,c,d,e,f},2,4]
>
> {a,d,c,b,e,f}
>
> For swapping columns we have (besides double Transpose versions of the
> above):
>
> m= {{a,b,c,d},{e,f,g,h}};
>
> m[[All,{2,4}]]= m[[All,{4,2}]];m
>
> {{a,d,c,b},{e,h,g,f}}
>
> Next, I look at the first three of  your examples.
>
> 1 ---------------------------------------------------------------------
>
> Clear["`*"]
>
> Exchangeitems1[m_, r_Integer, s_Integer] :=
>    Block[{temp = m[[r]]},
>      m[[r]] = m[[s]];
>      m[[s]] = temp;
>      m
>
>    ];
>
> Exchangeitems1[{a,b,c,d,e,f},2,4]
>
>         Set::setps:{a,b,c,d,e,f} in assignment of part is not a symbol.
>
>         Set::setps:{a,b,c,d,e,f} in assignment of part is not a symbol.
>
>         {a, b, c, d, e, f}
>
>
> Analysis
>
> Crucial here is that {a,b,c,d,e,f} is passed directly to m, so we get, for
> example
>   {a,b,c,d,e,f} [[r]]={a,b,c,d,e,f} [[s]]
>
> However settings like
>
> mm[[3]] = p
>
> works only when mm is a *symbol* that has been assigned a value by Set,
not
> SetDelayed. For example
>
> mm= Evaluate[{1,2,3,4}];
>
> and, of course this value must have a position with index 3.
>
> Further, when these conditions hold, it is the stored value of  mm that is
> changed: a new mm is not constructed -- this more efficient.
>
> 2 --------------------------------------------------------
>
> Clear["`*"]
>
> Exchangeitems2[m_,r_Integer,s_Integer]:=
> Block[{temp},
>       temp=m[[r]];
>       m=ReplacePart[m,m[[s]],{r}];
>       m=ReplacePart[m,temp,{s}];
>       m
> ];
>
> Exchangeitems2[{a,b,c,d,e,f},2,4]
>
>         {a,d,c,d,e,f}
>
>
> Analysis:
>
> The replacement of m by {a,b,c,d,e,f} is a crucial here also:
> First we get
>
> temp = {a,b,c,d,e,f}[[2]]
>
> that becomes
>
>         temp = b, which is stored  (actually as a replacement rule)
>
>
> Then we get
>
> {a,b,c,d,e,f}= ReplacePart[{a,b,c,d,e,f},{a,b,c,d,e,f}[[4]],{2}]
>
> that becomes
>
>         {a,b,c,d,e,f}= {a,d,c,d,e,f}
>
> This results in the following  being stored
>    a=a, b=d, c=c, d=d, e=e, f =f .
> Here
>    b=d
> is the important one if course.
> So, when the next line is evaluted we begin with
>
>         {a,b,c,d,e,f}= ReplacePart[{a,b,c,d,e,f},temp,{2}]
>
> Which becomes successively (temp has already been defined as b, *and
> a,b....on  the left side are not evaluated*)
>
>         {a,b,c,d,e,f}= ReplacePart[{a,d,c,d,e,f},temp,{2}]
>         {a,b,c,d,e,f}= ReplacePart[{a,d,c,d,e,f},b,{2}]
>         {a,b,c,d,e,f}= ReplacePart[{a,d,c,d,e,f},d,{2}]
>         {a,b,c,d,e,f}= {a,d,c,d,e,f}
>
> This does not change the rules stored.
>
> Finally we evaluated {a,b,c,d,e,f} with  b =d in store.
> This gives
>             {a,d,c,d,e,f}
>
> ** And  b = d is still around
>
> b
>
>         d
>
> **Actually, worse could happen
>
> Exchangeitems2[{1,2,3,4,5,6},2,4]
>
>         Set::setraw: Cannot assign to raw object 1.
>
>         Set::setraw: Cannot assign to raw object 2.
>
>         Set::setraw: Cannot assign to raw object 3.
>
>         General::stop: Further output of Set::setraw will be suppressed
> during this \
>         calculation.
>
> {1,2,3,4,5,6}
>
> 3 -------------------------------------------------------------
>
> I have interchanged k and m in the following to conform to the previous
two
> definitions
>
> Clear["`*"]
> Exchangeitems[m_,r_Integer,s_Integer]:=Block[{k,temp},k=m;
>       temp=k[[r]];
>       k=ReplacePart[k,k[[s]],{r}];
>       k=ReplacePart[k,temp,{s}];
>       k];
>
> Exchangeitems[{a,b,c,d,e,f},2,4]
>
>         {a,d,c,b,e,f}
>
> Analysis
>
> The variable k is not useless, it is what makes this work.
> We get
>  k = {a,b,c,d,e,f} , which is stored
>  temp = b is stored
> Then, the symbol k is redefined by
>  k = ReplacePart[{a,b,c,d,e,f} ,{a,b,c,d,e,f} [[4]],{2}]
> which becomes
>  k = {a,d,c,d,e,f}, which is stored
> Then
>  k=ReplacePart[{a,d,c,d,e,f},b,{4}]
> which becomes
>  k={a,d,c,b,e,f}, which is stored
> Finally k evauates to {a,d,c,b,e,f}
>
> --
> Allan
> ---------------------
> Allan Hayes
> Mathematica Training and Consulting
> Leicester UK
> www.haystack.demon.co.uk
> hay at haystack.demon.co.uk
> Voice: +44 (0)116 271 4198
> Fax: +44 (0)870 164 0565
>
> "Richard Fateman" <fateman at cs.berkeley.edu> wrote in message
> news:98505m$5h0 at smc.vnet.net...
> >
> > Actually, I wanted to exchange 2 rows in a matrix,
> > but writing this program I found I could not even
> > exchange 2 elements in a simple list by the first
> > two (most obvious) programs I wrote.  The third
> > works. So does the fourth.
> >
> > Anyone care to explain why the first 2 fail?
> > (Typing them in to a system does not really explain
> > that much.)
> >
> > try Exchangitems[{a,b,c,d,e,f},2,4] which should
> > result in {a,d,c,b,e,f}.
> > Naturally it should not SET any of the variables
> > a,b,c,... . version 2 sets b to the value d.
> >
> >
> > Exchangeitems1[m_,r_Integer,s_Integer]:=
> > Block[{temp=m[[r]]},
> >        m[[r]]=m[[s]];
> >        m[[s]]=temp;
> >        m];
> >
> >
> > Exchangeitems2[m_,r_Integer,s_Integer]:=
> > Block[{temp},
> >        temp=m[[r]];
> >        m=ReplacePart[m,m[[s]],{r}];
> >        m=ReplacePart[m,temp,{s}];
> >        m];
> >
> >
> > (* this works by adding a useless variable *)
> > Exchangeitems[k_,r_Integer,s_Integer]:=
> > Block[{m,temp},
> >        m=k;
> >        temp=m[[r]];
> >        m=ReplacePart[m,m[[s]],{r}];
> >        m=ReplacePart[m,temp,{s}];
> >        m];
> >
> > (*Here is a more "functional" version *)
> >
> > ei[k_, low_, hi_]:= ei[k,hi,low] /; low>hi;
> > ei[k_, low_, hi_]:= k /; low==hi;
> > ei[k_, low_, hi_] :=
> >   Flatten[{Take[k, {1, low - 1}], {k[[hi]]},
> >       Take[k, {low + 1, hi - 1}], {k[[low]]}, Drop[k, hi]}, 1];
> >
> > (*and here is an APL-style version*)
> >
> >
> > ei2[k_,r_,s_]:=Table[Switch[j,r,k[[s]],
> >                               s,k[[r]],
> >                               _,k[[j]]],
> >                    {j,1,Length[k]}];
> >
> >
> >
> > Is there a nice, efficient, (and correct) program to do this?
> >
> >
> > Perhaps there is a better way to do this
> >
>
>
>






  • Prev by Date: Re: Fibonacci
  • Next by Date: Re: [SYS #14934] (general) serious newsgroup problem
  • Previous by thread: Re: V4.1 Carriage Returns w/ ReplaceRepeated in Windows?
  • Next by thread: RE: Re: exchanging 2 elements in a list (problem with Block)