top of page

Quick Start

The total beginners' guide to Flag4j

Welcome to Flag4j, a fast linear algebra library for Java. This quick start guide is designed to get you up and running as fast as possible. In this guide you’ll learn how to create complex numbers, initialize vectors, matrices, and tensors (both dense and sparse), and perform basic operations with these arrays. By the end, you’ll have a solid foundation to begin leveraging Flag4j’s efficient linear algebra features into your Java projects.

For more detailed information and tutorials about using Flag4j see the Javadoc API reference and the User Guide.

Importing Flag4j

Once Flag4j has been installed, all packages are prefaced by the domain org.flag4j. To access a specific package org.flag4j.X, it is imported as:

Complex Numbers

* This section covers instantiating and working with complex numbers in Flag4j.

Flag4j provides two primary implementations of complex numbers, a 64-bit implementation (Complex64) and a 128-bit implementation (Complex128). They are backed by two 32-bit floats and two 64-bit floats respectively, representing the real and imaginary component of the complex value. These objects are immutable.

Complex numbers support all common arithmetic operations with other complex numbers as well as with real values (e.g. float or double).

Array Objects

* This section covers nD array objects in Flag4j including matrices, vectors, and tensors.

In Flag4j "arrays" are n-dimensional numerical arrays that are either a vector, matrix, or tensor.  In this article, the term "array" referrers to these algebraic array objects. To disambiguate the term with standard Java arrays, we will refer to them as "Java arrays" explicitly throughout this guide.

To access all array objects provided by Flag4j: 

You may import the specific array object(s) that you require or all of them. The table below contains some of common array objects users may be interested in.

Package
Class
Dense/Sparse
Field
org.flag4j.arrays
SmartMatrix
dynamic
dynamic
org.flag4j.arrays.dense
Vector
dense
double
org.flag4j.arrays.dense
Tensor
dense
double
org.flag4j.arrays.dense
Matrix
dense
double
org.flag4j.arrays.dense
CVector
dense
Complex128
org.flag4j.arrays.dense
CTensor
dense
Complex128
org.flag4j.arrays.dense
CMatrix
dense
Complex128
org.flag4j.arrays.sparse
CsrMatrix
compressed sparse row
double
org.flag4j.arrays.sparse
CooVector
sparse coordinate
double
org.flag4j.arrays.sparse
CooTensor
sparse coordinate
double
org.flag4j.arrays.sparse
CooMatrix
sparse coordinate
double
org.flag4j.arrays.sparse
CsrCMatrix
compressed sparse row
Complex128
org.flag4j.arrays.sparse
CooCVector
sparse coordinate
Complex128
org.flag4j.arrays.sparse
CooCTensor
sparse coordinate
Complex128
org.flag4j.arrays.sparse
CooCMatrix
sparse coordinate
Complex128

All array objects inherit from AbstractTensor. This allows for some basic operations to be performed on any Falg4j array type. For instance, the shape (size along each axis) and rank (number of axes or dimension of array) can be accessed for any array. A Flag4j array's shape is defined by a Shape object which is a fundamental component of Flag4j that describes the rank and size of all dimensions of an nD array.

To construct a Shape object, users simply specify the dimensions of each axes in "row major" order (i.e. the last axis varies the fastest).

The following code snippet demonstrates some basic operations with a generic Flag4j array object. This code snippet will work for any array object in Flag4j inheriting from AbstractTensor.

Dense Arrays

* This section covers dense array objects in Flag4j.

Flag4j represents dense array objects internally as a flat 1D Java array stored in row major ordering. For nD arrays (i.e. tensors), "row major" means that the last axis varies the fastest while the first axis varies the slowest. There are three main dense array types: vectors, matrices, and tensors. All Flag4j array objects are rectangular, have homogeneous entry types, and are designed specifically to handle numerical data.

Vectors are 1D arrays similar to a list:

Matrices are 2D arrays like a table: 

Tensors are generalized nD arrays. A 3D or "rank 3" tensor is essentially a list of 2D arrays. Similarly, a 4D tensor is a list of 3D arrays and so on. An example of a rank 3 tensor:

Initializing Dense Arrays

A simple way to initialize array objects is to specify the data using standard Java arrays.

Another useful way to initialize dense arrays is using a Shape object and a flat 1D Java array.

In general, a 1D tensor and a vector are conceptually the same (similarly for 2D tensors and matrices), but defining an array explicitly as a vector or matrix is often preferred if you know the rank will be 1D or 2D. This is because Flag4j has specialized implementations of some operations for 1D and 2D tensors to improve efficiency.

All dense arrays support common arithmetic operations like addition, subtraction, scalar multiplication etc. In the code snippet below, the variables a and b can be any of the dense arrays as long as they are all the same type.

Dense Tensors

Tensors are generalize vectors and matrices to higher dimensions and represent nD numerical arrays. In addition to the basic arithmetic operations supported by all Flag4j array objects, the tensor objects (e.g. Tensor, CTensor, FieldTensor, etc.) support some tensor specific operations like tensor dot products and tensor traces.

The code snippet below demonstrates how to generate some random tensors for testing and perform some basic operations with them. This can easily be replicated with complex tensors using the CTensor object and the randomCTensor(Shape) method.

Dense Vectors and Matrices

Vectors and matrices are essentially 1D and 2D special cases of a tensor. However as mentioned, the vector and matrix objects in Flag4j have methods specific to vectors/matrices (e.g. vector outer product and matrix multiplication) and specialized efficient implementations for some operations. Because of this, it is generally recommended to use vectors and matrices if you know the rank is  1D or 2D.

The code snippet below demonstrates how to generate random matrices and vectors for testing and performing some basic operations with them.

Using complex vectors and matrices is exactly the same. It should be noted that the cross product is not formally defined for complex vectors but it can still be defined algebraically equivalent to the real case. However, the operation will not satisfy the formal requirements of a cross product.

Dense Tensors

Tensors are generalize vectors and matrices to higher dimensions and represent nD numerical arrays. In addition to the basic arithmetic operations supported by all Flag4j array objects, the tensor objects (e.g. Tensor, CTensor, FieldTensor, etc.) support some tensor specific operations like tensor dot products and tensor traces.

Dense Vectors and Matrices

Vectors and matrices are essentially 1D and 2D special cases of a tensor. However, the vector and matrix objects in Flag4j have methods specific to vectors/matrices (e.g. vector outer product and matrix multiplication) and specialized efficient implementations for some operations.

Using complex vectors and matrices is exactly the same. Note that the outer product is not formally defined for complex vectors but it can still be defined algebraically equivalent to the real case. However, the operations will not satisfy the formal requirements of a cross product.

Dense Tensors

Tensors are generalize vectors and matrices to higher dimensions and represent nD numerical arrays. In addition to the basic arithmetic operations supported by all Flag4j array objects, the tensor objects (e.g. Tensor, CTensor, FieldTensor, etc.) support some tensor specific operations like tensor dot products and tensor traces.

Dense Vectors and Matrices

Vectors and matrices are essentially 1D and 2D special cases of a tensor. However, the vector and matrix objects in Flag4j have methods specific to vectors/matrices (e.g. vector outer product and matrix multiplication) and specialized efficient implementations for some operations.

Using complex vectors and matrices is exactly the same. Note that the outer product is not formally defined for complex vectors but it can still be defined algebraically equivalent to the real case. However, the operations will not satisfy the formal requirements of a cross product.

Sparse Arrays

A sparse tensor, matrix, or vector is an array where most elements are zero. However, there is no strict definition for the proportion of zero-values elements within the array for it to be considered sparse. In general there should be many times more zeros than non-zero values.

Sparse arrays can offer advantages such as reduced memory usage and, in many cases, improved computational performance. These benefits depend on the degree of sparsity and the algorithms used.

Flag4j supports two main formats for sparse arrays: coordinate list (COO) and compressed sparse row (CSR). COO is supported for all tensor, matrix, and vectors while CSR is supported only for matrices. In addition to these standard formats, Flag4j has limited support for some more specialized sparse formats such as a permutation matrix and a symmetric tri-diagonal matrix.

In the code snippet below, a is any sparse array type in Flag4j. The same general methods for getting the arrays

shape and performing arithmetic operations with dense arrays also applies to sparse arrays. This snippet demonstrates some operations which are specific to sparse arrays. The second coalesce method call allows for a custom aggregator to be supplied. In this snippet it is assumed to be a real-valued sparse array but this could be replaced with an appropriate binary operator for complex arrays.

In Flag4j, many operations with sparse arrays assume that non-zero values are sorted lexicographically by their indices. All operations will maintain this sorting but most of these operations will not explicitly verify that the entries are sorted and may exhibit undefined behavior in the case there the entries are not sorted in this manner. Calling sortIndices() on a sparse array will ensure the non-zero values are properly sorted.

COO Arrays

The coordinate list (COO) format represents a sparse array as a list of coordinates of the non-zero entries within the array. COO arrays are generally good for efficient incremental construction or manipulation. However, if working with matrices, CSR matrices are generally more efficient for computations such as matrix multiplication.

Vectors, matrices, and tensors may all be represented in COO format with subtle differences. A single 1D Java array can be used to specify the indices for a COO vector, two 1D Java arrays specify the row and column indices for a COO matrix, and a single 2D Java array specifies the ND indices within a COO tensor. The index array for a COO tensor must have shape (nnz, rank)  where nnz is the number of non-zero values in the tensor.

CSR Arrays

Only matrices support the compressed sparse row (CSR) format. The CSR format represents the non-zero values of a sparse matrix in three 1D Java arrays: non-zero data, row pointers, and column indices.

Both the non-zero data and column index arrays have length nnz where nnz is the number of non-zero entries in the sparse matrix. The row-pointers array has length m + 1 where m is the number of rows in the matrix. The row-pointer array encodes the number of non-zero elements above a given row. For instance, if index 5 in the row-pointers array is 15, this indicates there are 15 non-zero entries above row 5. The row-pointers array will be monotonically increasing.

CSR matrices may be constructed directly from using a shape, the non-zero data, row-pointers, and column indices. However, it is often more convenient to first construct a COO matrix then convert to a CSR matrix. The conversion may also be done in the other direction. Dense matrices can similarly be converted to/from CSR and COO matrices.

bottom of page