       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]

>
>
> 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:=
x = {1,2,3,4,5}
x[]++
x

Out=
{1, 2, 3, 4, 5}

Out=
3

Out=
{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:=
x = {1,2,3,4,5}
x[] = Sequence @@ {"a","b","c"}
x
Length[x]
x[]

Out=
{1, 2, 3, 4, 5}

Out=
Sequence[a, b, c]

Out=
{1, 2, a, b, c, 4, 5}

Out=
7

Out=
b

everything looks fine...but

In:=
x[] = Pi

Set::partw:
Part 6 of {1, 2, Sequence[a, b, c], 4, 5}
does not exist.

Out=
Pi

why is the Sequence[] head still there? it seems to be totally
transparent to Length[] and Part[]. more confusingly still:

In:=
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:=
y = {1, 2, Sequence[a, b, c], 4, 5};
y === x

Out=
False

and then, to cap it all:

In:=
y[]

Out=
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[] is
as quick as x[] 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.