Vec2/vec3/mat3 glsl alternative for numba?

Hi. I am already using this great library.

Is there an alternative to types like vec2/mat3 for numba?

At the moment it is not convenient to program vector math in numba.

I need classes that repeat vec2/mat3.

I tried to implement it via jitclass , but such classes do not support isinstance check to do e.g. multiplication of Vec2 by int/float

def __mul__(self, other):
    if isinstance(other, Vec2):
        return Vec2(self._x * other._x, self._y * other._y)
    elif type(other) in (int, float):
        return Vec2(self._x * other, self._y * other)

What is vec2/mat3? Are you looking for numpy?

vec2/mat3 are GLSL types

It’s a bit difficult to guess what your are trying to do since there is little contextual information, but:

As @esc said numpy is probably the most frutiful direction for you, it brings a lot of the math you probably try to do with the GLSL types. (No named access and swizzling though).

If your scope is more limited, the pyglet game framework has Vec and Mat types that come closer to GLSL

OK, I am not familiar with GLSL, is it this: Data Type (GLSL) - OpenGL Wiki ??-- in that case you do indeed want Numpy arrays: Supported NumPy features — Numba 0+untagged.4320.g54c0cf8.dirty documentation

Cool but I don’t need numpy arrays. Np arrays are ND arrays.
Vec2 is vector or point (x,y). Using numpy for that is not efficient for readability and not elegant.

Ok, all I want is the following code working:


import numba as nb
from numba.experimental import jitclass


@jitclass([ ('_x', float32),   
            ('_y', float32), ])
class Vec2:
    def __init__(self, x : float, y : float):
        self._x = x
        self._y = y

    @property
    def x(self) -> float: return self._x
    @property
    def y(self) -> float: return self._y

    def __len__(self): return 2
    def __getitem__(self, key): return (self._x, self._y)[key]

    def __mul__(self, other):
        if type(other) == Vec2:
            return Vec2(self._x * other._x, self._y * other._y)
        elif type(other) in (int, float):
            return Vec2(self._x * float(other), self._y * float(other))
        raise ValueError()
    

@nb.njit(nogil=True)
def test1():
    return Vec2(1,1) * 2.0

@nb.njit(nogil=True)
def test2():
    return Vec2(1,1) * Vec2(2,2)

print(test1())    
print(test2())

Maybe you could use NamedTuples:

https://numba.pydata.org/numba-doc/dev/reference/pysupported.html#collections

1 Like

my reply is hidden by spam filter :disappointed_relieved:

@esc why you don’t approve hidden posts. I tried to create new topic, also hidden. Such unfriendly forum

Sorry for the delay, was in a meeting. Posts are all approved now.

ok this topic may be closed.

I realized that there is no builtin vector math glsl-like types. I’m going to try to create them for myself.

If you mainly want to learn, then implementing your own Vec Mat types might be fun :-).

But if you want to use this in production code, I would think twice whether it is worth reinventing the wheel, it will likely be hard to come just remotely close to the capabilities and performance of numpy.
If you would like to have the named access (.x .y etc.) then I suggest you take a look at numpys record arrays. Structured arrays — NumPy v1.26 Manual . They probably come very close to what you want and all the logic already exists (vector math, matrix multiplications etc).

If you want to hide the truth from your api consumer you can make thin wrapper function dubbed Vec2, Vec3, … and create a record array in them. This hides most of the implementation detail and provides a more familiar vector / matrix creation interface. Swizzling, i.e. epxressions like vector.xxyz, would be an interesting challenge to tackle though …

Good luck! :slight_smile:

as I said before, using huge numpy ndarray api for single vectors are bad for readability and debugging.
Also ndarray has implicit broadcast and may produce more errors.
Also vec2 has convenient .x .y .zyx and other properties.
I want to use some code from shadertoy for image filtering.
Writing few functions are not “reinventing the wheel”.

crap:

p = np.ndarray([1,1])
d = np.linalg.norm(p)

perfect:

p = Vec(1,1)
d = p.length