4

I am trying to use Numpy and vectorization operations to make a section of code run faster but I don't succeed to find a solution. If somebody has an idea... Thanks.

Here's the working code with loops:

y = np.zeros(len(tab))
for i in range(len(tab)):
    s =  0
    for n in range(len(coef[0])):
        s += coef[0][n] * ((a + b * np.dot(tab[i], vectors[n])) ** d)
    y[i] = s

Where,

  • tab: numpy.array(N,M)
  • vectors: numpy.array(P,M)
  • coef: numpy.array(1,P)
  • a, b, c: constants (a = 0, if it's more easy)
2
  • Can you include a sentence at the beginning of your question describing what the code is supposed to accomplish? It's hard to give a pure programmatic assessment. Commented May 17, 2015 at 19:29
  • @mprat - it's a part of SVM algorithm implementation, similar to this implementation link - lines 83-88 Commented May 17, 2015 at 20:28

2 Answers 2

4

You can use an approach based on np.einsum and matrix-multiplication with np.dot as listed below -

# Calculate "((a + b * np.dot(tab[i], vectors[n])) ** d)" part
p1 = (a + b*np.einsum('ij,kj->ki',tab,vectors))**d

# Include "+= coef[0][n] *" part to get the final output
y_vectorized = np.dot(coef,p1)

Runtime test

Dataset #1:

This is a quick runtime test comparing the original loopy approach with the proposed approach for some random values -

In [168]: N = 50
     ...: M = 50
     ...: P = 50
     ...: 
     ...: tab = np.random.rand(N,M)
     ...: vectors = np.random.rand(P,M)
     ...: coef = np.random.rand(1,P)
     ...: 
     ...: a = 3.233
     ...: b = 0.4343
     ...: c = 2.0483
     ...: d = 3
     ...: 

In [169]: %timeit original_approach(tab,vectors,coef,a,b,c,d)
100 loops, best of 3: 4.18 ms per loop

In [170]: %timeit proposed_approach(tab,vectors,coef,a,b,c,d)
10000 loops, best of 3: 136 µs per loop

Dataset #2:

With N, M and P as 150 each, the runtimes were -

In [196]: %timeit original_approach(tab,vectors,coef,a,b,c,d)
10 loops, best of 3: 37.9 ms per loop

In [197]: %timeit proposed_approach(tab,vectors,coef,a,b,c,d)
1000 loops, best of 3: 1.91 ms per loop
Sign up to request clarification or add additional context in comments.

Comments

0

Looks terrible. But is it what you need?

y = array([ sum( [coef[0][n] * ((a + b * np.dot(tab[i], vectors[n])) ** d) 
            for n in range(len(vectors[0]))] ) for i in range(len(tab)) ])

3 Comments

With the same dataset, my implementation: total runtime = 28min and for your implementation: total runtime = 15min. It's better, but isn't there a better solution, without using these 2 loops?
this isn't vectorizing, you still have 2 for loops even though you use numpy to speed it up a bit..
This just rewrites the 2 loop as list comprehensions. Still a Python loop, just a bit more efficient.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.