def angle(cls, v1, v2, degrees=False): if Tensor.match_shapes(v1, v2): if degrees: return LIB().v_angle(v1.pointer, v2.pointer, 1) return LIB().v_angle(v1.pointer, v2.pointer, 0) else: raise ValueError("Vectors must have matching lengths")
def uniform(cls, low=0.0, high=1.0, shape=None): pointer = None if shape: rank = len(shape) c_data = rank * c_uint pointer = LIB().uniform(rank, (c_data)(*shape), low, high) else: # TODO - change to scalar (now it's a vector) pointer = LIB().uniform(1, (1 * c_uint)(1), low, high) return cls(pointer=pointer)
def matmul(cls, a, b): if a.shape[0] != b.shape[1]: raise ValueError( "The number of columns in the first matrix must be equal to the number of rows in the second matrix" ) pointer = LIB().matmul(a.pointer, b.pointer) return cls(pointer=pointer)
def add(cls, t1, t2): if Tensor.match_shapes(t1, t2): pointer = LIB().add(t1.pointer, t2.pointer) return cls(pointer=pointer) else: raise ValueError("Tensors must have matching shapes")
def copy(self): pointer = LIB().copy(self.pointer) return Tensor(pointer=pointer)
def set(self, data): data = _flatten(data) c_data = c_double * len(data) LIB().set(c_void_p(self.pointer), (c_data)(*data))
def from_shape(self, shape): self.shape = shape self.rank = len(shape) self.pointer = LIB().init(self.rank, (c_int * self.rank)(*shape))
def det(self): return LIB().det(self.pointer)
def sub(cls, v1, v2): if Tensor.match_shapes(v1, v2): pointer = LIB().v_sub(v1.pointer, v2.pointer) return cls(pointer=pointer) else: raise ValueError("Vectors must have matching lengths")
def rotate(self, angle): LIB().v_rotate(self.pointer, angle)
def random(cls, *shape): rank = 1 if isinstance(shape, int) else len(shape) c_data = c_int * rank pointer = LIB().random(rank, (c_data)(*shape)) return cls(pointer=pointer)
def zeros(cls, *shape): rank = 1 if isinstance(shape, int) else len(shape) c_data = c_uint * rank pointer = LIB().zeros(rank, (c_data)(*shape)) return cls(pointer=pointer)
def identity(cls, shape): rank = len(shape) c_data = c_int * rank pointer = LIB().identity(rank, (c_data)(*shape)) return cls(pointer=pointer)
def transpose(self): new_shape = LIB().T(self.pointer) self.shape = [new_shape[i] for i in range(len(self.shape))] return self
def mul(cls, t, scalar): if isinstance(scalar, (int, float)): pointer = LIB().mul(t.pointer, scalar) return cls(pointer=pointer) else: raise TypeError(f"Can't multiply tensor with type {type(scalar)}")
def norm(self): return LIB().v_norm(self.pointer)
def prod(cls, t): return LIB().prod(t.pointer)
def dot(cls, v1, v2): if Tensor.match_shapes(v1, v2): return LIB().v_dot(v1.pointer, v2.pointer) else: raise ValueError("Vectors must have matching lengths")
def sqrt(cls, t): return LIB().sqrt(t.pointer)
def __del__(self): try: LIB().destory(self.pointer) except AttributeError: return
def trace(self): return LIB().trace(self.pointer)