title: Using numba for cosine similarity between a vector and rows in a matix
body: <p>Found this <a href="https://gist.github.com/FedericoV/0e7d6d8c8794a99a7a42" rel="nofollow noreferrer">gist</a> using numba for fast computation of cosine similarity.</p>
  
  <pre><code>import numba
  
  @numba.jit(target='cpu', nopython=True)
  def fast_cosine(u, v):
      m = u.shape[0]
      udotv = 0
      u_norm = 0
      v_norm = 0
      for i in range(m):
          if (np.isnan(u[i])) or (np.isnan(v[i])):
              continue
  
          udotv += u[i] * v[i]
          u_norm += u[i] * u[i]
          v_norm += v[i] * v[i]
  
      u_norm = np.sqrt(u_norm)
      v_norm = np.sqrt(v_norm)
  
      if (u_norm == 0) or (v_norm == 0):
          ratio = 1.0
      else:
          ratio = udotv / (u_norm * v_norm)
      return ratio
  </code></pre>
  
  <p>Results look promising (500ns vs. only 200us without jit decorator in my machine).</p>
  
  <p>I would like to use numba to <strong>parallelize</strong> this computation between a vector <code>u</code> and a candidate matrix <code>M</code> -- i.e. cosine across each row.</p>
  
  <p>Example:</p>
  
  <pre><code>def fast_cosine_matrix(u, M):
      """
      Return array of cosine similarity between u and rows in M
      &gt;&gt;&gt; import numpy as np
      &gt;&gt;&gt; u = np.random.rand(100)
      &gt;&gt;&gt; M = np.random.rand(10, 100)
      &gt;&gt;&gt; fast_cosine_matrix(u, M)
      """
  </code></pre>
  
  <p>One way is to just rewrite with second input a matrix. But I get a <code>NotImplementedError</code> if I try to iterate over the rows of a matrix. Going to try just using slices.</p>
  
  <p>I thought about using <code>vectorize</code> but I can't get it to work.</p>