Parallelization of multiple numpy.linalg.multi_dot calls - python

I'm trying to parallelize this function:
def update_G_left(self):
num = np.linalg.multi_dot([self.association_matrix,
self.G_right, self.S.transpose()])
den = np.linalg.multi_dot([self.G_left, self.S, self.G_right.transpose(),
self.G_right, self.S.transpose()])
for am in self.dep_own_left_other_left:
num += np.linalg.multi_dot([am.association_matrix,
am.G_right, am.S.transpose()])
den += np.linalg.multi_dot([self.G_left, am.S, am.G_right.transpose(),
am.G_right, am.S.transpose()])
for am in self.dep_own_left_other_right:
num += np.linalg.multi_dot([am.association_matrix.transpose(),
am.G_left, am.S])
den += np.linalg.multi_dot([self.G_left, am.S.transpose(),
am.G_left.transpose(), am.G_left, am.S])
div = np.divide(num, den + sys.float_info.min)
return np.multiply(self.G_left, div)
The function is working well, but when I use pools:
def update_G_left(self):
num = np.linalg.multi_dot([self.association_matrix, self.G_right, self.S.transpose()])
den = np.linalg.multi_dot([self.G_left, self.S, self.G_right.transpose(), self.G_right, self.S.transpose()])
with multiprocessing.Pool(6) as pool:
for x in pool.map(np.linalg.multi_dot,
[[am.association_matrix, am.G_right, am.S.transpose()]
for am in self.dep_own_right_other_left]):
num += x
for x in pool.map(np.linalg.multi_dot,
[[self.G_left, am.S,
am.G_right.transpose(), am.G_right, am.S.transpose()]
for am in self.dep_own_right_other_left]):
den += x
for x in pool.map(np.linalg.multi_dot,
[[am.association_matrix.transpose(), am.G_left, am.S]
for am in self.dep_own_right_other_right]):
num += x
for x in pool.map(np.linalg.multi_dot,
[[self.G_left, am.S.transpose(),
am.G_left.transpose(), am.G_left, am.S]
for am in self.dep_own_right_other_right]):
den += x
div = np.divide(num, den + sys.float_info.min)
return np.multiply(self.G_left, div)
Now it is no more working.
I get the error ValueError: operands could not be broadcast together with shapes (10,6) (7,6) (10,6) at the second num += x .
I'm wondering why because i don't see any differences in the code.
There are other patterns to parallelize my function?

Related

Rewrite Python code for compilation it in PyPy

I am stuck in rewriting Python code to compile it in PyPy. My task is to calculate number of inversions in a list using modification of merge sort. Input data brings from input.txt, the result of the code is written in output.txt. My last attempt to do this looks like:
import sys
def merge(a, b, inverse_num):
n, m = len(a), len(b)
i = 0
j = 0
c = []
while i < n or j < m:
if j == m:
c.append(a[i])
i += 1
# inverse_num += 1
elif i < n and a[i] <= b[j]:
c.append(a[i])
i += 1
elif i < n and a[i] > b[j]:
c.append(b[j])
j += 1
inverse_num += n - i
if j == m and i == n - 1:
c.append(a[i])
i += 1
else:
c.append(b[j])
j += 1
return c, inverse_num
def merge_sort(arr, inverse_num=0):
n = len(arr)
if n == 1:
return arr, inverse_num
l = arr[:(n//2)]
r = arr[(n//2):n]
l, inverse_num_l = merge_sort(l, inverse_num)
r, inverse_num_r = merge_sort(r, inverse_num)
inverse_num = inverse_num_l + inverse_num_r
return merge(l, r, inverse_num)
def main():
with open('input.txt') as f:
n = int(f.readline().split()[0])
in_list = list(map(int, f.readline().split()))
output_file = open('output.txt', 'w')
sorted_arr, inverse_num = merge_sort(in_list, inverse_num=0)
output_file.write(str(inverse_num))
output_file.close()
return 0
def target(*args):
return entry_point, None
def entry_point(argv):
main()
return 0
if __name__ == "__main__":
entry_point(sys.argv)
After compilation it with command pypy "C:/pypy_compile/pypy-src/translate.py" Task2.py
error appears:
[translation:ERROR] TypeError: method_split() takes at least 2 arguments (1 given)
Processing block:
block#27[v4...] is a <class 'rpython.flowspace.flowcontext.SpamBlock'>
in (Task2:44)main
containing the following operations:
v6 = getattr(v5, ('split'))
v7 = simple_call(v6)
--end--
Thanks in advance for helping.

How to divide code using functions Python 3.x

I got my code to work but now I need to divide it into functions input(), processing() and output().
lista=[]
lista = [int(clan) for clan in input("Unesi članove niza : ").split(',')]
lista.reverse()
rezultat=[]
c=0
for i in lista:
if i < 0:
i = i * -1
t = i
rev = 0
rev = rev * 10 + t % 10
t = t // 10
i = i * -1
rezultat.append(str(i))
else:
t = i
rev = 0
while t > 0:
rev = rev * 10 + t % 10
t = t // 10
if rev == i:
c=c+1
rezultat.append(str(i))
if c == 0:
print("")
print(','.join(rezultat))
I do not really know how to do it so it would be nice if someone can help me
Something like this...
def input(clan):
lista = [int(clan) for clan in input("Unesi članove niza : ").split(',')]
lista.reverse()
return lista
def processing(lista):
rezultat = []
c = 0
for i in lista:
if i < 0:
i = i * -1
t = i
rev = 0
rev = rev * 10 + t % 10
t = t // 10
i = i * -1
rezultat.append(str(i))
else:
t = i
rev = 0
while t > 0:
rev = rev * 10 + t % 10
t = t // 10
if rev == i:
c=c+1
rezultat.append(str(i))
if c == 0:
print("")
return(','.join(rezultat))
def output(result):
print(result)
if __name__ == '__main__':
result_list = input(clan)
result = processing(result_list)
output(result)
Try using the def command,
like this
def inp(): #declare a function
#your commands
inp() #run the commands
Don't forget to declare global variables a.k.a. those variable that you might alter in many functions by using the global command.
try this
def get_input():
lista = [int(clan) for clan in input("Unesi članove niza : ").split(',')]
lista.reverse()
return lista
def process_input(input):
rezultat=[]
c=0
for i in input:
if i < 0:
i = i * -1
t = i
rev = 0
rev = rev * 10 + t % 10
t = t // 10
i = i * -1
rezultat.append(str(i))
else:
t = i
rev = 0
while t > 0:
rev = rev * 10 + t % 10
t = t // 10
if rev == i:
c=c+1
rezultat.append(str(i))
if c == 0:
print("")
return rezultat
def main():
lista = get_input()
result = process_input(lista)
def output(xlist):
return ','.join(xlist)
output(result)
if __name__ == "__main__":
main()
that should work, but I don't see the need to divide it into functions, since the code might even work well as one function.

Best way to run a function in main function when one of the parameters is not in the scope

Basically my brain is not working right now can't figure out the best way to resolve this error. builtins.NameError: name 'numIters' is not defined
I know this problem is that numIters is not defined in its scope but don't know the best solution to fix that.
Here is the bulk of my code
import random
alg = int(input("Select the sorting algorithm \n 1 - linear search \n 2 - binary search \nEnter Choice: "))
n = int(input("Choose the size of the list: "))
def main():
createList(n,alg)
print(runTest(values,n,alg))
printResults(alg,n,numIters)
#print(linearSearch(values,2))
#print(binarySearch(values, 2))
def createList(n,alg):
global values
values = []
random.seed(1456)
for j in range(n):
values.append(random.randint(0, 2*n))
while len(values) == n:
if alg == 2:
values.sort()
print(values)
return values
elif alg == 1:
print(values)
return values
def linearSearch(values, target):
numIters = 0
for i in range(len(values)):
numIters = numIters + 1
if values[i] == target:
return numIters
return -1
def binarySearch(values, target):
numIters = 0
start = 0
high = len(values) - 1
while start <= high:
middle = (start + high)//2
if values[middle] == target:
numIters = numIters + 1
return numIters
elif values[middle] > target:
numIters = numIters + 1
high = middle - 1
else:
numIters = numIters + 1
start = middle + 1
return -1
def runTest(values,n,alg):
if alg == 2:
count = 0
for j in range(n * 2):
count = count + 1
tgt = random.randint(0, 2*n)
binarySearch(values, tgt)
return count
elif alg == 1:
count = 0
for j in range(n * 2):
count = count + 1
tgt = random.randint(0, 2*n)
linearSearch(values, tgt)
return count
def printResults(alg, n, numIters):
avgIter = n / numIters
if alg == 2:
algType = Binary
if alg == 1:
algType = Linear
print("Results \n n = %d \n %s = %f.2 " % (n,algtype,avgIter))
main()
Thank you in advance for any help given as I am still trying to learn and understand how python works as a whole.
You need to return numIters so that you can pass it to the next function. It looks like it currently gets returned from binarySearch and linearSearch to runTest, but it gets discarded there; just bubble it up like this (I'm going to add type annotations and comments to help me keep track of what's going on):
from typing import List, Tuple
def runTest(values: List[int], n: int, alg: int) -> Tuple[int, int]:
"""Returns count, numIters"""
numIters = 0 # default value in case n is so small we don't iterate
if alg == 2:
count = 0
for j in range(n * 2):
count = count + 1
tgt = random.randint(0, 2*n)
numIters = binarySearch(values, tgt)
return count, numIters
elif alg == 1:
count = 0
for j in range(n * 2):
count = count + 1
tgt = random.randint(0, 2*n)
numIters = linearSearch(values, tgt)
return count, numIters
raise ValueError("alg needs to be 1 or 2!")
Now in your main() you can do:
def main():
createList(n, alg)
count, numIters = runTest(values, n, alg)
print(count)
printResults(alg, n, numIters)

list assignment index out of range by code python?

I keep getting an
IndexError: list assignment index out of range.
The error on line 78
This code is written to find motif DNA to bioinformatics
How we can solve this error or the problem ?
Here is my code:
from math import log
class MotifMedianFinding(object):
def __init__(self, input_file):
super(MotifMedianFinding, self).__init__()
self.input_lines = open("C:\\Users\\A.Khassawneh\\Desktop\\fasta.txt")
def output(self):
#main method to call both functions
sequences = {}
for line in self.input_lines:
if '>' in line:
sequences[line] = self.input_lines.next()
for label, seq in sequences.iteritems():
print "DNA:" + seq + "\n\n\n\n\n"
median = self.median_string(seq, 5,5, len(seq))
self.motif(seq, median,5,len(seq))
def median_string(self, dna, t, n, l):
#bound and search method of calulating median string
start_pos = start_pos = [1,1,1,1,1]
best_dist = 1000000000
i = 1
while i > 0:
if i < l:
prefix = str(start_pos)
opt_dist = self.hamming_score(prefix, dna)
if opt_dist > best_dist:
s,i = self.bypass(start_pos,i,l,4)
else:
s,i = self.next_vertex(start_pos,i,l,4)
else:
word = str(s)
if self.hamming_score(word, dna) < best_dist:
best_dist = self.hamming_score(word, dna)
bestword = word
s,i = self.next_vertex(start_pos,i,l,4)
print "Best Word: %s (tot_dis = %s)" % (bestword,best_dist)
return bestword
def motif(self, dna, t, n, l):
#bound and search method of calculating motif
start_pos = [1,1,1,1,1]
best_score = 0
i = 1
while 1 > 0:
if i < t:
opt_score = Score(s, i, dna) + (t-1) * l
if opt_score < best_score:
start_pos, i = self.bypass(start_pos, i, t, n-l+1)
else:
start_pos, i = self.next_vertex(start_pos, i, t, n-l+1)
else:
if self.score(start_pos, dna) > best_score:
best_score = self.score(start_pos)
best_motif = str(s)
start_pos, i = self.next_vertex(start_pos, i, t, n-l+1)
print "motif consensus string: %s (consensus_score = %s) " % (best_motif, best_score)
print "motif positions/string s=(s1..st): %s" % ', '.join(start_pos)
return best_motif
def bypass(vertex, level, l, k):
#skip uncessary calculations in the tree
j = level
for ind in xrange(j,1,-1):
if a[j] < k:
a[j] = a[j] + 1
return vertex, j
return vertex, 0
def next_vertex(self, vertex, level, L, k):
#transverse the tree of a strand of genes
if level <L:
vertex[level+1] = 1
return vertex,level+1
else:
j = L
for ind in xrange(j,1,-1):
if vertex[ind] < k:
vertex[j] = vertex[j] + 1
return vertex, j
return vertex, 0
def score(start_pos):
# biggest score of motif
total = 0
for i in start_pos:
total += i
return total
def hamming_score(self, s, dna):
pass
motif_median = MotifMedianFinding('HMP-part.fa')
motif_median.output()
xrange(x,y) goes from x to y-1 (x, x+1.... y-1). In your code, it would have been fine to do xrange(1,j), because that wouldn't have included j. But if you swap it to xrange(j,1,-1), you go (j, j-1.... 2).
Basically, you probably need to change it to xrange(j-1,0,-1) depending on your intended range.

python 2d array condition

i'm working on 8 queen(Genetic Algorithm) program with python 3.4
i use a matrix for keep queens position. but i have an error in sort() function,i dont underestand this error.
please help me ...
my code:
from random import randrange
__author__ = 'Moein'
class NQueen:
NUM_COLS = 8
POPULATIONS = 100
current = [[]]
def __init__(self):
self.current = [[0 for col in range(self.NUM_COLS + 1)] for row in range(self.POPULATIONS)]
# generate first Generation
for i in range(0, self.POPULATIONS):
for j in range(0, self.NUM_COLS):
self.current[i][j] = randrange(self.NUM_COLS)
count = 0
condition = True
while condition:
self.crossover()
self.mutation()
self.fitness()
self.sort()
count += 1
print(self.current)
# print(self.current[0])
if self.current[0][self.NUM_COLS] == 0:
condition = False
print(self.current[0])
pass
def fitness(self):
count = 0
for i in range(0, self.POPULATIONS):
for j in range(0, self.NUM_COLS):
for x in range(j + 1, self.NUM_COLS):
if self.current[i][j] == self.current[i][x]:
count += 1
if abs(j - x) == abs(self.current[i][j] - self.current[i][x]):
count += 1
self.current[i][self.NUM_COLS] = count
count = 0
pass
def sort(self):
for i in range(0, self.POPULATIONS - 1):
for j in range(i + 1, self.POPULATIONS):
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
for x in range(0, self.NUM_COLS + 1):
temp = self.current[i][x]
self.current[i][x] = self.current
self.current[j][x] = temp
pass
def crossover(self):
_new = [[0 for x in range(self.NUM_COLS + 1)] for x in range(self.POPULATIONS)]
for i in range(0, int(self.POPULATIONS / 2)):
for j in range(0, int(self.NUM_COLS / 2)):
_new[i + 49][j] = self.current[i][j]
_new[i + 49 + 1][j] = self.current[i + 1][j]
for j in range(int(self.NUM_COLS / 2), self.NUM_COLS):
_new[i + 49][j] = self.current[i][j]
_new[i + 49 + 1][j] = self.current[i + 1][j]
self.current = _new
pass
def mutation(self):
for i in range(0, self.POPULATIONS):
self.current[i][randrange(self.NUM_COLS)] = randrange(self.NUM_COLS)
pass
nQueen = NQueen()
print(nQueen.current[0])
and my error:
Traceback (most recent call last):
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 81, in <module>
nQueen = NQueen()
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 27, in __init__
self.sort()
File "C:/Users/Moein/PycharmProjects/NQueen/project.py", line 54, in sort
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
TypeError: unorderable types: list() > int()
self.current[i][x] = self.current
I guess that its this line causing the problem, since
self.current
is a list, so you are setting
self.current[i][x]
to be a list instead of an int. So at this point:
if self.current[i][self.NUM_COLS] > self.current[j][self.NUM_COLS]:
when you try to compare those values it might happen, that you compare
an int with a list, which causes the error.
TypeError: unorderable types: list() > int()
Cheers
EDIT:
I just tried it out.
Replacing
self.current
with an int for example 2 prevents the Exception from occurring.

Categories