Re: Compile problem: Mathematica 4
- To: mathgroup at smc.vnet.net
- Subject: [mg18908] Re: [mg18777] Compile problem: Mathematica 4
- From: simon shannon <sshannon at taz.dra.hmg.gb>
- Date: Mon, 26 Jul 1999 14:27:48 -0400
- Organization: dera
- References: <7n68mn$gu3@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
paul's original function:
> f=Compile[{{x, _Real,1}}, i=Round[2.3]; x[[i]]++;Return[x]]
[snip]
>
> Try this instead:
>
> f=Compile[{{x, _Real,1}}, Block[{i,var=x},
> i=Round[2.3]; var[[i]]++;Return[var]]]
>
> or
>
> f=Compile[{{x, _Real,1}}, Block[{var=x},
> i=Round[2.3]; var[[i]]++;Return[var]], {{i, _Integer}}]
>
[snip]
> An unrelated problem with this example is that it tries to assign a value
> to a number. The expression x[[i]]++, where x is a list of numbers, picks
> out an element from that list and tries to increment it. Mathematica will
> not let you do that. That is the reason for introducing the variable var
> in the above examples.
>
> Dave Withoff
> Wolfram Research
it seems to me that paul was explicitly trying to *avoid* doing the
structure duplication to save memory and time. after all, the following
fragment works ok:
In[1]:=
x = {1,2,3,4,5}
x[[3]]++
x
Out[1]=
{1, 2, 3, 4, 5}
Out[2]=
3
Out[3]=
{1, 2, 4, 4, 5}
i have a slightly more tricky teaser for you though;
(i tried to post this last week to the group, but it
didn't arrive for some reason). i want to replace just
element 3 of a list with a sequence. the list could be
huge and complicated, so i *dont* want to duplicate the
whole thing using Join[]s and Take[]s, or Replace[]s, so
let's try:
In[1]:=
x = {1,2,3,4,5}
x[[3]] = Sequence @@ {"a","b","c"}
x
Length[x]
x[[4]]
Out[1]=
{1, 2, 3, 4, 5}
Out[2]=
Sequence[a, b, c]
Out[3]=
{1, 2, a, b, c, 4, 5}
Out[4]=
7
Out[5]=
b
everything looks fine...but
In[6]:=
x[[6]] = Pi
Set::partw:
Part 6 of {1, 2, Sequence[a, b, c], 4, 5}
does not exist.
Out[6]=
Pi
why is the Sequence[] head still there? it seems to be totally
transparent to Length[] and Part[]. more confusingly still:
In[7]:=
InputForm[x]//Print
{1, 2, "a", "b", "c", 4, 5}
i thought InputForm[] ought to be able to exactly reconstruct
an object as though you had typed it in at the input. we can easily
test this:
In[8]:=
y = {1, 2, Sequence[a, b, c], 4, 5};
y === x
Out[9]=
False
and then, to cap it all:
In[10]:=
y[[6]]
Out[10]=
4
so the Sequence[] has been stripped off by the input reading
process somehow. i have strayed a little bit from the original
question, but here is my question: is there any way of doing
efficient in-place element modification/substitution without
duplicating the list. many people may not be aware that lists
are actually implemented as arrays in Mathematica so that doing x[[3]] is
as quick as x[[3000]] ie we do not have to track down 3000 Rest[]
pointers (aka cdr for lisp hackers). however, in my case i would
like to do a little local pointer surgery.
any comments?
- simon shannon