# Universal Functions (ufunc)

A universal function (or `nlcpy.ufunc` for short) is a function that operates on ndarrays in an element-by-element fashion, supporting array broadcasting, type casting, and several other standard features. That is, a ufunc is a "vectorized" wrapper for a function that takes a fixed number of specific inputs and produces a fixed number of specific outputs.

As with NumPy, Broadcasting rules are applied to input arrays of the universal functions of NLCPy.

Each universal function takes array inputs and produces array outputs by performing the core function element-wise on the inputs (where an element is generally a scalar, but can be a vector or higher-order sub-array for generalized ufuncs). Standard broadcasting rules are applied so that inputs not sharing exactly the same shapes can still be usefully operated on. Broadcasting can be understood by four rules:

1. All input arrays with ndim smaller than the input array of largest ndim, have 1's prepended to their shapes.

2. The size in each dimension of the output shape is the maximum of all the input sizes in that dimension.

3. An input can be used in the calculation if its size in a particular dimension either matches the output size in that dimension, or has value exactly 1.

4. If an input has a dimension size of 1 in its shape, the first data entry in that dimension will be used for all calculations along that dimension. In other words, the stepping machinery of the ufunc will simply not step along that dimension (the stride will be 0 for that dimension).

### Examples

If a.shape is (5,1), b.shape is (1,6), c.shape is (6,) and d.shape is () so that d is a scalar, then a, b, c, and d are all broadcastable to dimension (5,6); and

• a acts like a (5,6) array where a[:,0] is broadcast to the other columns,

• b acts like a (5,6) array where b[0,:] is broadcast to the other rows,

• c acts like a (1,6) array and therefore like a (5,6) array where c[:] is broadcast to every row, and finally,

• d acts like a (5,6) array where the single value is repeated.

## Available Ufuncs

The following tables show Universal functions(ufuncs) provided by NLCPy.

### Math Operations

 `nlcpy.add` Computes the element-wise addition of the inputs. `nlcpy.subtract` Computes the element-wise subtraction of the inputs. `nlcpy.multiply` Computes the element-wise multiplication of the inputs. `nlcpy.matmul` Matrix product of two arrays. `nlcpy.divide` Computes the element-wise division of the inputs. `nlcpy.logaddexp` Computes the element-wise natural logarithm of . `nlcpy.logaddexp2` Computes the element-wise base-2 logarithm of . `nlcpy.true_divide` Computes the element-wise division of the inputs. `nlcpy.floor_divide` Computes the element-wise floor division of the inputs. `nlcpy.negative` Computes numerical negative, element-wise. `nlcpy.positive` Computes numerical positive, element-wise. `nlcpy.power` Computes the element-wise exponentiation of the inputs. `nlcpy.remainder` Computes the element-wise remainder of division. `nlcpy.mod` Computes the element-wise remainder of division. `nlcpy.fmod` Computes the element-wise remainder of division. `nlcpy.absolute` Computes the element-wise absolute value. `nlcpy.fabs` Computes the element-wise absolute value. `nlcpy.rint` Computes the element-wise nearest integer. `nlcpy.heaviside` Computes Heaviside step function. `nlcpy.conj` Returns the element-wise complex conjugate. `nlcpy.conjugate` Returns the element-wise complex conjugate. `nlcpy.exp` Computes the exponential of all elements in the input array. `nlcpy.exp2` Computes 2**x for all elements in the array. `nlcpy.log` Computes the element-wise natural logarithm of x. `nlcpy.log2` Computes the element-wise base-2 logarithm of x. `nlcpy.log10` Computes the element-wise base-10 logarithm of x. `nlcpy.log1p` Computes the element-wise natural logarithm of 1 + x. `nlcpy.expm1` Computes exp(x) - 1 for all elements in the array. `nlcpy.sqrt` Computes the element-wise square-root of the input. `nlcpy.square` Computes the element-wise square of the input. `nlcpy.cbrt` Computes the element-wise cubic-root of the input. `nlcpy.reciprocal` Computes the element-wise reciprocal of the input.

### Trigonometric Functions

 `nlcpy.sin` Computes the element-wise sine. `nlcpy.cos` Computes the element-wise cosine. `nlcpy.tan` Computes the element-wise tangent. `nlcpy.arcsin` Computes the element-wise inverse sine. `nlcpy.arccos` Computes the element-wise inverse cosine. `nlcpy.arctan` Computes the element-wise inverse tangent. `nlcpy.arctan2` Computes the element-wise inverse tangent of x1/x2 choosing the quadrant correctly. `nlcpy.hypot` Computes the "legs" of a right triangle. `nlcpy.sinh` Computes the element-wise hyperbolic sine. `nlcpy.cosh` Computes the element-wise hyperbolic cosine. `nlcpy.tanh` Computes the element-wise hyperbolic tangent. `nlcpy.arcsinh` Computes the element-wise inverse hyperbolic sine. `nlcpy.arccosh` Computes the element-wise inverse hyperbolic cosine. `nlcpy.arctanh` Computes the element-wise inverse hyperbolic tangent. `nlcpy.degrees` Converts angles from radians to degrees. `nlcpy.radians` Converts angles from degrees to radians. `nlcpy.deg2rad` Converts angles from degrees to radians. `nlcpy.rad2deg` Converts angles from radians to degrees.

### Bit-Twiddling Functions

 `nlcpy.bitwise_and` Computes the bit-wise AND of two arrays element-wise. `nlcpy.bitwise_or` Computes the bit-wise OR of two arrays element-wise. `nlcpy.bitwise_xor` Computes the bit-wise XOR of two arrays element-wise. `nlcpy.invert` Computes the bit-wise NOT element-wise. `nlcpy.left_shift` Shifts bits of an integer to the left, element-wise. `nlcpy.right_shift` Shifts bits of an integer to the right, element-wise.

### Comparison Functions

 `nlcpy.greater` Returns (x1 > x2), element-wise. `nlcpy.greater_equal` Returns (x1 >= x2), element-wise. `nlcpy.less` Returns (x1 < x2), element-wise. `nlcpy.less_equal` Returns (x1 <= x2), element-wise. `nlcpy.not_equal` Returns (x1 != x2), element-wise. `nlcpy.equal` Returns (x1 == x2), element-wise. `nlcpy.logical_and` Computes the logical AND of two arrays element-wise. `nlcpy.logical_or` Computes the logical OR of two arrays element-wise. `nlcpy.logical_xor` Computes the logical XOR of two arrays element-wise. `nlcpy.logical_not` Computes the logical NOT of the input array element-wise. `nlcpy.maximum` Computes the element-wise maximum of the inputs. `nlcpy.minimum` Computes the element-wise minimum of the inputs. `nlcpy.fmax` Computes the element-wise maximum of the inputs. `nlcpy.fmin` Computes the element-wise minimum of the inputs.

### Floating Point Functions

 `nlcpy.isfinite` Tests whether input elements are neither inf nor nan, or not. `nlcpy.isinf` Tests whether input elements are inf, or not. `nlcpy.isnan` Tests whether input elements are nan, or not. `nlcpy.signbit` Returns True where signbit is set (less than zero), element-wise. `nlcpy.copysign` Changes the sign of x1 to that of x2, element-wise. `nlcpy.sign` Returns the element-wise indication of the sign of a number. `nlcpy.nextafter` Returns the next floating-point value after x1 towards x2, element-wise. `nlcpy.spacing` Returns the distance between x and the nearest adjacent number, element-wise. `nlcpy.ldexp` Returns , element-wise. `nlcpy.floor` Returns the floor of the input, element-wise. `nlcpy.ceil` Returns the ceiling of the input, element-wise. `nlcpy.trunc` Returns the truncated value of the input, element-wise.

## Methods

In NLCPy, ufuncs are instances of the `nlcpy.ufunc` class. `nlcpy.ufunc` have four methods. However, these methods only make sense on scalar ufuncs that take two input arguments and return one output argument. Attempting to call these methods on other ufuncs will cause a ValueError.

 `nlcpy.ufunc.reduce` Reduces one of the dimension of the input array, by applying ufunc along one axis. `nlcpy.ufunc.accumulate` Accumulates the result of applying the operator to all elements. `nlcpy.ufunc.reduceat` Performs a (local) reduce with specified slices over a single axis. `nlcpy.ufunc.outer` Applies the ufunc op to all pairs (a, b) with a in A and b in B.

The current version of NLCPy does not provide `nlcpy.ufunc.at()`, which is supported by NumPy.

## Optional Keyword Arguments

All ufuncs take optional keyword arguments. Most of these represent advanced usage and will not typically be used.

out

A location into which the result is stored. If provided, it must have a shape that the inputs broadcast to. If not provided or None, a freshly-allocated array is returned. A tuple (possible only as a keyword argument) must have length equal to the number of outputs.

where

This condition is broadcast over the input. At locations where the condition is True, the out array will be set to the ufunc result. Elsewhere, the out array will retain its original value. Note that if an uninitialized out array is created via the default `out=None`, locations within it where the condition is False will remain uninitialized.

casting

Controls what kind of data casting may occur.

• 'no' means the data types should not be cast at all.

• 'equiv' means only byte-order changes are allowed.

• 'safe' means only casts which can preserve values are allowed.

• 'same_kind' means only safe casts or casts within a kind, like float64 to float32, are allowed.

NLCPy does NOT support 'unsafe', which is supported in NumPy.

order

Specifies the calculation iteration order/memory layout of the output array. Defaults to 'K'. 'C' means the output should be C-contiguous, 'F' means F-contiguous, 'A' means F-contiguous if the inputs are F-contiguous and not also not C-contiguous, C-contiguous otherwise, and 'K' means to match the element ordering of the inputs as closely as possible.

dtype

Overrides the dtype of the calculation and output arrays.

subok

Not implemented in NLCPy.