|
Blender
V2.59
|
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