Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_BIG_MOORE_PENROSE_PSEUDOINVERSE_H
00002 #define OPENTISSUE_CORE_MATH_BIG_MOORE_PENROSE_PSEUDOINVERSE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013 #include <OpenTissue/core/math/big/big_lu.h>
00014 #include <OpenTissue/core/math/big/big_svd.h>
00015
00016 #include <boost/cast.hpp>
00017 #include <stdexcept>
00018
00019 namespace OpenTissue
00020 {
00021 namespace math
00022 {
00023 namespace big
00024 {
00025
00026
00035 template<class matrix_type, typename invert_functor>
00036 inline void moore_penrose_pseudoinverse(matrix_type const & A, matrix_type& invA, invert_functor const & invert)
00037 {
00038 typedef typename matrix_type::size_type size_type;
00039 typedef typename matrix_type::value_type value_type;
00040 typedef ublas::vector<value_type> vector_type;
00041
00042 if(A.size1() <= 0 || A.size2() <= 0)
00043 throw std::invalid_argument("moore_penrose_pseudoinverse(): A was empty");
00044
00045 size_type m = A.size1();
00046 size_type n = A.size2();
00047
00048 invA.resize(n,m,false);
00049
00050 if(m>n)
00051 {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 matrix_type M;
00062 matrix_type invM;
00063
00064 M.resize(n,n,false);
00065 invM.resize(n,n,false);
00066
00067 ublas::noalias(M) = ublas::prec_prod(ublas::trans(A),A);
00068 invert(M,invM);
00069 ublas::noalias(invA) =ublas::prec_prod(invM,ublas::trans(A)) ;
00070 }
00071 else if(m<n)
00072 {
00073
00074
00075
00076
00077
00078
00079 matrix_type M;
00080 matrix_type invM;
00081
00082 M.resize(m,m,false);
00083 invM.resize(m,m,false);
00084
00085 ublas::noalias(M) = ublas::prec_prod(A,ublas::trans(A));
00086 invert(M,invM);
00087 ublas::noalias(invA) = ublas::prec_prod(ublas::trans(A),invM);
00088 }
00089 else
00090 {
00091
00092 invert(A,invA);
00093 }
00094
00095
00096 }
00097
00104 template<class matrix_type>
00105 inline void lu_moore_penrose_pseudoinverse(matrix_type const & A, matrix_type& invA)
00106 {
00107 #ifdef USE_ATLAS
00108 moore_penrose_pseudoinverse( A, invA, &lu_atlas_invert<matrix_type> );
00109 #else
00110 moore_penrose_pseudoinverse( A, invA, &lu_invert<matrix_type> );
00111 #endif
00112 }
00113
00120 template<class matrix_type>
00121 inline void svd_moore_penrose_pseudoinverse(matrix_type const & A, matrix_type& invA)
00122 {
00123 moore_penrose_pseudoinverse( A, invA, &svd_invert<matrix_type> );
00124 }
00125
00126 }
00127 }
00128 }
00129
00130
00131 #endif