Blender V2.61 - r43446
|
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