mammy wood
mammy wood

Reputation: 143

multiple sigma notations python

given this formula implement it in python

enter image description here

So for n = 3

x = []
y = []
for i in range(1, 4):
    x.append(i)

for j in range(1, 4):
    y.append(j**2)



total = 0
for i in range(len(x)):
    for j in range(len(y)):

        total = total + x[i] *  y[j] 
print(total)

this works. But say I wanted a third sigma notation such as

enter image description here

Which would be the exact same as above by just adding another loop k.

My question is if theres a way to generalize this in a function given n, the value inside (i.e. j^2 * i). I'm stumped on generalizing more loops

def manysums(n, L : i.e. [[1, 2,3], [1,4,9], [1, 8, 27]]):
    pass

like above where the values inside the list totals the sum value

L = [[1, 2,3], [1,4,9], [1, 8, 27], [1,2,3]]

would be 4 sigma notation which would be 4 four loops. I'm wondering whether something like this can be generalized in a function

Upvotes: 3

Views: 1473

Answers (4)

hiro protagonist
hiro protagonist

Reputation: 46869

my suggestion is:

from itertools import product
from operator import mul
from functools import reduce

n = 3
powers = zip(*((i, i**2, i**3) for i in range(1, n+1)))
s = sum(reduce(mul, p) for p in product(*powers))

and you could even generalize powers to a function:

def powers(n, exponents):
    return [[i**e for i in range(1, n+1)] for e in exponents]

powers(n=3, exponents=[2, 1, 3]))
# [[1, 4, 9], [1, 2, 3], [1, 8, 27]]

Explanation:

using product with the repeat option the sum can be written as:

from itertools import product 

n = 3
s = sum(j**2 * i * k**3 for i, j, k in product(range(1, n+1), repeat=3)))
print(s)

this can easily be generalized to more variables.

if efficiency is an issue you can pre-calculate the powers and then sum them:

powers = list(zip(*((i, i**2, i**3) for i in range(1, n+1))))
# [(1, 2, 3), (1, 4, 9), (1, 8, 27)]

s = sum(p0 * p1 * p2 for p0, p1, p2 in product(*powers))

or, in order to keep the notation short if you have way more variables you can use functools.reduce:

from operator import mul
from functools import reduce

s = sum(reduce(mul, p) for p in product(*powers))

Upvotes: 0

Jeronimo
Jeronimo

Reputation: 2387

Here's a solution without any additional imports, using recursion to make the amount of inner loops dynamic. It takes the inner formula as a function, of which the number of arguments is taken to determine the recursion depth needed.

def manysums(f, n):
    depth = f.__code__.co_argcount   # number of nested loops        
    def inner_loop(vals):        
        if len(vals) == depth - 1:     # last (most-inner) loop?
            return sum(f(*(vals + (i,))) for i in range(1,n+1))  
        else:
            return sum(inner_loop(vals + (i,)) for i in range(1,n+1))                    
    return inner_loop(())

Use like this:

f = lambda i, j, k : j**2 * i * k**3
manysums(f, 3)
# --> 3024

f = lambda i, j, k, l : j**2 * i * k**3 * l
manysums(f, 3)
# --> 18144

Upvotes: 0

gmds
gmds

Reputation: 19885

A solution taking advantage of numpy:

import numpy as np

from functools import reduce

def multiple_sigma(n, exponents):
    arrays = [np.arange(1, n + 1) ** exponent for exponent in exponents]
    return reduce(np.multiply.outer, arrays).sum()

# j ** 2, i ** 1, k ** 3 for n in [1, 3]
multiple_sigma(n=3, exponents=[2, 1, 3]) 

Output:

3024

Upvotes: 1

c2huc2hu
c2huc2hu

Reputation: 2497

See itertools.product. If you're interested in how it's implemented, there's a mock implementation in the link

Cartesian product of input iterables.

Roughly equivalent to nested for-loops in a generator expression. For example, product(A, B) returns the same as ((x,y) for x in A for y in B).

The nested loops cycle like an odometer with the rightmost element advancing on every iteration. This pattern creates a lexicographic ordering so that if the input’s iterables are sorted, the product tuples are emitted in sorted order.

from itertools import product
for i,j,k in product([1,2,3],[1,4,9],[1,8,27]):
  print(j**2 * i * k**3)

Upvotes: 1

Related Questions