Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Series sum in python

Tags:

python

numpy

Is there is a built-in function in python, numpy or one of its libraries can get sum of series like this one:

list1 = [2,3,4]
list2 = [3,3,3]

enter image description here

where x and y are lists and L is the length of x or y.

Lastly if there is no built-in function do that, I tried another code like :

Total = sum ((i for i in list1) * (j for j in list2))

Sure, it doesn't work but I need something near that or near this one:

Total = sum (i * j for i in list1 and j in list2 )

Note : I can build my own function to do that but I am looking for a simple, fast or built-in one, so please don't give me your own function.

Edit : I want general form to do that so I can use this form when there are as an example Log(n) or another kind of math in the series.

enter image description here

like image 373
mohammed awni Avatar asked Dec 05 '22 14:12

mohammed awni


2 Answers

That's literally just a dot product:

result = numpy.dot(list1, list2)

Note that if you're using NumPy, you shouldn't be using lists to represent your matrices and vectors. NumPy arrays are much more efficient and convenient for that.

like image 126
user2357112 supports Monica Avatar answered Dec 17 '22 16:12

user2357112 supports Monica


for build-in you can use zip to group together elements in the same index position

list1 = [2,3,4]
list2 = [3,3,3]
result = sum( x*y for x,y in zip(list1, list2) )

About the edit

A buil-in version would be

from math import log
result = sum( log(i)*y for i,y in enumerate(list1,1) )

a more generalized version would be

enter image description here

import operator
def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul):
    return sum(map(mul, vec1, vec2))    

where you can provide whatever function you like for any of its part, then the first one is

result = dotproduct(list1,list2)

and the second is could be

result = dotproduct(range(1,len(list1)+1),list1, mul=lambda i,x:log(i)*x )
#                        ^ the i                    ^ how to operate

or

result = dotproduct(map(log,range(1,len(list1)+1) ), list1 )
#                           ^ the log i

the point being that you calculate the second vector accordingly

with numpy is more easy

import numpy as np
logi = np.log(np.arange(1,len(list1)+1)
result = np.dot(logi,list1)

which again boils down to calculate the parts accordingly


you can also make such that instead of receiving 2 vectors/lists it only work with one and receive a function that work in the element and its index

enter image description here

def sum_serie(vect, fun = lambda i,x:x, i_star=0): #with that fun, is like the regular sum
    return sum( fun(i,x) for i,x in enumerate(vect, i_star) )

and use it as

result = sum_serie( list1, lambda i,x:log(i)*x, 1)

from the comments, if I get it right, then something like this

from itertools import islice
def sum_serie(vect, *slice_arg, fun = lambda x:x): #with that fun, is like the regular sum
    """sum_serie(vect, [start,]stop[,step], fun = lambda x:x)"""
    if not slice_arg:
        slice_arg = (0,None,None)
    return sum( fun(x) for x in islice(vect, *slice_arg) )

or with enumerate as before

from itertools import islice
def sum_serie_i(vect, *slice_arg, fun = lambda i,x:x): #with that fun, is like the regular sum
    if not slice_arg:
        slice_arg = (0,None,None)
    return sum( fun(i,x) for i,x in islice(enumerate(vect), *slice_arg) )

and use, for example as

sum_serie( x, 0, 100, 2, fun=lambda xi: c*xi) #for arbitrary constant c
sum_serie_i( x, 0, 100, 2, fun=lambda i,xi: log(i)*xi)

Note: this way it accept the serie/iterable/whatever and at most 3 positional argument with the same meaning as those from range

Note 2: that is for PY3 which make fun a key-word only argument, in python 2 the same effect is accomplished with

def sum_serie_i(vect, *slice_arg, **kargv): 
    fun = kargv.get('fun', lambda i,x:x) #with that fun, is like the regular sum
    if not slice_arg:
        slice_arg = (0,None,None)
    return sum( fun(i,x) for i,x in islice(enumerate(vect), *slice_arg) )
like image 20
Copperfield Avatar answered Dec 17 '22 16:12

Copperfield