Learning to use the package requires a little effort, especially for C++ programmers, because the code was originally written in Fortran. It requires some care in interpreting and passing arguments. But it is worth the effort.
There are hundreds of routines to choose from in the LAPACK packages. Our computer laboratories have online documentation in the form of man pages for each of them. The documentation is intended mainly for Fortran users, but there is some help for C and C++ programmers.
We will use the SUN repackaging of LAPACK in our laboratories. Here are the steps with the current installation:
Alternatively, you may use the LAPACK manual
on the netlib site. Find the table of contents and go to the
"Index of Driver and Computational Routines". Note that to get the
names of the equivalent double precision routines, replace the first S
with a D. To get complex single precision, use C, and complex double
precision, use Z.
man -M /opt/SUNWspro/man 3p routinewhere "routine" is the name of the subroutine you have chosen. (On Solaris 8, change SUNWspro/prod to SUNWspro/WS6U2 throughout.) Use lower case letters for the name of the routine. The -M flag tells man where to find the documentation and the 3p accesses the section of the man pages with the routine abstracts.
g++ -O -c -I/opt/SUNWspro/prod/include/cc myprog.cc
and link path -L/opt/SUNWspro/prod/lib/ and a bewildering
series of libraries that must be listed in approximately the order
shown. Be sure to put all of the g++ options on one line:
g++ myprog.o -o myprog -L/opt/SUNWspro/prod/lib/
-lsunperf -lfsu -lsunmath -lmtsk
Of course compilation and linking can be done in a single step with
g++ -O -I/opt/SUNWspro/prod/include/cc myprog.cc -o myprog
-L/opt/SUNWspro/prod/lib -lsunperf -lfsu -lsunmath -lmtsk
again, be sure to put all of the g++ options on one line.
(For Solaris 7 the libraries are -lsunperf -lF77 -lM77
-lsunmath.) One may also use the SUN C++ compiler CC for
good performance. In that case the compiler flag
-xlic_lib=sunperf simplifies the process. It replaces the
-I and -L flags and the list of libraries.
man -M /opt/SUNWspro/man 3p dgesv
shows the C(C++) declaration:
void dgesv(int n, int nrhs, double *da, int lda, int
*ipivot, double *db, int ldb, int *info) ;
The abstract explains that n is the number of linear equations,
nrhs is the number of columns of the rhs matrix B (so you want
nrhs = 1), da is a double precision array of dimension
(lda,n), and lda is the "leading" dimension of the
array da. In C(C++) the subscript convention is reversed, so
lda will be the second dimension, as shown below. Continuing
with the arguments, ipivot is an output array indicating the
rows of the matrix that were interchanged upon pivoting. If this
information is of no interest to you, the array must still be
supplied, but the result can be ignored. Next db is a double
precision array of dimension (ldb,nrhs) specifying the rhs
upon entry and containing the solution upon return, ldb is its
"leading" dimension, and info tells whether the solution was
successful.
Armed with this information we write our code as follows:
#include <iostream>
#include <sunperf.h>
#define MAX 10
int main(){
// Values needed for dgesv
int n;
int nrhs = 1;
double a[MAX][MAX];
double b[1][MAX];
int lda = MAX;
int ldb = MAX;
int ipiv[MAX];
int info;
// Other values
int i,j;
// Read the values of the matrix
std::cout << "Enter n \n";
std::cin >> n;
std::cout << "On each line type a row of the matrix A followed by one element of b:\n";
for(i = 0; i < n; i++){
std::cout << "row " << i << " ";
for(j = 0; j < n; j++)std::cin >> a[j][i];
std::cin >> b[0][i];
}
// Solve the linear system
dgesv(n, nrhs, &a[0][0], lda, ipiv, &b[0][0], ldb, &info);
// Check for success
if(info == 0)
{
// Write the answer
std::cout << "The answer is\n";
for(i = 0; i < n; i++)
std::cout << "b[" << i << "]\t" << b[0][i] << "\n";
}
else
{
// Write an error message
std::cerr << "dgesv returned error " << info << "\n";
}
return info;
}
Note that we are not required to use the same names as given in the
prototype.
AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=jThese instructions are appropriate for Fortran arrays and must be translated for use in C++ and C. The rules are simple:
ab[j-1][ka+i-j] = a[j-1][i-1] for max(1,j-ka)<=i<=jWe have changed to the C++ and C bracket subscript notation and use lower case names to emphasize that we are now speaking of C++ and C arrays. The subscripts i and j are dummy variables, so we are allowed to redefine them by adding 1 to each everywhere they appear. Making that replacement then gives
ab[j][ka+i-j] = a[j][i] for max(1,j-ka+1)<=i+1<=j+1Of course, since a is symmetric, we could also write a[i][j]. With a little algebra the inequalities can also be rewritten more neatly, giving the final result:
ab[j][ka+i-j] = a[i][j] for max(0,j-ka)<=i<=j.The array ab must be declared with
float ab[MAX][ldab]where MAX >= N and ldab >= ka. It is passed to the subprogram as the pointer &ab[0][0].
This page is maintained by: Carleton DeTar Mail Form Last modified 1 November 2007