Blender  V2.59
lapack.h
Go to the documentation of this file.
00001 
00005 /*
00006 
00007 *
00008 * Template Numerical Toolkit (TNT): Linear Algebra Module
00009 *
00010 * Mathematical and Computational Sciences Division
00011 * National Institute of Technology,
00012 * Gaithersburg, MD USA
00013 *
00014 *
00015 * This software was developed at the National Institute of Standards and
00016 * Technology (NIST) by employees of the Federal Government in the course
00017 * of their official duties. Pursuant to title 17 Section 105 of the
00018 * United States Code, this software is not subject to copyright protection
00019 * and is in the public domain.  The Template Numerical Toolkit (TNT) is
00020 * an experimental system.  NIST assumes no responsibility whatsoever for
00021 * its use by other parties, and makes no guarantees, expressed or implied,
00022 * about its quality, reliability, or any other characteristic.
00023 *
00024 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
00025 * see http://math.nist.gov/tnt for latest updates.
00026 *
00027 */
00028 
00029 
00030 
00031 // Header file for Fortran Lapack
00032 
00033 #ifndef LAPACK_H
00034 #define LAPACK_H
00035 
00036 // This file incomplete and included here to only demonstrate the
00037 // basic framework for linking with the Fortran Lapack routines.
00038 
00039 #include "fortran.h"
00040 #include "vec.h"
00041 #include "fmat.h"
00042 
00043 
00044 #define F77_DGESV   dgesv_
00045 #define F77_DGELS   dgels_
00046 #define F77_DSYEV   dsyev_
00047 #define F77_DGEEV   dgeev_
00048 
00049 extern "C"
00050 {
00051 
00052     // linear equations (general) using LU factorizaiton
00053     //
00054     void F77_DGESV(cfi_ N, cfi_ nrhs, fda_ A, cfi_ lda,
00055         fia_ ipiv, fda_ b, cfi_ ldb, fi_ info);
00056 
00057     // solve linear least squares using QR or LU factorization
00058     //
00059     void F77_DGELS(cfch_ trans, cfi_ M, 
00060         cfi_ N, cfi_ nrhs, fda_ A, cfi_ lda, fda_ B, cfi_ ldb, fda_ work, 
00061             cfi_ lwork, fi_ info);
00062 
00063     // solve symmetric eigenvalues
00064     //
00065     void F77_DSYEV( cfch_ jobz, cfch_ uplo, cfi_ N, fda_  A, cfi_ lda, 
00066         fda_ W, fda_ work, cfi_ lwork, fi_ info);
00067 
00068     // solve unsymmetric eigenvalues
00069     //
00070     void F77_DGEEV(cfch_ jobvl, cfch_ jobvr, cfi_ N, fda_ A, cfi_ lda,
00071         fda_ wr, fda_ wi, fda_ vl, cfi_ ldvl, fda_ vr, 
00072         cfi_ ldvr, fda_ work, cfi_ lwork, fi_ info);
00073 
00074 }
00075 
00076 // solve linear equations using LU factorization
00077 
00078 using namespace TNT;
00079 
00080 Vector<double> Lapack_LU_linear_solve(const Fortran_Matrix<double> &A,
00081     const Vector<double> &b)
00082 {
00083     const Fortran_integer one=1;
00084     Subscript M=A.num_rows();
00085     Subscript N=A.num_cols();
00086 
00087     Fortran_Matrix<double> Tmp(A);
00088     Vector<double> x(b);
00089     Vector<Fortran_integer> index(M);
00090     Fortran_integer info = 0;
00091 
00092     F77_DGESV(&N, &one, &Tmp(1,1), &M, &index(1), &x(1), &M, &info);    
00093 
00094     if (info != 0) return Vector<double>(0);
00095     else
00096         return x;
00097 }
00098 
00099 // solve linear least squares problem using QR factorization
00100 //
00101 Vector<double> Lapack_LLS_QR_linear_solve(const Fortran_Matrix<double> &A,
00102     const Vector<double> &b)
00103 {
00104     const Fortran_integer one=1;
00105     Subscript M=A.num_rows();
00106     Subscript N=A.num_cols();
00107 
00108     Fortran_Matrix<double> Tmp(A);
00109     Vector<double> x(b);
00110     Fortran_integer info = 0;
00111 
00112     char transp = 'N';
00113     Fortran_integer lwork = 5 * (M+N);      // temporary work space
00114     Vector<double> work(lwork);
00115 
00116     F77_DGELS(&transp, &M, &N, &one, &Tmp(1,1), &M, &x(1), &M,  &work(1),
00117         &lwork, &info); 
00118 
00119     if (info != 0) return Vector<double>(0);
00120     else
00121         return x;
00122 }
00123 
00124 // *********************** Eigenvalue problems *******************
00125 
00126 // solve symmetric eigenvalue problem (eigenvalues only)
00127 //
00128 Vector<double> Upper_symmetric_eigenvalue_solve(const Fortran_Matrix<double> &A)
00129 {
00130     char jobz = 'N';
00131     char uplo = 'U';
00132     Subscript N = A.num_rows();
00133 
00134     assert(N == A.num_cols());
00135 
00136     Vector<double> eigvals(N);
00137     Fortran_integer worksize = 3*N;
00138     Fortran_integer info = 0;
00139     Vector<double> work(worksize);
00140     Fortran_Matrix<double> Tmp = A;
00141 
00142     F77_DSYEV(&jobz, &uplo, &N, &Tmp(1,1), &N, eigvals.begin(), work.begin(),
00143         &worksize, &info);
00144 
00145     if (info != 0) return Vector<double>();
00146     else
00147         return eigvals;
00148 }
00149 
00150 
00151 // solve unsymmetric eigenvalue problems 
00152 //
00153 int eigenvalue_solve(const Fortran_Matrix<double> &A, 
00154         Vector<double> &wr, Vector<double> &wi)
00155 {
00156     char jobvl = 'N';
00157     char jobvr = 'N';
00158 
00159     Fortran_integer N = A.num_rows();
00160 
00161 
00162     assert(N == A.num_cols());
00163     
00164     if (N<1) return 1;
00165 
00166     Fortran_Matrix<double> vl(1,N);  /* should be NxN ? **** */
00167     Fortran_Matrix<double> vr(1,N);  
00168     Fortran_integer one = 1;
00169 
00170     Fortran_integer worksize = 5*N;
00171     Fortran_integer info = 0;
00172     Vector<double> work(worksize, 0.0);
00173     Fortran_Matrix<double> Tmp = A;
00174 
00175     wr.newsize(N);
00176     wi.newsize(N);
00177 
00178 //  void F77_DGEEV(cfch_ jobvl, cfch_ jobvr, cfi_ N, fda_ A, cfi_ lda,
00179 //      fda_ wr, fda_ wi, fda_ vl, cfi_ ldvl, fda_ vr, 
00180 //      cfi_ ldvr, fda_ work, cfi_ lwork, fi_ info);
00181 
00182     F77_DGEEV(&jobvl, &jobvr, &N, &Tmp(1,1), &N, &(wr(1)),
00183         &(wi(1)), &(vl(1,1)), &one, &(vr(1,1)), &one,
00184         &(work(1)), &worksize, &info);
00185 
00186     return (info==0 ? 0: 1);
00187 }
00188 
00189 #endif // LAPACK_H
00190