MathGroup Archive 2009

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

Search the Archive

Re: Is it possible to impose a condition on an iterator of

  • To: mathgroup at smc.vnet.net
  • Subject: [mg101556] Re: [mg101499] Is it possible to impose a condition on an iterator of
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Fri, 10 Jul 2009 06:43:40 -0400 (EDT)
  • References: <200907090552.BAA16854@smc.vnet.net>

Hi Mauro,

You can use the particular syntax of Sum which allows to supply a list of
values to be summed over:

In[1] =
With[{iterlist = Select[Range[1, 20] , # <= 6 || # >= 12 &]},
 Sum[a^2 - 3 a/(4 a^2), {a, iterlist}]]

Out[1] = 69209343871/28217280

This is however not very general. What if, for instance, you need
to do a multi-dimensional sum and exclude some points according to the
test that mixes different coordinates (iteration variables). Here is my
attempt to implement a function with such additional functionality but  with
the standard iterator syntax of Sum:

In[2] =

ClearAll[conditionalSum];
SetAttributes[conditionalSum, HoldAll];
conditionalSum[expr_, test_, iterators__] :=
  With[{heldVars = Replace[Hold[iterators], {var_, __} :> var, 1]},
   Block @@
    Append[Replace[heldVars, Hold[vars___] :> Hold[{vars}], {0}],
     Unevaluated[
      With[{itervalues =
         Flatten[Table[
           If[TrueQ[test], List @@ heldVars, Sequence @@ {}],
           iterators], Length[Hold[iterators]] - 1]},
       Total@Map[expr /. Thread[List @@ heldVars -> #] &,
         itervalues]]]]];


This uses the fact that Table has the same iterator syntax as Sum and can be
used to generate expression values and filter out points on which <test>
does not give True. It also uses Block to localize iteration variables,
so it won't suffer from possible global values set for the iterator
variables. So:

In[3] =

a = 1;
conditionalSum[a^2 - 3 a/(4 a^2), a <= 6 || a >= 12, {a, 1, 20}]

Out[3] = 69209343871/28217280

(I gave a global value to <a> deliberately).

This will sum over 3 coordinates, with all 3 iterators using different
iterator sematics:

In[4] =
conditionalSum[i + j + k,  i + j + k < 8, {i, 3}, {j, 1, 4, 1}, {k, {1, 3,
4, 6}}]

Out[4] = 116

It can also handle cases when the limits of the "outer" variables  depend
on inner variables:

In[5]  = conditionalSum[i + j + k,  i + j + k < 8, {i, 3}, {j, 1, i, 1}, {k,
{1, 3, 4, 6}}]

Out[5] = 68

I did a few more tests indicating that this works correctly, but I don't
exclude the possibility of some subtle bugs that I failed to spot. I did not
supply type-checks for the input parameters (iterators in particular) and
error messages (this can be done easily).  Also, I don't know which cool
features of the standard Sum I am missing with this approach - perhaps there
are lots of symbolic simplifications or built-in rules associated with Sum,
also it is certainly faster. But for some simple things conditionalSum may
be convenient.

Hope this helps.

Regards,
Leonid






On Wed, Jul 8, 2009 at 10:52 PM, Mauro <mauro at nonoyahoo.com> wrote:

> I would like to perform a summation of this type,
>
> Sum[a^2 - 3 a/(4 a^2), {a, 1, 20}]
>
> excluding however some values of the iteratore, I would for instance
> like to exclude the values than to greater of 6 and inferior to 12. Is
> it possible?
>
> Thanks
>
>



  • Prev by Date: Re: stirring chocolate pudding backwards: identifying coordinates
  • Next by Date: Re: Is it possible to impose a condition on an iterator
  • Previous by thread: Re: Is it possible to impose a condition on an iterator
  • Next by thread: Re: Is it possible to impose a condition on an iterator