## Issue

There is a procedure involving a search over an (eventually) big number of parameter combinations that I am trying to speed up using numba.

I tried to change my initial code to make it compatible but still got a TypingError I do not know how to resolve. I had many issues when using ‘np.asarray()’ so I removed that and am mostly dealing with standard lists now but it still does not work.

I will only mention the parts of the code that seem relevant given the error message, if more is needed, I will supply that too (just to keep it fairly short).

The seemingly crucial part of the error message (the rest, as far as I can tell, is just due to this function being called within another which is again called within another) reads:

Failed in nopython mode pipeline (step: nopython frontend)

No implementation of function Function(<function dot at 0x0000021490EA2400>) found for signature:dot(list(list(float64)<iv=None>)<iv=None>, reflected list(float64)<iv=None>)

There are 4 candidate implementations:

– Of which 4 did not match due to:

Overload in function ‘_OverloadWrapper._build..ol_generated’: File: numba\core\overload_glue.py: Line 131.

With argument(s): ‘(list(list(float64)<iv=None>)<iv=None>, reflected list(float64)<iv=None>)’:

Rejected as the implementation raised a specific error:

TypingError: Failed in nopython mode pipeline (step: nopython frontend)

No implementation of function Function() found for signature:

```
>>> stub(list(list(float64)<iv=None>)<iv=None>, reflected list(float64)<iv=None>)
```

It seems to originate from the function ‘nvaxes_lab’ defined as follows:

```
# reference position of NV axis vectors, each row holds the orientation (vector) of one NV axis
nvaxes_ref = [[1.0, 1.0, 1.0],
[-1.0, 1.0, -1.0], [1.0, -1.0, -1.0], [-1.0, -1.0, 1.0]]
@njit()
def rot_euler(a, b, g):
"""
:param a: float, angle of third rotation (around z-axis) in radians
:param b: float, angle of second rotation (around x-axis) in radians
:param g: float, angle of first rotation (around z-axis) in radians
:return: rotation matrix for a general rotation around the Euler angles a (=alpha), b (=beta), g (=gamma) defined
as follows: rot_euler(a,b,g) = rotZ(a).rotX(b).rotZ(g)
"""
return [[np.cos(a) * np.cos(g) - np.cos(b) * np.sin(a) * np.sin(g),
-np.cos(b) * np.cos(g) * np.sin(a) - np.cos(a) * np.sin(g), np.sin(a) * np.sin(b)],
[np.cos(g) * np.sin(a) + np.cos(a) * np.cos(b) * np.sin(g),
np.cos(a) * np.cos(b) * np.cos(g) - np.sin(a) * np.sin(g), -np.cos(a) * np.sin(b)],
[np.sin(b) * np.sin(g), np.cos(g) * np.sin(b), np.cos(b)]]
@njit()
def nvaxes_lab(a, b, g):
"""
:param a: float, angle of third Euler rotation (around z-axis) in radians
:param b: float, angle of second Euler rotation (around x-axis) in radians
:param g: float, angle of first Euler rotation (around z-axis) in radians
:return: numpy array of dimensions 3x4, each row holds the orientation (vector) of the corresponding NV-axis
after rotation by the Euler angles a,b,g
"""
return [np.dot(rot_euler(a, b, g), nvaxes_ref[0]).astype(float), np.dot(rot_euler(a, b, g), nvaxes_ref[1]).astype(float),
np.dot(rot_euler(a, b, g).astype(float), nvaxes_ref[2]), np.dot(rot_euler(a, b, g), nvaxes_ref[3]).astype(float)]
```

The problem seems to be the dot product in each component of the array returned in ‘nvaxes_lab’ … unfortunately, I have no idea how to define the arrays (I tried out multiple versions) or what else I could do to make this error disappear since this is the first time I am using numba.

I would appreciate your help!

## Solution

You have a couple of issues. First, the actual error you are seeing comes from when numba compile your function, it uses the C implementations of the numpy functions. Those implementations expect numpy arrays, not lists. So the error:

dot(list(list(float64)<iv=None>)<iv=None>, reflected list(float64)<iv=None>)

is basically trying to tell you that the `np.dot`

function doesn’t know how to handle lists. In the python version, it will coerce the lists to a numpy array, but I guess not in the C/numba version. You can either wrap `np.array`

around each list, or a better option would be to output an array `rot_euler`

.

Next, it is best practice to not reference mutable variables that are defined outside the scope of the function that you are trying to JIT. In `nvaxes_lab`

, you reference each of the elements of `nvaxes_ref`

. You are better off passing those in as a parameter of the function, and to be consistent, also make them an array.

Last, you docstring doesn’t match your return type for `nvaxes_lab`

. You can just vstack the entire list to make it an array.

In terms of converting stuff to floats, because the `nvaxes_ref`

array is already a float array, all of the outputs will be floats as well, so you can drop the `astype`

methods.

```
import numpy as np
from numba import njit
nvaxes_ref = np.array([
[1.0, 1.0, 1.0],
[-1.0, 1.0, -1.0],
[1.0, -1.0, -1.0],
[-1.0, -1.0, 1.0]
])
@njit
def rot_euler(a, b, g):
"""
:param a: float, angle of third rotation (around z-axis) in radians
:param b: float, angle of second rotation (around x-axis) in radians
:param g: float, angle of first rotation (around z-axis) in radians
:return: rotation matrix for a general rotation around the Euler angles
a (=alpha), b (=beta), g (=gamma) defined as follows:
rot_euler(a,b,g) = rotZ(a).rotX(b).rotZ(g)
"""
return np.array([
[
np.cos(a) * np.cos(g) - np.cos(b) * np.sin(a) * np.sin(g),
-np.cos(b) * np.cos(g) * np.sin(a) - np.cos(a) * np.sin(g),
np.sin(a) * np.sin(b)
],
[
np.cos(g) * np.sin(a) + np.cos(a) * np.cos(b) * np.sin(g),
np.cos(a) * np.cos(b) * np.cos(g) - np.sin(a) * np.sin(g),
-np.cos(a) * np.sin(b)
],
[
np.sin(b) * np.sin(g),
np.cos(g) * np.sin(b),
np.cos(b)
]
])
@njit
def nvaxes_lab(a, b, g, refs):
"""
:param a: float, angle of third Euler rotation (around z-axis) in radians
:param b: float, angle of second Euler rotation (around x-axis) in radians
:param g: float, angle of first Euler rotation (around z-axis) in radians
:return: numpy array of dimensions 3x4, each row holds the orientation (vector)
of the corresponding NV-axis after rotation by the Euler angles a,b,g
"""
return [
np.dot(rot_euler(a, b, g), refs[0]),
np.dot(rot_euler(a, b, g), refs[1]),
np.dot(rot_euler(a, b, g), refs[2]),
np.dot(rot_euler(a, b, g), refs[3])
]
```

Answered By – James

Answer Checked By – Clifford M. (BugsFixing Volunteer)