Blender V2.61 - r43446

lapack.h

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