Mismatch specification error

Hi @DannyWeitekamp
I started exploring the use of structured numpy arrays. In theory, one could progressively build dtypes for a point, edge and a triangle. My main concern then is how to access the data for operations. E.g. want to generate the plane equation of a triangle… I need access to each point data (passing by each edge) and convert them so that I can then do some calculation (f that makes sense). Doing this with structured arrays would be cumbersome (mainly because of the conversion to a normal array).

More specifically, here I am referring to the use of

from numpy.lib.recfunctions import structured_to_unstructured

to be able to use the actual values stored in the structured arrays for operations. This operation is not recognized in numba.

It’s late so I might have made a mistake somewhere, but this is the gist of what I was thinking. You can use view instead of the numpy function you mention.

import numpy as np
import numba
from numba import njit, f4

np_point_type = np.dtype([
    ('x', np.float32),
    ('y', np.float32),
    ('z', np.float32),
])
point_type = numba.from_dtype(np_point_type)

@njit(point_type[::1](point_type[:, ::1]), cache=True)
def find_norms(triangles):
    norms = np.empty(len(triangles), dtype=point_type)
    for i, t in enumerate(triangles):
        # edges
        ax = t[1].x-t[0].x
        ay = t[1].y-t[0].y
        az = t[1].z-t[0].z
        bx = t[2].x-t[1].x
        by = t[2].y-t[1].y
        bz = t[2].z-t[1].z

        # Cross product
        nx = +(ay*bz - az * by)
        ny = -(ax*bz - az * bx)
        nz = +(ax*by - ay * bx)

        # Norm
        dist = np.sqrt(nx * nx + ny * ny + nz * nz)
        norms[i].x = nx / dist
        norms[i].y = ny / dist
        norms[i].z = nz / dist

    return norms

# Three random triangles
rand_vals = np.random.rand(3, 3, 3).astype(dtype=np.float32)
triangles = rand_vals.view(dtype=np_point_type).reshape((3,3))
print(find_norms(triangles))

This is maybe more verbose than your OO implementation, and I don’t even bother defining special edge or triangles types, but it gets the job done. And I expect is quite fast.

Many thanks @DannyWeitekamp ! I am hoping to make a function out of the view/reshape operations.
Thanks again!

1 Like

Hi @DannyWeitekamp
It took me a while to figure out that within a numba function you access data in a numpy structured array using .dot notation. So if you were to remove the following line

@njit(point_type[::1](point_type[:, ::1]), cache=True)

the above code would not work. Based on this, I have a new query but I will posted as a new topic.