Operations on vectors

Extreme Numerics.NET provides methods for all common operations on vectors. Where applicable, overloaded operator methods are supplied for languages that support them, including element-wise operators in F#. In addition, a series of instance methods have been defined. These provide more efficient use of resources. All instance methods return a reference to the (modified) instance. This enables their use in compound expressions.

All operations can be performed on any combination of vector types. The return value is always an instance of type Vector<T>. The actual return value is of a derived type that is chosen for optimal performance.

Most operations come in 3 variants:

  • A static method in the Vector class that names the operation, for example Vector.Add<T>(Vector<T>, Vector<T>). These methods compute the result and return it as a new object. They take the element type of the vectors as a generic type argument. In nearly all cases, the element type can be inferred and the type argument can be omitted.

  • A static method in the Vector class that names the operation and a Into suffix, for example Vector.AddInto<T>(Vector<T>, Vector<T>, Vector<T>). These methods again take the element type as a generic type argument that can usually be omitted. They are similar to the first kind, but take an additional parameter that specifies the vector that is to hold the result. If this argument is not null, then the result of the operation is copied to this argument and the argument is returned. Otherwise, the method acts exactly like the first method.

  • An instance method in the Vector<T> class that names the operation and an InPlace suffix, for example Vector<T>.AddInPlace(Vector<T>). These methods perform the operation in-place on the instance and return the instance.

Some operations that involve both vectors and matrices are covered in the section on Operations on Matrices.

Addition and subtraction

Besides the usual binary operators, several common compound operations are supported. The following table lists the main methods for addition and subtraction:

Operators and methods for addition and subtraction

Method

Description

Add(a, b).

Adds the vector b to the vector a.

Add(a, f)
Add(f, a).

Adds the scalar f to the vector a.

AddScaled(a, f, b).

Adds the scalarf times the vector b to the vector a.

AddProduct(a, m, b).

Adds the matrix m times the vector b to the vector a.

AddScaledProduct(a, f, m, b). a.AddScaledProduct(f, m, b)

Adds the scalarf times the matrix m times the vector b to the vector a.

Subtract(a, b). a.Subtract(b)

Subtracts the vector b from the vector a.

Subtract(a, f)

Subtracts the scalar f from the vector a.

Subtract(f, a).

Subtracts the vector a from the scalar f.

Multiplication and Division

This section covers multiplication and division of vectors by scalars as well as element-wise operations, cross product and dot product.

Operators and methods for multiplication and division

Method

Description

Multiply(f, a).

Multiplies the vector a by the scalar f.

Divide(a, f).

Divides the vector a by the scalar f.

ElementwiseMultiply(a, b).

Multiplies each element of the vector a by the corresponding element of the vector b. In F#, the .* operator can be used instead.

ElementwiseConjugateMultiply(a, b).

Multiplies each element of the vector a by the corresponding element of the vector b. In F#, the .* operator can be used instead.

ElementwiseDivide(a, b).

Divides each element of the vector a by the corresponding element of the vector b. In F#, the ./ operator can be used instead.

ElementwiseDivide(f, a).

Divides the scalar f by each element of the vector a. In F#, the .* operator can be used instead.

DotProduct(a, b).

Computes the dot product of the vector a and the vector b.

CrossProduct(a, b).

Computes the cross product of the vector a and the vector b. Both vectors must have length 3.

ElementwisePow(a, f).

Raises each element of the vector a to the power specified the integer f. In F#, the .** operator can be used instead.

ElementwisePow(a, f).

Raises each element of the vector a to the power specified the scalar f. In F#, the .** operator can be used instead.

ElementwisePow(a, b).

Raises each element of the vector a to the power specified by the corresponding element in the vector b. In F#, the .** operator can be used instead.

A note on compound assignment operators

The C# language does not provide for explicit overloading of compound assignment operators. A compound operator is translated into the operator followed by an assignment. This means that an expression like

C#
a += b;

is exactly equivalent to

C#
a = a + b;

This is important when working with reference types such as vectors. To perform the above addition, a new vector instance must be created to hold the sum of a and b. This new instance is then assigned to a, releasing the original value. This causes an unnecessary memory allocation. For large vectors, this may lead to excessive garbage collection, degrading overall performance.

The recommended way to use the InPlace instance methods discussed earlier.

Relational operators

The operators in this section are all element-wise. They return a Boolean vector with the result of comparing the corresponding elements of two vectors, or the corresponding element of a vector and a fixed scalar. Also listed here are the Max and Min methods, which follow the same pattern.

Each relational method comes in three flavors: one comparing a vector to a vector, one comparing a scalar to a vector, and one comparing a vector to a scalar. The table below lists the main functions.

Relational Operators

Method

Description

EqualTo(a, b).

Returns whether each element of a is equal to the corresponding element of the vector b. In F#, the .= operator can be used instead.

EqualTo(a, b).

Returns whether each element of a is not equal to the corresponding element of the vector b. In F#, the .<> operator can be used instead.

LessThan(a, b).

Returns whether each element of a is less than the corresponding element of the vector b. In F#, the .< operator can be used instead.

LessThanOrEqualTo(a, b).

Returns whether each element of a is less than or equal to the corresponding element of the vector b. In F#, the .<= operator can be used instead.

GreaterThan(a, b).

Returns whether each element of a is greater than the corresponding element of the vector b. In F#, the .> operator can be used instead.

GreaterThanOrEqualTo(a, b).

Returns whether each element of a is greater than or equal to the corresponding element of the vector b. In F#, the .>= operator can be used instead.

Max(a, b).

Returns the largest of two corresponding elements of the vectors a and b.

Min(a, b).

Returns the smallest of two corresponding elements of the vectors a and b.

Basic functions

The table below lists a number of basic functions that don't qualify as operators but also aren't elementary functions.

Relational Operators

Method

Description

Abs<T>.

Returns the absolute value of each element of the vector.

Floor<T>.

Returns the largest integer less than or equal to each element of the vector.

Ceiling<T>.

Returns the smallest integer less than or equal to each element of the vector.

Conjugate<T>.

Returns the complex conjugate of each element of the vector.

Difference(a).

Returns the forward or backward difference of the vector. A positive value for the lag indicates a forward difference (an increase results in a positive value). The default lag is 1.

Map.

Applies a function to each element of the vector.

Basic functions

The table below lists a number of basic functions that don't qualify as operators but also aren't elementary functions.

Relational Operators

Method

Description

Sqrt<T>(Vector<T>).

Returns the square root of each element of the vector.

Exp<T>(Vector<T>).

Returns the exponential function of each element of the vector.

Log<T>(Vector<T>).

Returns the natural logarithm of each element of the vector.

Log10<T>(Vector<T>).

Returns the base 10 logarithm of each element of the vector.

Hypot<T>(Vector<T>, Vector<T>).

Returns the square root of the sum of the squares of corresponding elements in two vectors.

Sin<T>(Vector<T>).

Returns the sine of each element of the vector.

Cos<T>(Vector<T>).

Returns the cosine of each element of the vector.

Tan<T>(Vector<T>).

Returns the tangent of each element of the vector.

Asin<T>(Vector<T>).

Returns the inverse sine of each element of the vector.

Acos<T>(Vector<T>).

Returns the inverse cosine of each element of the vector.

Atan<T>(Vector<T>).

Returns the inverse tangent of each element of the vector.

Atan2<T>(Vector<T>, Vector<T>).

Returns the 4 quadrant inverse tangent of the ratio of corresponding elements in two vectors.

Sinh<T>(Vector<T>).

Returns the hyperbolic sine of each element of the vector.

Cosh<T>(Vector<T>).

Returns the hyperbolic cosine of each element of the vector.

Tanh<T>(Vector<T>).

Returns the hyperbolic tangent of each element of the vector.

Asinh<T>(Vector<T>).

Returns the inverse hyperbolic sine of each element of the vector.

Acosh<T>(Vector<T>).

Returns the inverse hyperbolic cosine of each element of the vector.

Atanh<T>(Vector<T>).

Returns the inverse hyperbolic tangent of each element of the vector.

References

G. H. Golub, C. F. Van Loan, Matrix Computations (3rd Ed), Johns Hopkins University Press, 1996.