00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <iostream>
00020 #include <sstream>
00021 #include <iomanip>
00022 #include <term.h>
00023 #include <unistd.h>
00024 #include <cmath>
00025 #include "math.h"
00026 #include <limits>
00027 #include <boost/numeric/ublas/io.hpp>
00028 #include <boost/numeric/ublas/vector.hpp>
00029 #include <boost/numeric/ublas/vector_proxy.hpp>
00030 #include <boost/numeric/ublas/matrix.hpp>
00031 #include <boost/numeric/ublas/matrix_proxy.hpp>
00032 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00033 #include <boost/numeric/bindings/traits/ublas_vector.hpp>
00034 #include <boost/numeric/bindings/lapack/gesvd.hpp>
00035 #include <boost/numeric/bindings/lapack/workspace.hpp>
00036 #include <string>
00037 #include <algorithm>
00038
00039 using namespace boost::numeric::ublas;
00040 using namespace boost::numeric::bindings;
00041
00042 double max(vector<double> v);
00043 matrix<double> pinv(matrix<double> A);
00044
00045 int main()
00046 {
00047 matrix<double> A(3,3);
00048 A(0,0) = 1;
00049 A(1,2) = 2;
00050 A(2,2) = .2;
00051 A(2,1) = .5;
00052 std::cout << "A: " << A << std::endl;
00053 std::cout << "pinv(A): " << pinv(A) << std::endl;
00054 }
00055
00056 double max(vector<double> v)
00057 {
00058 double max = v(0);
00059 for (int i=1;i<v.size();i++)
00060 {
00061 if (v(i) > max) max = v(i);
00062 }
00063 return max;
00064 }
00065
00066 matrix<double> pinv(matrix<double> A)
00067 {
00068 matrix<double, column_major> Ac = A;
00069 int m = A.size1(), n = A.size2();
00070 int maxDim = std::max(m,n), minDim = std::min(m,n);
00071 vector<double> Sig(minDim);
00072 matrix<double, column_major> U(m,m), SigI(n,m), VT(n,n);
00073 std::cout << "Performing SVD" << std::endl;
00074 lapack::gesvd('A','A', Ac, Sig, U, VT);
00075
00076
00077 double tol = std::numeric_limits<double>::epsilon()*maxDim*max(Sig);
00078
00079
00080
00081
00082
00083 SigI = zero_matrix<double>(n,m);
00084 for (int i=0;i<minDim;i++)
00085 {
00086 if (Sig(i) > tol)
00087 {
00088 SigI(i,i) = 1/Sig(i);
00089 }
00090 else
00091 {
00092 SigI(i,i) = 0;
00093 }
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103 matrix<double> temp = prod(trans(VT),SigI);
00104 return prod(temp,trans(U));
00105 }
00106
00107