Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2011

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

Search the Archive

Re: Assigning part of indexed object

  • To: mathgroup at smc.vnet.net
  • Subject: [mg119863] Re: Assigning part of indexed object
  • From: Oleksandr Rasputinov <oleksandr_rasputinov at hmamail.com>
  • Date: Sun, 26 Jun 2011 06:26:49 -0400 (EDT)
  • References: <itsjn7$8u7$1@smc.vnet.net> <iu49sb$jp7$1@smc.vnet.net>

Leonid,

I fully agree with all of your comments and of course you are right to
point out that modifying core functions such as Set is a bad idea in
general due to the likelihood of unintended consequences. Of course,
the performance issue introduced for setting parts of OwnValues can
be repaired to some extent:

indexedQ = Function[sym,
   Symbol =!= Head@Unevaluated[sym] =!= Unevaluated[sym],
   HoldFirst
  ];

Unprotect[Set];
Set[(sym_?indexedQ)[[part_]], val_] := (
   sym = ReplacePart[sym, part -> val];
   sym[[part]]
  );
Protect[Set];

which restores the O(1) behaviour (albeit at the cost of an increased
constant factor). But even so, I will join with you in stressing that this
general approach is dangerous and should be attempted only with
extreme caution, if at all.

Best,

O. R.

On Jun 25, 10:30 am, Leonid Shifrin <lsh... at gmail.com> wrote:
> Hi Fabrice,
>
> My guess is that the reasons are efficiency and immutability of  expres=
sions
> in Mtahematica. By restricting Set
> to variables or array elements, one can connect it directly to the intern=
al
> memory layout for that element. Note
> that all proposed solutions are based on ReplacePart, which copies the
> entire list to modify a single element.
> OTOH, constructs like indexed variables are serviced by hash-tables
> internally. Even if the value stored
> in the hash table is a pointer to some array, that array will likely be
> immutable. Whether it would be a
> good idea to make it mutable I don't know, but the general ideology is th=
at
> expressions are immutable
> in Mathematica. In other words, I don't think that the case of indexed
> variables was overlooked when
> designing Set - my guess is that the restriction to symbols is quite
> intentional.
>
> Regarding the "fix", I'd consider this not a fix but  a recipe for disa=
ster,
> because modifying Set in such
> a fashion is  dangerous, not to mention that it will often be completel=
y
> unacceptable performance-wise. Let us say
> you store a large array in a symbol and use a For loop with array indexin=
g.
> Suddenly all your array element assignments
> become O(n) time, where n is the list size, or even worse for higher
> dimensional tensors, not to mention increased
> memory consumption. Here is an illustration:
>
> In[18]:= a = Range[10000];
>
> In[19]:= Unprotect[Set];
> Set[sym_[[part_]], val_] := sym = ReplacePart[sym, part -> val];
> Protect[Set];
>
> In[27]:= Do[a[[i]] = a[[i]]^2, {i, Length[a]}] // Timing
>
> Out[27]= {1.156, Null}
>
> In[28]:= Unprotect[Set];
> Clear[Set];
> Protect[Set];
>
> In[31]:= Do[a[[i]] = a[[i]]^2, {i, Length[a]}] // Timing
>
> Out[31]= {0.047, Null}
>
> You may do this for  yourself if you wish (although I'd avoid even that=
),
> but I'd strongly
> advise against such modifications in production code or any code someone
> else will be using. Set is one of the
> most fundamental operations, and its modifications may have very far-
> reaching and hard to predict consequences.
> It may, for example, corrupt the system in very subtle ways, which you ma=
y
> never be able to identify.
>
> Unfortunately, the standard mechanism of "soft" system symbols overloadin=
g
> via UpValues does not
> quite work with Set (or at least I don't know of a way to make it work)
> because Set holds its argument and UpValues
> can only be defined for tags not deeper than level 1 in an expression. In
> this post:
>
> http://stackoverflow.com/questions/5886066/overloading-seta-b-a-b/588...
>
> I demonstrated a method, which I also don't like, but which is at least
> safer because it tests for a
> specific data type. Generally, the still  safer way is to create your o=
wn
> data type and introduce your own
> assignment operator(s) - in this way, you don't have to modify Set at all=


  • Prev by Date: Re: Date based calculations
  • Next by Date: Geolocation in Session Information Message
  • Previous by thread: Re: Assigning part of indexed object
  • Next by thread: Re: Assigning part of indexed object