svd_basis_weight, a FORTRAN90 code which applies the singular value decomposition ("SVD") to a set of weighted data vectors, to extract the leading "modes" of the data.
This procedure, originally devised by Karl Pearson, has arisen repeatedly in a variety of fields, and hence is known under various names, including:
The role of the weights is to assign greater importance to some vectors. This will have the effect of making it more likely that modes associated with such input data will reappear in the output basis.
This program is intended as an intermediate application, in the following situation:
Thus, the program might read in 500 solution files, and a weight file, and write out 5 or 10 files of the corresponding size and "shape", representing the dominant solution modes.
The optional normalization step involves computing the average of all the solution vectors and subtracting that average from each solution. In this case, the average vector is treated as a special "mode 0", and also written out to a file.
To compute the singular value decomposition, we first construct the M by N matrix A using the individual solution vectors as columns (after multiplication by the weights (w1, w2, ..., wN):
A = [ w1 * X1 | w2 * X2 | ... | wN * XN ]
The singular value decomposition has the form:
A = U * S * V'and is determined using the DGESVD routine from the linear algebra package LAPACK. The leading L columns of the orthogonal M by M matrix U, associated with the largest singular values S, are chosen to form the basis.
In most PDE's, the solution vector has some structure; perhaps there are 100 nodes, and at each node the solution has perhaps 4 components (horizontal and vertical velocity, pressure, and temperature, say). While the solution is therefore a vector of length 400, it's more natural to think of it as a sort of table of 100 items, each with 4 components. You can use that idea to organize your solution data files; in other words, your data files can each have 100 lines, containing 4 values on each line. As long as every line has the same number of values, and every data file has the same form, the program can figure out what's going on.
The program assumes that each solution vector is stored in a separate data file and that the files are numbered consecutively, such as data01.txt, data02,txt, ... In a data file, comments (beginning with '#") and blank lines are allowed. Except for comment lines, each line of the file is assumed to represent all the component values of the solution at a particular node.
Here, for instance, is one data file for a problem with just 3 nodes, and 4 solution components at each node:
# This is solution file number 1 # 1 2 3 4 5 6 7 8 9 10 11 12As far as the program is concerned, this file contains a vector of length 12, the first data item. Presumably, many more files will be supplied.
A separate file must be supplied for the weights, with one weight for each data item. The magnitude of the weight is important, but the sign is meaningless. For a set of 500 data vectors, the weight file might have 500 lines of text (ignoring comments) such as:
# weight file # 0.15 0.50 1.25 0.01 1.95 ... 0.77
The program is interactive, but requires only a very small amount of input:
The program computes L basis vectors, and writes each one to a separate file, starting with svd_001.txt, svd_002.txt and so on. The basis vectors are written with the same component and node structure that was encountered on the solution files. Each vector will have unit Euclidean norm.
The computer code and data files described and made available on this web page are distributed under the MIT license
svd_basis_weight is available in a FORTRAN90 version.
POD_BASIS_FLOW, a FORTRAN90 code which uses the same algorithm used by SVD_BASIS_WEIGHT, but specialized to handle solution data from a particular set of fluid flow problems.
SVD_BASIS, a FORTRAN90 code which is similar to SVD_BASIS_WEIGHT but works on the case where all data has the same weight.
SVD_SNOWFALL, a FORTRAN90 code which reads a file containing historical snowfall data and analyzes the data with the Singular Value Decomposition (SVD), and plots created by GNUPLOT.