def dot(a, b): # Arrayfire requires that the types match for dot and matmul res_dtype = numpy.result_type(a, b) a = a.astype(res_dtype, copy=False) b = b.astype(res_dtype, copy=False) if a.ndim == 1 and b.ndim == 1: s = arrayfire.dot(a.d_array, b.d_array) return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()] a_shape = a.shape b_shape = b.shape if a.ndim == 1: a = a.reshape((a.shape[0], 1)) if b.ndim == 1: b = b.reshape((b.shape[0], 1)) if a.ndim == 2 and b.ndim == 2: # Notice the order of the arguments to matmul. It's not a bug! s = arrayfire.matmul(b.d_array, a.d_array) return afnumpy.ndarray(pu.af_shape(s), dtype=pu.typemap(s.dtype()), af_array=s) # Multidimensional dot is done with loops # Calculate the shape of the result array a_shape = list(a_shape) a_shape.pop(-1) b_shape = list(b_shape) b_shape.pop(-2) res_shape = a_shape + b_shape # Make sure the arrays are at least 3D if a.ndim < 3: a = a.reshape((1, ) + a.shape) if b.ndim < 3: b = b.reshape((1, ) + b.shape) # We're going to flatten the regions over which we're going to loop over # to make our life easier and reduce the amount of indexing code a = a.reshape((-1, a.shape[-2], a.shape[-1])) b = b.reshape((-1, b.shape[-2], b.shape[-1])) # Initialize the output array. The shape matches the reshape a and b. res = afnumpy.empty((a.shape[0], a.shape[-2], b.shape[0], b.shape[-1]), dtype=a.dtype) # Loop through the flattened indices and calculate the matmuls for i in range(0, a.shape[0]): for j in range(0, b.shape[0]): res[i, :, j, :] = afnumpy.dot(a[i], b[j]) # Finally appropriately reshape the result array return res.reshape(res_shape)
def dot(a, b): # Arrayfire requires that the types match for dot and matmul res_dtype = numpy.result_type(a,b) a = a.astype(res_dtype, copy=False) b = b.astype(res_dtype, copy=False) if a.ndim == 1 and b.ndim == 1: s = arrayfire.dot(a.d_array, b.d_array) return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()] a_shape = a.shape b_shape = b.shape if a.ndim == 1: a = a.reshape((a.shape[0],1)) if b.ndim == 1: b = b.reshape((b.shape[0],1)) if a.ndim == 2 and b.ndim == 2: # Notice the order of the arguments to matmul. It's not a bug! s = arrayfire.matmul(b.d_array, a.d_array) return afnumpy.ndarray(pu.af_shape(s), dtype=pu.typemap(s.dtype()), af_array=s) # Multidimensional dot is done with loops # Calculate the shape of the result array a_shape = list(a_shape) a_shape.pop(-1) b_shape = list(b_shape) b_shape.pop(-2) res_shape = a_shape + b_shape # Make sure the arrays are at least 3D if a.ndim < 3: a = a.reshape((1,)+a.shape) if b.ndim < 3: b = b.reshape((1,)+b.shape) # We're going to flatten the regions over which we're going to loop over # to make our life easier and reduce the amount of indexing code a = a.reshape((-1,a.shape[-2],a.shape[-1])) b = b.reshape((-1,b.shape[-2],b.shape[-1])) # Initialize the output array. The shape matches the reshape a and b. res = afnumpy.empty((a.shape[0], a.shape[-2], b.shape[0], b.shape[-1]), dtype=a.dtype) # Loop through the flattened indices and calculate the matmuls for i in range(0,a.shape[0]): for j in range(0,b.shape[0]): res[i,:,j,:] = afnumpy.dot(a[i],b[j]) # Finally appropriately reshape the result array return res.reshape(res_shape)
def test_empty(): a = afnumpy.empty((2,3)) b = numpy.array(a) a[:] = 1 b[:] = 1 fassert(a,b)
def arrayfire_flip(a): b = afnumpy.empty(a.shape, a.dtype) b.d_array = afnumpy.arrayfire.data.flip(a.d_array, dim=0) b.d_array = afnumpy.arrayfire.data.shift(b.d_array, d0=1) return b
def afnumpy_flip(a): b = afnumpy.empty(a.shape, a.dtype) b[0] = a[0] b[1 :] = a[-1:0:-1] return b
def afnumpy_3Dflip(a): b = afnumpy.empty(a.shape, a.dtype) b[:, 0, :] = a[:, 0, :] b[:, 1:, :] = a[:, -1:0:-1, :] return b
def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None): if axis is not None: axisa, axisb, axisc = (axis,) * 3 a = asarray(a) b = asarray(b) # Move working axis to the end of the shape a = rollaxis(a, axisa, a.ndim) b = rollaxis(b, axisb, b.ndim) msg = ("incompatible dimensions for cross product\n" "(dimension must be 2 or 3)") if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3): raise ValueError(msg) # Create the output array shape = broadcast(a[..., 0], b[..., 0]).shape if a.shape[-1] == 3 or b.shape[-1] == 3: shape += (3,) dtype = afnumpy.promote_types(a.dtype, b.dtype) cp = afnumpy.empty(shape, dtype) # create local aliases for readability a0 = a[..., 0] a1 = a[..., 1] if a.shape[-1] == 3: a2 = a[..., 2] b0 = b[..., 0] b1 = b[..., 1] if b.shape[-1] == 3: b2 = b[..., 2] if cp.ndim != 0 and cp.shape[-1] == 3: cp0 = cp[..., 0] cp1 = cp[..., 1] cp2 = cp[..., 2] if a.shape[-1] == 2: if b.shape[-1] == 2: # a0 * b1 - a1 * b0 afnumpy.multiply(a0, b1, out=cp) cp -= a1 * b0 if cp.ndim == 0: return cp else: # This works because we are moving the last axis return rollaxis(cp, -1, axisc) else: # cp0 = a1 * b2 - 0 (a2 = 0) # cp1 = 0 - a0 * b2 (a2 = 0) # cp2 = a0 * b1 - a1 * b0 afnumpy.multiply(a1, b2, out=cp0) afnumpy.multiply(a0, b2, out=cp1) negative(cp1, out=cp1) afnumpy.multiply(a0, b1, out=cp2) cp2 -= a1 * b0 elif a.shape[-1] == 3: if b.shape[-1] == 3: # cp0 = a1 * b2 - a2 * b1 # cp1 = a2 * b0 - a0 * b2 # cp2 = a0 * b1 - a1 * b0 afnumpy.multiply(a1, b2, out=cp0) tmp = afnumpy.array(a2 * b1) cp0 -= tmp afnumpy.multiply(a2, b0, out=cp1) afnumpy.multiply(a0, b2, out=tmp) cp1 -= tmp afnumpy.multiply(a0, b1, out=cp2) afnumpy.multiply(a1, b0, out=tmp) cp2 -= tmp else: # cp0 = 0 - a2 * b1 (b2 = 0) # cp1 = a2 * b0 - 0 (b2 = 0) # cp2 = a0 * b1 - a1 * b0 afnumpy.multiply(a2, b1, out=cp0) negative(cp0, out=cp0) afnumpy.multiply(a2, b0, out=cp1) afnumpy.multiply(a0, b1, out=cp2) cp2 -= a1 * b0 if cp.ndim == 1: return cp else: # This works because we are moving the last axis return rollaxis(cp, -1, axisc)
def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None): if axis is not None: axisa, axisb, axisc = (axis, ) * 3 a = asarray(a) b = asarray(b) # Move working axis to the end of the shape a = rollaxis(a, axisa, a.ndim) b = rollaxis(b, axisb, b.ndim) msg = ("incompatible dimensions for cross product\n" "(dimension must be 2 or 3)") if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3): raise ValueError(msg) # Create the output array shape = broadcast(a[..., 0], b[..., 0]).shape if a.shape[-1] == 3 or b.shape[-1] == 3: shape += (3, ) dtype = afnumpy.promote_types(a.dtype, b.dtype) cp = afnumpy.empty(shape, dtype) # create local aliases for readability a0 = a[..., 0] a1 = a[..., 1] if a.shape[-1] == 3: a2 = a[..., 2] b0 = b[..., 0] b1 = b[..., 1] if b.shape[-1] == 3: b2 = b[..., 2] if cp.ndim != 0 and cp.shape[-1] == 3: cp0 = cp[..., 0] cp1 = cp[..., 1] cp2 = cp[..., 2] if a.shape[-1] == 2: if b.shape[-1] == 2: # a0 * b1 - a1 * b0 afnumpy.multiply(a0, b1, out=cp) cp -= a1 * b0 if cp.ndim == 0: return cp else: # This works because we are moving the last axis return rollaxis(cp, -1, axisc) else: # cp0 = a1 * b2 - 0 (a2 = 0) # cp1 = 0 - a0 * b2 (a2 = 0) # cp2 = a0 * b1 - a1 * b0 afnumpy.multiply(a1, b2, out=cp0) afnumpy.multiply(a0, b2, out=cp1) negative(cp1, out=cp1) afnumpy.multiply(a0, b1, out=cp2) cp2 -= a1 * b0 elif a.shape[-1] == 3: if b.shape[-1] == 3: # cp0 = a1 * b2 - a2 * b1 # cp1 = a2 * b0 - a0 * b2 # cp2 = a0 * b1 - a1 * b0 afnumpy.multiply(a1, b2, out=cp0) tmp = afnumpy.array(a2 * b1) cp0 -= tmp afnumpy.multiply(a2, b0, out=cp1) afnumpy.multiply(a0, b2, out=tmp) cp1 -= tmp afnumpy.multiply(a0, b1, out=cp2) afnumpy.multiply(a1, b0, out=tmp) cp2 -= tmp else: # cp0 = 0 - a2 * b1 (b2 = 0) # cp1 = a2 * b0 - 0 (b2 = 0) # cp2 = a0 * b1 - a1 * b0 afnumpy.multiply(a2, b1, out=cp0) negative(cp0, out=cp0) afnumpy.multiply(a2, b0, out=cp1) afnumpy.multiply(a0, b1, out=cp2) cp2 -= a1 * b0 if cp.ndim == 1: return cp else: # This works because we are moving the last axis return rollaxis(cp, -1, axisc)
def test_empty(): a = afnumpy.empty((2, 3)) b = numpy.array(a) a[:] = 1 b[:] = 1 fassert(a, b)