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

Out = 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 =

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 =

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

Out = 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 =
conditionalSum[i + j + k,  i + j + k < 8, {i, 3}, {j, 1, 4, 1}, {k, {1, 3,
4, 6}}]

Out = 116

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

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

Out = 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