THE JAMPACK OWNER'S MANUAL

G. W. Stewart

Department of Computer Science
Institute for Advanced Computer Studies
University of Maryland

Mathematical and Computations Sciences Division
NIST

stewart@cs.umd.edu
http://www.cs.umd.edu/~stewart/

This document describes a pre-alpha release of Jampack--a package for manipulating matrices in Java. It is not a tutorial and assumes that the reader is familiar with matrices and Java programming. Nontheless it should serve to get you started.

Jampack, like its author, has one foot in the University of Maryland and the other in NIST. In preparing Jampack, I have been particularly indebted to my friends at NIST--Ron Boisvert, Bruce Miller, Roldan Pozo, and Karen Remmington. There willingness to listen to my ideas and their helpful advice turned what might have been a long, lonely slog of coding into a stimulating project.

Contents

Overview
What is Jampack?
The classes of Jampack
Indexing
History
I/O
Parameters
The base index
History
Printing
Complex numbers and arithmetic (the class Znum)
Complex numbers
Complex arithmetic
Complex arrays (the class Znum1)
Matrix classes
The base index and looping
The class Zmat
The tag classes (Zutmat, Zltmat, Zpsdmat)
The class Zdiagmat
Operations
The Plus suite
The Minus suite
The Times suite
The conjugate transpose (the Ctp suite)
Linear Systems
Inverses and linear systems
The Solve suite
Matrix Functions
The matrix inverse (the Inv Suit)
The Norm suite
The trace
New Matrices
Identity matrices (the Eye suite)
Partitioning matrices (the Block suite)
Concatenating matrices (the Merge suite)
Random matrices (the Rand suite)
Input/Output
The Print suite
Decompositions
The LU decomposition (Zludpp)
The Cholesky decomposition (Zchol)
The QR decomposition (Zqrd, Zhqrd)
The spectral decomposition of a Hermitian matrix (Zspec )
The singular value decomposition (Zsvd)
Hessenberg form (Zhess)
Schur form (Schur)
Eigenvalue-vector form (Eig)
Transformations
Householder Transformations (The House Suite)
Pivoting (the Pivot suite)
Plane rotations (the Rot suite)
Swapping Rows and Columns (the Swap suite)
Class index with pointer to java and javadoc files and manual entries)

Overview

Back to Main contents.

This section presents an overview of the Jampack matrix package.

Contents

What is Jampack?
The classes of Jampack
Indexing
History
I/O

What is Jampack?

Back to: Main contents, Top of section.

Jampack (JAva Matrix PACKage) is a collection of classes and methods for manipulating matrices. It is designed to be easy for a novice to use but rich enough to meet the needs of the expert. It is reasonably efficient, although it is not in the high-performance league.

Jampack includes classes for several types of matrices (e.g., diagonal and triangular), methods implementing the common matrix operations, and methods to compute the most important matrix decompositions. The package also includes methods for generating and manipulating Householder transformations and plane rotations. A novel feature of the package is a history list that remembers decompositions that have been computed from a matrix and reuses them later.

The guiding principles of Jampack are openness and extensibility. Jampack makes no attempt to hide the implementation of its classes and methods--as if such a thing could ever be desirable in matrix computations. Instead this manual makes it easy for the user to get at the raw code of Jampack. I expect that most people will simply want to use the features of Jampack without further ado. But the significant minority with special interests or needs can get under the hood and tinker. Jampack is yours to play with--which is why this document is an owner's manual, not a user's guide.

Jampack is also open ended. Matrix operations, transformations, and functions are organized into classes of methods called suites. New features to Jampack can be added by placing new methods in the appropriate suite. It will often turn out that methods already in a suite can be used as templates to guide the coding of a new features.

The current version of Jampack is incomplete and tentative--a sort of pre-alpha job. All matrices are complex because it was felt that implementing real matrices first would cause design conflicts later. Of the full complement of matrix types--general, diagonal, band, and sparse--only general and diagonal have been implemented. The ensemble of matrix functions is incomplete--for example there is not yet a routine to compute the determinant. Many of the methods are "soft coded"; that is, they are implemented using previously coded Jampack functions instead of being written in raw Java. And the code itself is sparsely commented and lightly tested.

The main reason for releasing Jampack at this stage is to see if there is enough interest in it to justify further development. Another reason is to get people interested in contributing to the package. I hope that once a reliable core package has been established, it will continue to grow by public contributions reviewed by a Jampack supervisory committee.

The classes of Jampack

Back to: Main contents, Top of section.

The classes of Jampack fall into three broad categories: classes that define matrices, classes that manipulate matrices, and classes that generate matrix decompositions. In addition, there is a class defining complex numbers and their operations and a class defining global parameters for the package. Let's look briefly at each in turn.

Matrix classes

There are currently two matrix types implemented in Jampack--complex general matrices (Zmat) and complex diagonal matrices (Zdiagmat). (Eventually the core package will include real versions of these classes and real and complex classes for band matrices.) In addition, there are three subclasses of Zmat for upper triangular, lower triangular, and positive semidefinite matrices. These classes (called tag classes) have no constructors of their own; they exist only to allow Jampack to perform certain matrix operations efficiently--for example, the solution of linear systems.

Jampack has no vector class, but it does have a class Z1 that implements a one dimensional array of type complex. However, Z1s do not participate in the usual matrix operations.

Operation Suites

The classes for manipulating matrices are called suites. The most important suites are the ones that implement the basic matrix operations: Plus, Minus, Times, Solve, and Ctp (for conjugate transpose). Generally a suite will have several methods. For example, the Times suite contains, among others, methods for multiplying two Zmats, multiplying a Zmat by its conjugate transpose, or multiplying a Zmat by a Zdiagmat. The generic method in any suite is named "o". For example, Times.o(A,B) will produce the product of A and B for any combination of Zmats and Zdiagmats. Special methods have longer names. For example, Times.aha(A) computes AHA.

Suites that manipulate matrices are nonaltering or altering. The methods of nonaltering suites leave their inputs unchanged. All the usual matrix operations fall in this category, as do such functions as Norm and Trace. Altering suites change their arguments. The prime examples of altering suites are Rot, which manipulates plane rotations, and House, which manipulates Householder transformations.

Decompositions

Jampack has classes implementing the six basic decompositions of matrix computations: the partially pivoted LU decomposition (Zludpp), the Cholesky decomposition (Zchol), the QR decomposition (Zqrd, Zhqrd), the Schur decomposition (Schur), the spectral decomposition of a Hermitian matrix (Zspec) and the singular value decomposition (Zsvd). In addition it has an eigenvalue-vector decomposition (Eig). For ready use, all members of a decomposition are public.

Complex numbers

Complex numbers are implemented by the class Znum, which provides useful constructors and the usual operations. The operations are written in the form c.op(a,b) which causes c to be overwritten by a.op.b. This convention allows computations with Zs to proceed without the creation of new Zs, which is very important in inner loops.

Parameters

The Parameters class contains global parameters that control such things as default printing format and the base for indexing matrices.

Indexing

Back to: Main contents, Top of section.

A Zmat is implemented as two arrays of type double, one representing the real part of the matrix, the other the imaginary part. The indexing of these arrays begins at zero, as usual with Java arrays. In Jampack we say that a primitive array has a base index of zero. Matrices--as opposed to primitive arrays--usually have nonzero base indices, which vary from discipline to discipline. Consequently, Jampack allows the user to set the base index of the matrices in a Java application. To keep things from becoming too complicated, the base may be set only once per application.

History

Back to: Main contents, Top of section.

A major problem in any matrix package is to avoid the recomputation of decompositions. For example, in solving the system

Ax = b
Jampack computes (at considerable expense) an LU decomposition of A. The problem is to avoid the recomputation of the decomposition when we subsequently solve the system
Ay = c
with the same matrix A.

Jampack solves this problem by associating a history list with each matrix. When a Jampack method computes a decomposition of a matrix it may put it on the history list for later use. This procedure is surrounded by rigorous safeguards. While a decomposition is on the history list of a matrix, it is not available outside Jampack, and any alteration of the elements of a matrix causes its history list to be flushed.

I/O

Back to Main contents, Top of section.

Jampack matrices are not yet serializable, but they will be soon.

Jampack has a utility suite Print that prints primitive arrays and matrices in an appropriate format. Default parameters for the formatting are defined in the class Parameters and may be changed. They may also be specified in the Print methods themselves.

Parameters

Back to: Main contents.

Contents

The base index
History
Printing

Jampack has several global parameters that are contained in the class JampackParameters. The following is a description of them.

The base index

Back to: Main contents, Top of section.

The elements of a Jampack matrix are indexed starting with a base index that points to the element in the northeast corner of the matrix. For example, the matrix

| a33  a34  a35 |
| a43  a44  a45 |
| a53  a54  a55 |
has a base index of three. The default base index is contained in the JampackParameters field
protected static int BaseIndex = 1
The current value of the base index can be obtained via the JampackParameters method
public static int getBaseIndex()

The default base index can be changed once in an application, before any new matrix classes have been constructed. This is done by invoking the JampackParameters method

public static void setBaseIndex(int bx)
where bx is the new value of the base index. Any attempt to reset the base index a second time or after a matrix class has been constructed will result in a JampackException. This insures that the matrices generated by an application all have a common base index.

Since matrices are serializable, it is possible to read matrices that have a different base indices into an application. To bring such a matrix into line with the others, JampackParameters provides the functions

public static void adjustBaseIndex(Zmat A)

public static void adjustBaseIndex(Zdiagmat A)
that resets the base index to the common value.

For more on base indices see Matrices.BaseIndex.

History

Back to: Main contents, Top of section.

Since certain matrix decomposition tend to be reused, each Jampack matrix contains a history list indicating which of these decompositions has been computed from the matrix. If a Jampack method requires a decomposition, it interrogates the history list, and if the decomposition is there, it reuses it. This history list (and the reuse) can be turned of by changing the JampackParameters history flag:

protected static boolean history = true
The methods for setting and unsetting the history flag are

public static void setHistory()

public static void unsetHistory()

For more details on history, see Matrices.Zmat.

Printing

Back to: Main contents, Top of section.

JampackParameters contains three fields to control the format of output from Jampack's Print suite. They are

protected static int OutputFieldWidth = 12
The width of the field in characters in which a number is printed

protected static int OutputFracPlaces = 3
The number of places to the right of the decimal point

protected static int PageWidth = 80
The width of an output line in characters

These parameters can be reset by the method

public static void setOutputParams(int width, int frac, int pagewidth)
If a parameter in the calling sequence is not positive, it is not reset.

Complex numbers and arithmetic

Back to: Main contents.

Contents

Complex numbers
Complex arithmetic
Complex arrays (the class Znum1)
Java does not have a primitive complex type, and it is therefore necessary to implement complex numbers and operations on them as a class. For Jampack, the class is named Znum--Z being the standard indicator for double complex floating-point numbers. In this section we will first describe the fields and constructors defining a complex number and then turn to the methods that manipulate complex numbers. We will conclude with a description of the class Znum1, which implements a one-dimensional array of complex numbers.

Complex numbers

Back to: Main contents, Top of section.

A complex number is an object of class Znum. It consists simply of a real and an imaginary part:

public double re
The real part of the complex number

public double im
The imaginary part of the complex number

The class Znum has four constructors.

public Znum()
Creates a Znum and initializes it to zero.

public Znum(double x, double y)
Creates a Znum whose real part is x and whose imaginary part is y.

public Znum(double x)
Creates a Znum whose real part is x and whose imaginary part is zero.

public Znum(Znum z)
Creates a Znum and initializes it to another Znum.

The class Znum has complex versions of zero, one, and the imaginary unit.

public static final Znum ZERO = new Znum(0,0)

public static final Znum ONE = new Znum(1,0)

public static final Znum I = new Znum(0,1)

Complex arithmetic

Back to: Main contents, Top of section.

The style of complex operations on Znums is designed to minimize the construction of new Znum's in inner loops. Most of the operations have the form a.op(b,c) in which a can be the same as b or c. Its effect is to assign the value of b.op.c to a. Thus to compute e = a*b + c*d you can write

z1.Times(a,b);
z2.Times(c,d);
e.Plus(z1,z2);

The intermediate quantities z1 and z2 may be thought of as registers that can be created at the beginning of the method doing the calculation. These registers can then be reused in subsequent calculations, which reduces the need to create new Znums.

The construction a.op(b, c) also returns a pointer to a. This means that you can code the above sequence in the more compact form

e.Plus(z1.Times(a,b), z2.Times(a,b));

Since Znum is not a primitive object and the values of a Znum may change, we discourage the use of the "=" operator with Znums. Instead of writing

z1 = z2;
which causes z1 and z2 to point to the same object, write
z1.Eq(z2);
which sets the value of z1 equal to the value of z2. Here is a list of the Znum methods in alphabetical order.

public static double abs(Znum z)
Returns the absolute value of z.

public static double abs1(Znum z)
Returns the sum of the absolute values of the real and imaginary parts of z.

public Znum Conj(Znum a)
Sets this Znum to the conjugate of a and returns this Znum.

public Znum Div(Znum a, Znum b)
Sets this Znum to a/b and returns this Znum.
Throws a JampackException if b is zero.

public Znum Div(Znum a, double b)
Sets this Znum to a/b and returns this Znum.
Throws a JampackException if b is zero.

public Znum Eq(Znum a)
Sets the real and imaginary parts of this Znum to those of a and returns this Znum.

public Znum Eq(double a, double b)
Resets the real and imaginary of this Znum to a and b and returns this Znum.

public Znum Exch(Znum a)
Exchanges the this Znum and a, so that the value of this Znum is the original value of a and vice versa.

public boolean IsEqual(Znum z1, Znum z2)
Tests two Znums for equality.

public Znum Minus(Znum a)
Sets this Znum to -a and returns this Znum.

public Znum Minus(Znum a, Znum b)
Sets this Znum to a-b and returns this Znum.

public Znum Plus(Znum a, Znum b)
Sets this Znum to a+b and returns this Znum.

public Znum Times(Znum a, Znum b)
Sets this Znum to a*b and returns this Znum.

public Znum Times(double a, Znum b)
Sets this Znum to a*b and returns this Znum.

public Znum Sqrt(Znum a)
Sets this Znum to the principal value of the square root of a and returns this Znum.

Complex arrays (the class Znum1)

Back to: Main contents, Top of section.

The implementation of an array of complex numbers is not a straightforward matter. The problem is the interaction of array references with cache memories. For such references to be efficient it is necessary that references to consecutive array elements translate into references to consecutive memory locations, i.e., that an array be stored in a single block of memory. Although Java does not specify how arrays of floats or doubles are to be stored, most versions of the language seem indeed to store their elements contiguously in memory. The same is not true of the members of an array of classes. For example, when a one-dimensional array of Znums is declared, only space for pointers to the elements of the array is allocated. The actual elements must be constructed later. Since each construction is an individual affair, there is no guarantee that the members of the array will occupy consecutive locations in memory.

The Jampack solution to this problem is to create a special class, the class Znum1, to implement one-dimensional complex arrays. The elements of the array are represented by two double arrays, one containing the real part and the other containing the imaginary part. The Znum1 should not be confused with a vector class. It is intended primarily for working storage in matrix algorithms and does not participate in the matrix operations that are defined for the core matrix classes like Zmat. Moreover, a Znum1 has no base index, so that all array references in a Znum1 begin at zero--just like in an array of primitive objects.

The data fields of a Znum1 are the following.

protected int n
The number of elements in the Znum1

protected double re[]
The real part of the Znum1

protected double im[]
The imaginary part of the Znum1

The class Znum1 has only one constructor.

public Znum1(int n)
Creats a Znum1 of length n and initializes it to zero.

Znum1 has the following methods.

public Znum get(int i)
Returns the i-th elements of this Znum1.

public void put(int i, Znum z)
Sets the i-th element of this Znum1 to z.

public void put(int i, double real, double imag)
Sets the real and imaginary parts of the i-th element of this Znum1.

public void Times(int i, Znum z)
Multiplies the i-th element of this Znum1 by z.

Matrix Classes

Back to: Main contents.

Contents

The base index and looping
The class Zmat
The tag classes (Zutmat, Zltmat, Zpsdmat)
The class Zdiagmat
This section is devoted to the matrix classes of Jampack. Matrix classes can be real or complex. Real classes are prefixed with a D (denoting double). Complex classes are prefixed with a Z (denoting double complex). At present all classes are complex.

Matrix classes are also divided into core classes and tag classes. Core classes are those for which all the standard matrix operations are defined. Currently there are two core classes: the Zmat, which represents a general complex matrix, and the Zdiagmat, which represents a complex diagonal matrix. It is planned to add a class to handle band matrices, as well as real versions of the matrix classes.

Tag classes are subclasses of the core classes that inform Jampack of special properties of the matrix in question. For example, the tag class Zutmat specifies that the matrix is complex upper triangular. At present there are three tag classes, Zutmat, Zltmat, and Zpsdmat, all extending Zmat. They specify that the Zmat in question is upper triangular, lower triangular, and positive semidefinite.

The base index and looping

Back to: Main contents, Top of section.

As discussed in the Parameters section each matrix has a base index. If the base index of a matrix A is bx, then the element of the matrix in the northwest corner is abx,bx. Since different disciplines have different indexing conventions, Jampack allows a limited control of the base index. The limitations insure that an application cannot create matrices with different base indices. For more see Parameters.BaseIndex.

The existence of a base index leads to two styles of programming. Suppose the base index is zero and we wish to initialize the elements of an mxn Zmat A to one. One way is the following

   for (i=0; i<m; i++){
      for (j=0; j<n; j++){
         A.put(i, j, Z.ONE);
      }
   }
(Here the method "put" sets the (i,j)-element of A to the value of its third argument.) We call this style of indexing absolute indexing .

On the other hand, when the Zmat A was created, its constructor set its public class members bx, rx, and cx of A to 0, bx+m-1, bx+n-1, so that we can write the above loop in the form

   for (i=A.bx; i<=A.rx; i++){
      for (j=A.bx; j<=A.cx; j++){
         A.put(i, j, Z.ONE);
      }
   }
We call this style of indexing relative indexing.

Absolute indexing is more natural that relative indexing, and in most applications it makes no difference which you use--especially, since the method Parameters.adjustBaseIndex can be used to a bring nonconforming matrix in line with its companions. However, if you are writing general purpose code designed to work with any base index, you must use relative indexing.

The class Zmat

Back to: Main contents, Top of section.

The class Zmat (along with its companion to be, the Dmat) is the workhorse of Jampack. It implements a general complex matrix and has a rich variety of constructors. Its methods are restricted to those that manipulate elements and submatrices. General matrix functions like addition and multiplication are handled by special suites of functions like Plus and Times. In what follows A will denote a generic Zmat.

Public members

Zmat has five public members, provided to make relative indexing easy.
int bx
The base index
int rx
The upper row index
int nr
The number of rows
int cx
The upper column index
int nc
The number of columns
These numbers are related by the equations
rx = bx + nr - 1,
cx = bx + nc - 1.

The Jampack convention is that these parameters are never to be altered. But if you think someone has been playing fast and loose with them, you can restore their values by coding

A.getProperties();

Zmat has the following constructors.

public Zmat(int nrow, int ncol)
Creates a Zmat and initializes it to zero.

public Zmat(double re[][], double im[][])
Creates a Zmat and initializes its real and imaginary parts to a pair of arrays.

public Zmat(Z A[][])
Creates a Zmat and initializes it to an array of class Z.

public Zmat(double A[][])
Creates a Zmat and initializes its real part to to an array of class double. The imaginary part is set to zero.

public Zmat(Zmat A)
Creates a Zmat and initializes it to a Zmat.

public Zmat(Z1 A)
Creates a Zmat and initialize it to a Z1.

public Zmat(Zdiagmat D)
Creates a Zmat and initialize it to a Zdiagmat.

Zmat has a number of methods for retrieving parts of its matrix. In the following descriptions the notation (i1:i2,:) and (:,j1,j2) refers to rows i1...i2 and columns j1...j2 of a matrix. If ii[] is an integer array of length k, then (ii[],:) refers to rows ii[0],...,ii[k-1] of a matrix. Similarly if jj[] is an integer array of length l, then (:,jj[]) refers to rows jj[1],...,jj[l-1] of a matrix. These notations can be mixed to produce submatrices; e.g., (ii[], j1:j2) refers to the submatrix subtended by rows ii[0],...,ii[k-1] and columns, j1,...,j2.

public double[][] getRe()
Returns a copy of the real part of a Zmat.

public double[][] getIm()
Returns a copy of the imaginary part of a Zmat.

public Z[][] getZ()
Returns a copy of the real and imaginary parts as a complex array.

public Z get(int i, int j)
Returns the (i,j)-element of a Zmat.

public Zmat get(int i1, int i2, int j1, int j2)
Returns the submatrix (i1:i2, j1:j2)

public Zmat get(int ii[], int j1, int j2)
Returns the submatrix (ii[], j1:j2).

public Zmat get(int i1, int i2, int jj[])
Returns the submatrix (i1:i2, jj[]).

public Zmat get(int ii[] , int jj[])
Returns the submatrix (ii[], jj[]).
Zmat also contains methods for altering elements and submatrices.

public void put(int i, int j, Z a)
Writes the (i,j) element of a Zmat.

public void put(int i1, int i2, int j1, int j2, Zmat A)
Overwrites the submatrix (i1:i2, j1:j2) with a Zmat.

public void put(int ii[], int j1, int j2, Zmat A)
Overwrites the submatrix (ii[], j1:j2) with a Zmat.

public void put(int i1, int i2, int jj[], Zmat A)
Overwrites the submatrix (i1:i2, jj[]) with a Zmat.

public void put(int ii[] , int jj[], Zmat A)
Overwrites the submatrix (ii[], jj[]) with a Zmat.

Some of the Jampack suites require a matrix decomposition to perform their computations. When they compute the decomposition, they store a pointer to it on the history list of the Zmat in question. To preserve the integrity of the decomposition, it is not directly available to the user. Zmat provides three methods that return decompositions provided they exist.

public Zludpp getLU()
Returns an LU decomposition if a valid one exists. Otherwise returns null.

public Zhqrd getHQR()
Returns a Householder QR decomposition if a valid one exists. Otherwise returns null.

public Zchol getCHOL()
Returns a Cholesky decomposition if a valid one exists. Otherwise returns null.
Note that a call to one of these methods results in the decomposition being removed from the history list of the Zmat.

Implementation details and private members

For reason's explained in the subsection on the class Z1, a Zmat is not implemented as an array of Zs. Instead, the elements of a Zmat are stored in two two-dimensional arrays of type double, one for the real part and the other for the imaginary part. Specifically, the matrix is defined by the following class members.

protected int nrow
The number of rows

protected int ncol
The number of columns

protected int basex
The base index

protected double re[][]
The real part of the matrix

protected double im[][]
The imaginary part of the matrix

The history option is implemented by four data fields and a method. The data fields are

protected boolean dirty
True if the matrix has been altered.

protected Zludpp LU
Points to an LU decomposition if there is one. Otherwise null.

protected Hqrd HQR
Points to a Householder QR decomposition if there is one. Otherwise null.

protected Zludpp CHOL
Points to a Cholesky decomposition if there is one. Otherwise null.
The method is

protected void clean()
Nullifies the history pointers if the matrix is dirty and sets the dirty flag to false.

These members work as follows to insure that decompositions on the history list actually correspond to the matrix in a Zmat. Only Jampack methods can alter a matrix, and by convention any method that alters the matrix sets the dirty flag. Before attempting to use a decomposition on the history list, a Jampack method runs clean(), which nullifies the history list if the matrix is dirty. The method then interrogates the pointer. If it is nonnull, it points to a valid decomposition. If it is null, the method must compute the decomposition from scratch.

To illustrate the use of these data items and clean, here is the code for the function getCHOL.

public Zchol getCHOL(){
   clean();
   Zchol temp = CHOL;
   CHOL = null;
   return temp;
}
Note that when a user requests a decomposition from history list, it is removed from the list. This prevents the user from altering decompositions on the history list.

The tag classes

Back to: Main contents, Top of section.

Tag classes are subclasses of a matrix class that tell Jampack methods what they can assume about a matrix. Currently all tag classes are subclasses of Zmat. They are

Zltmat
Assume the matrix is lower triangular (or if not square lower trapezoidal).

Zpsdmat
Assume the matrix is Hermitian positive semidefinite.

Zutmat
Assume the matrix is upper triangular (or if not square, upper trapezoidal).
The tag classes are null extensions of Zmat. They have no constructors, data, or methods of their own. They do no error checking, and the user is entirely responsible for seeing that they have the properties they announce.

In point of fact, the casual user is unlikely to encounter tag classes. Most tag class matrices are generated automatically--usually as a part of a decomposition--and the Jampack methods treat them properly without user intervention.

In the course of a reduction, a general Zmat A may become, say, upper triangular. In Java one cannot simply assign the result of the reduction to variable of type Zutmat. Instead one must copy the matrix into a Zutmat:

Zutmat U = new Zutmat(A)
An alternative is to copy the original matrix into a Zutmat and perform the reduction there.

The class Zdiagmat

Back to: Main contents, Top of section.

The Zdiagmat implements a complex diagonal matrix. In what follows D will denote a generic Zdiagmat.

Public members

Zdiagmat has three public parameters designed to make relative indexing easy.

public int n
The order of the matrix

public int bx
The base index

public int dx
The index of the last diagonal entry
These quantities are related by the following equation.
dx = bx + n - 1.

As with the Zmat, these public values should not be altered. However, if they are you can restore them by coding

D.getProperties();

Zdiagmat has the following constructors.

public Zdiagmat(int order)
Creates a Zdiagmat and initializes it to zero.

public Zdiagmat(int order, Z val)
Creates a Zdiagmat and initializes it to a constant.

public Zdiagmat(Z1 val)
Creates a Zdiagmat and initializes it to a Z1.

public Zdiagmat(Zmat A, int k)
Creates a Zdiagmat and initializes to to a diagonal of a Zmat. If k=0 the diagonal is the principal diagonal; if k<0, the diagonal is the kth subdiagonal; if k>0, the diagonal is the kth superdiagonal.
Throws a Jampack exception if k is too large or too small.

public Zdiagmat(Zmat A)
Creates a Zdiagmat and initializes it to the principal diagonal of a Zmat.

public Zdiagmat(Zdiagmat D)
Constructs a Zdiagmat and initializes it to another Zdiagmat.

Zdiagmat has two methods to get and retrieve elements.

public Z get(int i)
Returns the ith diagonal element of this Z.

public void put(int ii, Z val)
Writes the ith diagonal element of this Z with val.

Implementation details and private members

The elements of a Zdiagmat are stored in two one-dimensional arrays of type double, one for the real part of the diagonal and the other for the imaginary part. Specifically, the matrix is defined by the following class members.

protected int order
The order of the matrix

protected int basex
The base index

protected double re[]
The real part of the diagonal

protected double im[]
The imaginary part of the diagonal

Matrix Operations

Back to: Main contents.

Contents

The Plus suite
The Minus suite
The Times suite
The Ctp suite (conjugate transpose)

Core matrices in Jampack participate in the core matrix operations. They are: addition, subtraction, multiplication by a scalar, matrix multiplication, and conjugate transposition. Jampack provides four suites of static methods (Plus, Minus, Times, and Ctp) to perform these operations. The core matrix operations are implemented for all combinations of the core matrix classes. Most of these methods have the generic name "o" and are distinguished from one another by the types in their argument lists.

The Plus suite

Back to: Main contents, Top of section.

The Plus suite implements matrix-matrix addition. The methods all throw a JampackException for nonconformity of dimensions.

public static Zmat o(Zmat A, Zmat B)
Returns A + B.

public static Zmat o(Zmat A, Zdiagmat D)
Returns A + D.

public static Zmat o(Zdiagmat D, Zmat B)
Returns D + B.

public static Zdiagmat o(Zdiagmat D1, Zdiagmat D2 )
Returns D1 + D2.

The Minus suite

Back to: Main contents, Top of section.

The Minus suite implements unary minus and matrix-matrix subtraction. The methods for matrix-matrix subtraction throw a JampackException for nonconformity of dimensions.

public static Zmat o(Zmat A)
Returns -A.

public static Zdiagmat o(Zdiagmat D)
Returns -D.

public static Zmat o(Zmat A, Zmat B)
Returns A - B.

public static Zmat o(Zmat A, Zdiagmat D)
Returns A - D.

public static Zmat o(Zdiagmat D, Zmat B)
Returns D - B.

public static Zdiagmat o(Zdiagmat D1, Zdiagmat D2 )
Returns D1 - D2.

The Times suite

Back to: Main contents, Top of section.

The Times suite implements scalar-matrix and matrix-matrix multiplication. The methods for matrix-matrix multiplication throw a Jampack exception for nonconformity of dimensions. Two special methods (Times.aha and Times.aah) return AHA and AAH as a Zpsdmat.

public static Zmat o(Z z, Zmat A)
Returns zA.

public static Zdiagmat o(Z z, Zdiagmat D)
Returns zD.

public static Zmat o(Zmat A, Zmat B)
Returns AB.

public static Zmat o(Zdiagmat D, Zmat A)
Returns DA.

public static Zmat o(Zmat A, Zdiagmat D)
Returns AD.

public static Zdiagmat o(Zdiagmat D1, Zdiagmat D2)
Returns D1D2.

public static Zpsdmat aha(Zmat A)
Returns AHA.

public static Zpsdmat aah(Zmat A)
Returns AAH.

The Ctp suite

Back to: Main contents, Top of section.

The Ctp suite implements the conjugate transpose of a matrix. It has two generic methods.

public static Zmat o(Zmat A)
Returns AH.

public static Zdiagmat o(Zdiagmat D)
Returns DH.

Linear Systems

Back to: Main contents.

Contents

Inverses and linear systems
The Solve suite
In many applications one must solve linear systems of the form
AX = B,
where A is a nonsingular matrix. The Solve suite contains static methods for solving this and related systems. Before describing these methods, we will first discuss the use of inverses to solve systems.

Inverses and linear systems

Back to: Main contents, Top of section.

The solution of the system AX = B can be written in the form X= A-1B. This suggests the following algorithm.

1. Compute C = A-1

2. Compute X = CB
This algorithm can be implement in Jampack as follows.
Zmat C = Inv.o(A);
Zmat X  = Times.o(C, B);
Or more succinctly:
Zmat X  = Times.o(Inv.o(A), B);
On the other hand, we can also solve the problem using the function aib from the Solve suite.
Zmat X = Solve.aib(A, B);
The question is: Which is better?

Without going into details, the method used by Solve is better for two reasons.

1. It is faster.

2. It is numerically more stable.
For these reasons we recommend that the Jampack user substitute an appropriate Solve method for an explicit inverse wherever possible. For example, suppose that we have a formula of the form
S = A22 - A12*A11-1*A12.
Instead of computing an inverse and using the standard matrix functions to compute the matrix S, we can recognize that the matrix A11-1*A12 is the solution of the system A11*X=A12. Hence if we write
S = A22 - A12*X,
we have the following algorithm
Zmat X = Solve.aib(A11, A12);
Zmat S = Minus.o(A22, Times.o(A12, X));
In most instances when a matrix inverse appears in a formula, it can be replaced with an appropriate Solve method.

The Solve suite

Back to: Main contents, Top of section.

In spite of the large number of individual routines in Solve, the class methods can be described in a couple of tables. (For a complete listing of the calling sequences see the Java documentation or the raw code.)

First, the Solve suite solves four kinds of linear systems involving a nonsingular matrix A. The following table gives the names of the Solve methods, the systems they solve, and where the names come from.

aib(A, B) AX = B A Inverse B
ahib(A, B) AHX = B AH Inverse B
bai(B, A) XA = B B Inverse A
bahi(B, A) XAH = B B AH Inverse

(Ironically, although we have deprecated the use of inverses in solving systems, we have used them to generate the names for our methods. A foolish consistency is the hobgoblin of petty minds.)

The second table lists the classes that each of four functions supports. The matrix B is always a Zmat, so we need only list the possible classes of A.

aib Zmat Zltmat Zutmat Zpsdmat
ahib Zmat Zltmat Zutmat
bai Zmat Zltmat Zutmat Zpsdmat
bahi Zmat Zltmat Zutmat

The methods ahib and bahi are not implemented Zpsdmats. This is natural, since positive definite matrices are Hermitian and the two routines are therefore redundant. Note that it is perfectly possible to call ahib and bahi with a Zpsdmat for the first argument; however, it will be treated as if the argument were a Zmat.

In all the Solve methods the user is responsible for insuring that the matrix in question is nonsingular. If the matrix is singular or nearly singular, the methods may throw a JampackException. Owing to rounding error, however, there is no guarantee that they will. A later version of Jampack will implement condition estimators to help the user decide on the quality of a system.

The Solve suite shows the powers of tag classes. Triangular systems can be solved much faster than general systems. Consequently, if a triangular matrix is properly tagged, Solve will automatically take advantage of its triangularity.

Solve also takes full advantage of the history feature. Specifically, to solve a general system, the Solve routines require a Zludpp decomposition, which is expensive to compute. However, once it has been computed, it is put on the history list and can be reused. Thus in the sequence

while (!converged){
   x = Solve.aib(A, x);
   x = Times.o(1/Norm.fro(x), x);
   ...
}
the first iteration of the loop will be expensive but the subsequent interations will be cheap (unless A is altered in the latter part of the loop).

Matrix functions

Back to: Main contents.

Contents

The matrix inverse (the Inv suite)
The Norm suite
The trace

In this section we treat a miscellany of classes that compute scalar or matrix valued functions of a matrix. Currently, there are only three functions: the inverse, the Frobenius norm, and the trace. But there is great room for expansion.

The matrix inverse (Inv suite)

Back to: Main contents, Top of section.

The matrix inverse is computed by the methods of the Inv suite. There are five versions of the generic inverse function. Before using these methods see the admonitions about computing inverses in Linear Systems.

public static Zmat o(Zmat A)
Returns the inverse of A.
Throws JampackException if A is not square.

public static Zpdmat o(Zpdmat A)
Returns the inverse of A.
Throws JampackException if A is not square.

public static Zltmat o(Zltmat L)
Returns the inverse of L.
Throws JampackException if L is not square.
Throws JampackException if L is singular.

public static Zutmat o(Zutmat U)
Returns the inverse of U.
Throws JampackException if U is not square.
Throws JampackException if U is singular.

public static Zdiagmat o(Zdiagmat D)
Returns the inverse of D.
Throws Jampack exception if D is singular.

The first four functions may throw a Jampack exception from the Solve suite if the matrix is singular.

The norm suite

Back to: Main contents, Top of section.

There are a number of useful matrix norms, in particular the one, two, and infinity norms along with the Frobenius norm. Currently the Norm suite only provides methods for the Frobenius norm.

public static double fro(Zmat A)
Returns the Frobenius norm of A.

public static double fro(Zmat A, int i1, int i2, int j1, int j2)
Returns the Frobenius norm of A(i1:i2, j1:j2).

public static double fro(Zdiagmat D)
Returns the Frobenius norm of D.

public static double fro(Z1 u)
Returns the Frobenius norm of u.

The trace

Back to: Main contents, Top of section.

The trace of a matrix is the sum of its diagonal elements. The suite Trace has the following two methods for computing the trace.

public static Z o(Zmat A)
Returns the trace of A.

public static Z o(Zdiagmat D)
Returns the trace of D.

New Matrices

Back to: Main contents.

Contents

Identity matrices (the Eye suite)
Partitioning matrices (the Block suite)
Concatenating matrices (the Merge suite)
Random matrices (the Randu and Randn suites)

Although the core matrix classes have constructors to generate new matrices, there are other ways of forming matrices. The suites in this section all generate new matrices, sometimes from old matrices, sometimes from scratch.

Identity matrices (the Eye suite)

Back to: Main contents, Top of section.

The Eye suite has two methods: one to generate an identity matrix and one to generate a matrix with a leading identity matrix.

public static Zmat o(int n)
Returns an identity matrix of order n.

public static Zmat o(int m, int n)
Returns an mxn matrix with ones on its main diagonal and zeros on its off diagonals.

Partitioning matrices (the Block suite)

Back to: Main contents, Top of section.

In many applications it is necessary to work with the blocks of a partitioned matrix; e.g.,

A = | A00 A01 A02 |
    | A10 A11 A12 |
If A is a Zmat, any particular Aij can be obtained by using A.get. But this procedure is unwieldy when all the submatrices of a partition are needed. The block suite provides a method for gathering all the matrices of the partition into a block matrix.

Specifically, in Jampack a block Zmat is a two-dimensional array of Zmats. The Zmats in a block Zmat are not arbitrary but must satisfy two conformity conditions.

For each i the blocks B[i][j] must have the same number of rows.

For each j the blocks B[i][j] must have the same number of columns
These conditions insure that a block Zmat represents a partition of a larger Zmat.

A partition of a matrix A can be specified by two arrays of integers. Specifically, if ii[] and jj[] are integer arrays of lengths m and n respectively with

bx <= ii[0] < ii[1] < ... < ii[m] <= rx + 1
and
bx <= jj[0] < jj[1] < ... < jj[n] <= cx + 1,
then the arrays specify an mxn block matrix whose (i,j)-block is A.get(ii[i], ii[i+1]-1, jj[j], jj[j+1]-1). This is the block matrix that is returned by the single method of the class Block.

public static Zmat[][] o(Zmat A, int ii[], int jj[])
Returns the block matrix whose (i,j)-block is
A.get(ii[i], ii[i+1]-1, jj[j], jj[j+1]-1).
Throws JampackException for illegal ii or jj.

Concatenating matrices (the Merge suite)

Back to: Main contents, Top of section.

In many applications it is necessary to merge matrices to form a single matrix. For example, given the matrices B00, B01, B10, and B11, we may want to form the matrix

A = | B00 B01 |
    | B10 B11 |
(the B's are called blocks of A). Of course the blocks must conform for the assembly to be successful. Specifically,
B00 and B01 must have the same number of rows.
B10 and B11 must have the same number of rows.
B00 and B10 must have the same number of columns.
B01 and B11 must have the same number of columns.

The Merge suite contains methods to merge blocks into larger matrices. For the basic routine the blocks are contained in an array of Zmats.

public static Zmat o(Zmat[][] B)
If B has m rows and n columns, this method returns the Zmat
           | B[0][0]   ... B[0][n-1]   |
           |    .             .        |
           |    .             .        |
           |    .             .        |
           | B[m-1][0] ... B[m-1][n-1] |
           
Throws a JampackExcption for nonconformity.
In many applications one has to merge only a few matrices, in which case it is unwieldy to create the block matrix B. For this reason, the Merge suite has a number of special methods which are fed the blocks to be merged directly. For example, the method
o23(B00, B01, B02,
    B10, B11, B12)
produces the matrix
| B00 B01 B02 |
| B10 B11 B12 |
Here is a list of the current methods of this form. The names have the form omn, where m and n are the dimensions of the block matrix. The arguments are all Zmats.

public static Zmat o12(B00, B01) 

public static Zmat o21(B00,
                       B10)

public static Zmat o22(B00, B01,
                       B10, B11)

public static Zmat o13(B00, B01, B02)

public static Zmat o31(B00,
                       B10,
                       B20) 

public static Zmat o23(B00, B01, B02,
                       B10, B11, B12)

public static Zmat o32(B00, B01,
                       B10, B11,
                       B20, B21) 

public static Zmat o33(B00, B01, B02
                       B10, B11, B12,
                       B20, B21, B22) 

Random matrices (the Rand suite)

Back to: Main contents, Top of section.

Jampack has a suite of functions for generating (pseudo) random matrices as well as other objects (e.g. arrays of doubles, Z1s, etc.) Two kinds of distributions are supported. Methods whose names begin with "u" return object with uniform random entries in the interval [0,1]. Methods whose names begin with "n" return objects with normal random entries having mean zero and standard deviation one.

public static double ud(), nd()
Returns a random double.

public static double[] udary(int n), ndary(int n)
Returns a one-dimensional array of length n consisting of random doubles.

public static double[][] udary(int m, int n), ndary(int m, int n)
Returns an mxn two-dimensional array of random doubles.

public static Z uz(), nz()
Returns a random Z, i.e., a Z whose real and imaginary parts are random.

public static Z1 uz1(int n), nz1(int n)
Returns a random Z1 of length n.

public static Zmat uzmat(int m, int n), nzmat(int m, int n)
Returns a random mxn Zmat.

The suite has a method to set the seed of the random number generator.

public static void setSeed(long seed)
Sets the seed of the random number generator to seed.

Input/Output

Back to: Main contents.

At present Jampack's I/O routines are confined to one suite (Print) for displaying quantities on the screen.

Contents

The Print suite

The Print suite

Back to: Main contents, Top of section.

The print suite displays numerical and matrix objects on the screen in a standard format that includes numbering of rows and columns. The format of the output is specified by three integers. The field width specifies the width in characters of the field in which a number is displayed (always right adjusted). The number of places in the fraction tells how many digits are allocated to the fraction in a floating-point number. For example, the number of fraction places in -3.1416e+00 is four. Finally, the page width specifies the maximum number of characters in a line. The default value of these parameters are JampackParameters.OutputFieldWidth, JampackParameters.OutputFracPlaces, and JampackParameters.OutputPageWidth. They can be reset by the method setOutputParameters in the class JampackParameters. The first two can be overridden by including values for them in the methods below.

The Print methods come in pairs. One that uses the default parameters and one that overrides them. In the following, the variable w refers to the field width, and d refers to the number of characters in the fraction.

public static void o(int k)
public static void o(int k, int w)
Prints an integer.

public static void o(int ia[])
public static void o(int ia[], int w)
Prints an integer array.

public static void o(double a)
public static void o(double a, int w, int d)
Prints a double.

public static void o(double a[])
public static void o(double a[], int w, int d)
Prints a one-dimensional array of doubles.

public static void o(double a[][])
public static void o(double a[][], int w, int d)
Prints a two-dimensional array of doubles.

public static void o(Z a)
public static void o(Z a, int w, int d)
Prints a Z.

public static void o(Z[] a)
public static void o(Z[] a, int w, int d)
Prints a one-dimensional array of Zs.

public static void o(Z[] a)
public static void o(Z[] a, int w, int d)
Prints a one-dimensional array of Zs.

public static void o(Z[][] a)
public static void o(Z[][] a, int w, int d)
Prints a two-dimensional array of Zs.

public static void o(Z1 z)
public static void o(Z1 z, int w, int d)
Prints a Z1.

public static void o(Zmat A)
public static void o(Zmat A, int w, int d)
Prints a Zmat. The method checks to see if A is real, in which case it only prints the real part.

Decompositions

Back to: Main contents.

Contents

The LU decomposition (Zludpp)
The Cholesky decomposition (Zchol)
The QR decomposition (Zqrd, Zhqrd)
The spectral decomposition of a Hermitian matrix (Zspec)
The singular value decomposition (Zsvd)
Hessenberg form (Zhess)
Schur form (Schur)
Eigenvalue-vector form (Eig)

A matrix decomposition is a factorization of a matrix into the product of simpler matrices. For example, Gaussian elimination with partial pivoting when applied to a matrix A produces a factorization of the form

A = PLU,
where P is a permutation matrix, L is a lower triangular matrix, and U is an upper triangular matrix. This decomposition is widely used in the solution of linear systems--especially by the Solve suite.

At the heart of most computations with dense matrices is a decomposition. Jampack provides classes implementing the more commonly used decompositions. The computation of the decomposition is done by the class constructor.

The uses of a particular decomposition are too varied to be exhausted by a fixed set of methods. Consequently, Jampack's decomposition classes (with the exception of Zhqrd) have no methods of their own, and its members are public for ready access.

Certain matrix decompositions (ludpp, chol, and hqrd) are distinguished by the fact that they can be saved for further use on the history list of the matrix. In particular the Solve suite makes heavy use of this feature. While a decomposition is on the history list, it is hidden from applications outside the Jampack package. For more see JampackParameters.History and Matrices.Zmat.

The LU decomposition (Zludpp)

Back to: Main contents, Top of section.

The LU decomposition with partial pivoting is the decomposition computed by Gaussian elimination with partial pivoting. Specifically, any matrix A can be factored in the form

A = PLU,
where

P is a permutation matrix,

L is a lower triangular matrix with ones on its diagonal and with its subdiagonal elements less than one in magnitude,

U is upper triangular.
This decomposition is widely used in computing solutions to linear systems.

The pivoted LU decomposition is implemented by the class Zludpp. The matrix can be a general mxn Zmat, although square matrices are the rule in most applications. If m>n, the L-factor is lower trapezoidal; if m<n, the U-factor is upper trapezoidal.

The action of the permutation matrix P is specified by an integer vector of pivot indices. For more see the Pivot suite.

The members of Zlupp are all public.

public int nrl
The number of rows in L

public int ncl
The number of columns in L

public int nru
The number of rows in U

public int ncu
The number of columns in U

public int pvt[]
The pivot array

public Zltmat L
The L factor

public Zutmat U
The U factor

Note that L and U are of class Zltmat and Zutmat, subclasses of Zmat that tag them as representing lower and upper triangular matrices.

The decomposition itself is computed in the constructor for Zlupp.

Zludpp(Zmat A)
Returns the Zludpp of A.

A caution. The pivoted LU decomposition is always well defined, hence Zludpp does not return and exception. However, if A is singular, the matrix U will be singular (or numerically will have small diagonal elements), which may cause problems later.

The Cholesky decomposition (Zchol)

Back to: Main contents, Top of section.

If A is a (Hermitian) positive semi-definite matrix, then A can be factored in the form

A = RHR,
where R is upper triangular. This factorization is called the Cholesky decomposition of A. The class Zchol implements the Cholesky decomposition.

The Cholesky decomposition is defined only if A is Hermitian and satisfies xTAx >= 0 for all x. The first condition is checked by Zchol before any significant calculations can begin. The second condition is signaled by a failure of the algorithm for computing the Cholesky decomposition. The failure of either condition causes a JampackExcpetion to be thrown.

Here are the specifications for the Cholesky decomposition.

public int n
The order of A and R

public Zutmat R
The Cholesky factor of A

public Zchol(Zmat A)
Returns the Cholesky decomposition of A.
Throws JampackException if A is not Hermitian.
Throws JampackExcpetion if the decomposition does not exits

The QR decomposition (Zqrd, Zhqrd)

Back to: Main contents, Top of section.

For any mxn matrix A there is a unitary matrix Q such

QHA = R,
where R is zero below its main diagonal. Jampack provides two versions of this QR decomposition. The first is an explicit version in which Q and R are returned as matrices. The second version represents Q as a product of Householder transformations.

The explicit QR decomposition of an matrix mxn A is computed by the class Zqrd. Its data fields and constructor are

public Zmat Q
The Q factor of A

public Zmat R
The R factor of A

public Zqrd(Zmat A)
Returns the QR decomposition of A.

The factored form of the QR decomposition of a mxn matrix A is computed by the class Zhqrd (the "h" stands for Householder). The matrix Q is represented as the product of min(m,n) Householder transformations, whose generating vectors are stored in an array of Z1s. Moreover, if m>n, the the matrix R is made square by stripping it of its trailing m-n rows. Here are the specifications for Zhqrd

public int nrow
The number of rows in A

public int ncol
The number of columns in A

public int ntran
the number of Householder transformations into which Q is factored

public int Z1[] U
An array containing the ntran vectors generating the Householder transformations.

public Zutmat R
The R-factor of A. If nrow>ncol then R is square of order ncol. Otherwise R has the same dimensions as A.

public Zhqrd(Zmat A)
Returns the Householder QR decomposition of A.

Because the Q-factor produced by Zhqrd is in factored form, the class provides four methods for multiplying Q and its conjugate transpose into a matrix.

public Zmat qb(Zmat B)
Returns QB.

public Zmat qhb(Zmat B)
Returns QHB.

public Zmat bq(Zmat B)
Returns BQ.

public Zmat bqh(Zmat B)
Returns BQH.

The spectral decomposition of a Hermitian matrix (Zspec )

Back to: Main contents, Top of section.

For any Hermitian matrix A, there is a unitary matrix U such that

UHAU = D,
where D is a real diagonal matrix. The columns of U are eigenvectors of A. The corresponding diagonal elements of D are their eigenvalues. The decomposition is called the spectral decomposition of A. This decomposition is implemented by the class Zspec.

public Zmat U
The unitary matrix of eigenvectors of A

public Zdiagmat D
The diagonal matrix of eigenvalues of A

public Zspec (Zmat A)
Returns the spectral decomposition of A.
Throws a JampackException if A is not Hermitian.

Note that when real matrices are implemented, D will become a Ddiagmat.

The singular value decomposition (Zsvd)

Back to: Main contents, Top of section.

Let A be an mxn matrix m>=n there are unitary matrices U and V such that

UHAV = | S |
       | 0 |
where S = diag(s1,...,sn) with
s1 >= s2 >= ... >= sn >= 0.
If m<n the decomposition has the form
UHAV = | S  0 |,
where S is diagonal of order n.

The diagonals of S are the singular values of A. The columns of U are the left singular vectors of A and the columns of V are the right singular vectors.

The singular value decomposition is implemented by the class Zsvd.

static int MAXITER = 30
Limits the number of iterations in the SVD algorithm.

public Zmat U
The matrix of left singular vectors of X

public Zmat V
The matrix of right singular vectors of X

public Zdiagmat S
The diagonal matrix of singular values of X

public Zsvd(Zmat A)
Returns the SVD of A.
Throws a JampackException if MAXITER is exceeded.

Hessenberg form (Zhess)

Back to: Main contents, Top of section.

If A is a matrix of order n, there is a a unitary matrix U such that

H = UHAU
is upper Hessenberg; that is, H has the form illustrated below for n = 6.
    | X X X X X X |
    | X X X X X X |
H = | O X X X X X |.
    | O O X X X X |
    | O O O X X X |
    | O O O O X X |
This reduction to Hessenberg form is implemented by the class Zhess.

public Zmat H
The Hessenberg form of A

public Zmat U
The unitary transformation that reduces A to H

public Zhess(Zmat A)
Returns the Hessenberg form of A.
Throws a JampackException if A is not square.

Schur form (Schur)

Back to: Main contents, Top of section.

If A is a matrix of order n, there is a unitary matrix U such that

T = UHAU
is upper triangular. The matrix T is called a Schur form of A. The diagonals of T are eigenvalues of A and the corresponding columns of U are its Schur vectors. The decomposition is not unique--the order of the eigenvalues on the diagonal of T can vary. However, in most applications any Schur form is sufficient.

The class Schur implements this decomposition.

public Zmat T
A Schur form of A

public Zmat U
The unitary transformation that reduces A to T

public static MAXITER = 30
Limits the number of iterations in the QR algorithm

public Schur(Zmat A)
Returns a Schur form of A.
Throws a JampackException if A is not square.

Eigenvalue-vector form (Eig)

Back to: Main contents, Top of section.

Given a diagonalizable matrix A of order n, there is a nonsingular matrix X such that

D = X-1AX
is diagonal. The columns of X are eigenvectors of A corresponding to the diagonal elements of D. Eig implements this eigenvalue-vector decomposition.

public Zmat X
The matrix of eigenvectors of A

public Zdiagmat D
The matrix of eigenvalues of A

public Eig(Zmat A)
Returns an eigenvalue-vector decomposition of A.
Throws a JampackException if A is not square.
The user should be aware that the eigenvalue-vector decomposition is not necessarily stable. In particular, the matrix X of eigenvectors may be ill conditioned.

Transformations

Back to: Main contents.

Contents

Householder Transformations (The House suite)
Pivoting (the Pivot suite)
Plane rotations (the Rot suite)
Swapping Rows and Columns (the Swap suite)
Decompositions are computed by transforming the elements of a matrix. Since it is impossible for Jampack to cover all possible decompositions, the packages has suites implementing the more commonly used transformations.

Householder Transformations (The House suite)

Back to: Main contents, Top of section.

A Householder transformation is a unitary matrix of the form

U = I - uuH,
where uHu = 2. The vector u is said to generate the Householder transformation u.

For any vector x there is a generating vector u such that

Ux = se1,
where s is a scalar and e1 is the vector whose first component is one and whose other components are zero. Thus the Householder transformation U introduces zeros into the last components of x.

If the vector x is embedded in a matrix A, then the Householder transformation will introduce zeros into A. Specifically, if A has the form

|a a a a a a a|
|a x a a a a a|
|a x a a a a a|
|a x a a a a a|
|a x a a a a a|
|a a a a a a a|
and we embed the matrix U above in an identity matrix
|1 0 0 0 0 0|
|0 u u u u 0|
|0 u u u u 0|
|0 u u u u 0|
|0 u u u u 0|
|0 0 0 0 0 1|
then the product of the two has the form
|1 0 0 0 0 0| |a a a a a a a|   |a a a a a a a|
|0 u u u u 0| |a x a a a a a|   |a s a a a a a|
|0 u u u u 0| |a x a a a a a| = |a 0 a a a a a|
|0 u u u u 0| |a x a a a a a|   |a 0 a a a a a|
|0 u u u u 0| |a x a a a a a|   |a 0 a a a a a|
|0 0 0 0 0 1| |a a a a a a a|   |a a a a a a a|

Similarly a postmultiplication by a Householder transformation can introduce zeros into the rows of A.

The House suite contains method to generate and apply Householder transformations. There are two methods to generate a Householder transformation. The first,

public static Z1 genc(Zmat A, int r1, int r2, int c)
generates a Householder transformation that on premultiplication introduces zeros into a column of A. Its calling sequence and effect are illustrated by the following diagram.
      c
      |
   |a a a a a a a|     |a a a a a a|
r1-|a x a a a a a|     |a s a a a a|
   |a x a a a a a|     |a 0 a a a a|
   |a x a a a a a| --> |a 0 a a a a|
r2-|a x a a a a a|     |a 0 a a a a|
   |a a a a a a a|     |a a a a a a|
Here r1, r2, and c specify the part of the matrix from which the Householder transformation is generated. The elements denoted by x's are overwritten by the results of the transformation, but the matrix A is otherwise unaltered. The generating vector is returned as a Z1 of length r2-r1+1.

The method

public static Z1 genr(Zmat A, int r, int c1, int c2)
generates a Householder transformation that on postmultiplication introduces zeros into a row of A. Its calling sequence and effect are illustrated by the following diagram.
     c1    c2  
     |     |
  |a a a a a a|     |a a a a a a|
r-|a x x x x a|     |a s 0 0 0 a|
  |a a a a a a|     |a a a a a a|
  |a a a a a a| --> |a a a a a a|
  |a a a a a a|     |a a a a a a|
  |a a a a a a|     |a a a a a a|
Here r, c2, and c2 specify the part of the matrix from which the Householder transformation is generated. The elements denoted by x's are overwritten by the results of the transformation, but the matrix A is otherwise unaltered. The generating vector is returned as a Z1 of length c2-c1+1.

A Householder transformation can premultiply or postmultiply a matrix. Either operation requires a Z1 work array. Consequently, the methods for applying Householder transformations come in two varieties: one in which the user furnishes the array and the other in which it is generated by the by the method.

The methods

public static Zmat ua(Z1 u, Zmat A, int r1, int r2, int c1, int c2, Z1 v)

public static Zmat ua(Z1 u, Zmat A, int r1, int r2, int c1, int c2)

premultiply the Householder transformation generate by u into the submatrix of A marked by x's below.
        c1  c2
        |   |
   |a a a a a a|
r1-|a a x x x a|
   |a a x x x a|
   |a a x x x a|
r2-|a a x x x a|
   |a a a a a a|
If r1>r2 or c1>c2, the methods do nothing, which is useful in handling boundary conditions. The Z1 v must be at least r2-r1+1 in length. The methods throw a JampackException if u or v are too short.

The methods

public static Zmat au(Z1 u, Zmat A, int r1, int r2, int c1, int c2, Z1 v)

public static Zmat au(Z1 u, Zmat A, int r1, int r2, int c1, int c2)

postmultiply the Householder transformation generate by u into the submatrix of A illustrated above. If r1>r2 or c1>c2, the methods do nothing. The Z1 v must be at least c2-c1+1 in length. The methods throw a JampackException if u or v are too short.

Pivoting (the Pivot suite)

Back to: Main contents, Top of section.

The Pivot suite contains methods to perform a sequence of interchanges to a matrix. The pivot sequence is specified by an integer array pvt[], which determines a permutation as follows. Here bx is the base index of the matrix in question.

for (k=0; k<pvt.length; k++)
   swap row k+bx and row pvt[k]+bx;

The method for applying pvt to the rows of a is

public static Zmat row(Zmat A, int pvt[])

The suite also contains a method for performing the inverse pivot sequence

for(k=pvt.length-1; k>=0; k--)
   swap row k+bx and row pvt[k]+bx;
to the rows of A.
public static Zmat rowi(Zmat A, int pvt[])
Routines for column pivoting will be added later.

Plane rotations (the Rot suite)

Back to: Main contents, Top of section.

The Rot suite generates and applies plane rotations. A 2x2 plane rotation is a unitary matrix of the form

P = |   c      s|
    |-conj(s)  c|

where c is real and |c|2+|s|2 = 1. The number c is the cosine of the rotation and the number s is the sine.

Given a 2-vector whose components are x and y, there is plane rotation P such that

P|x| =  |   c      s||x| = |z|
 |y|    |-conj(s)  c||y|   |0|

Plane rotations may be premultiplied into a matrix A to combine two rows of A. For example, let x, y, c, s, and z be as above, and let

    |1    0     0 0 0|
    |0    c     0 s 0|
P = |0    0     1 0 0|
    |0 -conj(s) 0 c 0|
    |0    0     0 0 0|
Then if
    |a a a a a|
    |a x a a a|
A = |a a a a a|
    |a y a a a|
    |a a a a a|
the matrix PA has the form
    |a a a a a|
    |b z b b b|
B = |a a a a a|
    |b 0 b b b|
    |a a a a a|
The elements denoted by "a" are unchanged by the transformation. Thus a plane rotation can be used to introduce a zero into a matrix at the cost of altering two rows of the matrix.

Similarly there is a plane rotation such that

|x y||   c      s||x| = |z 0|
     |-conj(s)  c||y|
If P has the form above and A is of the form
    |a a a a a|
    |a x a y a|
A = |a a a a a|
    |a a a a a|
    |a a a a a|
then B = AP has the form
    |a b a b a|
    |a z a 0 a|
B = |a b a b a|
    |a b a b a|
    |a b a b a|
Thus postmultiplication by a plane rotation can also be used to introduce zeros into a matrix.

The Rot suite consists of data fields defining a plane rotation and static functions to generate and apply the rotations. The defining fields are

public double c
The cosine of the rotation

public double sr
The real part of the sine of the rotation

public double si
The imaginary part of the sine of the rotation

public double zr
The real part of the first component of the transformed vector

public double si
The imaginary part of the first component of the transformed vector

The methods that generate rotations satisfying

|   c      s||x| = |z|
|-conj(s)  c||y|   |0|
are called genc (c for column). They come in two varieties. One returns the required Rot. The other initializes a Rot in the calling sequence. This second variety is necessary to prevent certain rotation-intensive computations from being dominated by the generation of new Rots.

public static Rot genc(double xr, double xi, double yr, double yi)
public static void genc(double xr, double xi, double yr, double y, Rot P)
Generates a rotation from the complex numbers x = xr+i*xi and y = yr+i*yi.

public static Rot genc(double x, double y)
public static void genc(, double x, double y, Rot P)
Generates a real rotation from x and y.

public static Rot genc(Zmat A, int i1, int i2, int j)
public static void genc(Zmat A, int i1, int i2, intj, Rot P)
Generates a rotation from the elements x=ai1,j and y=ai2,j. The element ai1,j is overwritten by z and ai2,j is overwritten by zero.
The methods that generate rotations satisfying
|x y||   c      s||x| = |z 0|
     |-conj(s)  c||y|
are called genr. They also come in pairs.

public static Rot genr(double xr, double xi, double yr, double yi)
public static void genr(double xr, double xi, double yr, double yi, Rot P)
Generates a rotation from the numbers x = xr+i*xi and y = yr+i*xi.

public static Rot genr(double x, double y)
public static void genr(double x, double y, Rot P)
Generates a real rotation from x and y.

public static Rot genr(Zmat A, int i, int j1, int j2)
public static void genr(Zmat A, int i, int j1, int j2, Rot P)
Generates a rotation from the elements x=ai,j1 and y=ai,j2. The element ai,j1 is overwritten by z and ai,j2 is overwritten by zero.
There are four methods to apply a rotation to a matrix.

public static void pa(Rot P, Zmat A, int i1, int i2, int j1, int j2)
Multiplies rows (i1,j1:j2) and (i2,j1:j2) of A by P.

public static void pha(Rot P, Zmat A, int i1, int i2, int j1, int j2)
Multiplies rows (i1,j1:j2) and (i2,j1:j2) of A by PH.

public static void ap(Zmat A, Rot P, int i1, int i2, int j1, int j2)
Multiplies columns (i1:i2,j1) and A(i2:i2,j1) of A by P.

public static void aph(Zmat A, Rot P, int i1, int i2, int j1, int j2)
Multiplies columns (i1:i2,j1) and A(i2:i2,j1) of A by PH.

Swapping Rows and Columns (the Swap suite)

Back to: Main contents, Top of section.

The Swap suite has two routines for swapping rows or columns of a matrix.

public static void rows(Zmat A, int r1, int r2)
Interchanges rows r1 and r2 of A.
Throws JampackException if r1 or r2 is out of range.

public static void cols(Zmat A, int c1, int c2)
Interchanges columns c1 and c2 of A.
Throws JampackException of c1 or c2 is out of range.

Class Index

Back to Main contents .

The following is an index of the Jampack classes with pointers to the corresponding java and javadoc files and to manual entries.

Block ( java, doc, man)
Suite to partition a matrices.
Ctp ( java , doc, man)
Suite for conjugate transposes and transposes.
Eig ( java , doc, man)
The eigenvalue-vector decompostion.
House ( java, doc, man)
Suite for Householder transformations.
Inv ( java , doc, man)
Suite for matrix inversion.
JampackException ( java, doc)
The Jampack exception.
Merge ( java, doc, man )
Suite for merging matrices into larger matrices.
Minus ( java, doc, man)
Suite for subtracting matrices.
Norm ( java, doc, man)
Suite for computing matrix norms.
JampackParameters ( java, doc, man)
Jamapack global parameters.
Pivot ( java, doc, man)
Suite for applying interchanges.
Plus ( java, doc, man)
Suite for adding matrices.
Print ( java, doc, man)
Suite for printing matrices and arrays.
Rand ( java, doc, man)
Suite for random matrices and arrays.
Rot ( java, doc, man)
Suite for plane rotations.
Schur ( java, doc, man)
The Schur Decomposition.
Solve ( java, doc, man)
Suite for solving linear systems.
Swap ( java, doc, man)
Suite for swapping rows and columns of a matrix.
Times ( java, doc, man)
Suite for swapping rows and columns of a matrix.
Zchol ( java, doc, man)
One-dimensional complex array.
Zdiagmat ( java, doc, man)
Complex Diagonal matrix class.
Zhess ( java, doc, man)
The Hessenberg form.
Zhqrd ( java, doc, man)
The Householder QR decomposition.
Zltmat ( java, doc, man)
Complex lower triangular matrix tag class.
Zludpp ( java, doc, man)
The partially pivoted LU decomposition.
Zmat ( java, doc, man)
Complex general matrix class.
Znum ( java, doc, man)
Complex numbers and arithmetic.
Znum1 ( java, doc, man)
Zpsdmat ( java, doc, man)
Complex positive semidefinite matrix tag class.
Zqrd ( java, doc, man)
The QR decomposition.
Zspec ( java, doc, man)
The spectral decomposition of a Hermitian matrix.
Zsvd ( java, doc, man)
The singular value decomposition.
Zutmat ( java, doc, man)
Complex upper triangular matrix tag class.