00001 // This is core/vnl/vnl_transpose.h 00002 #ifndef vnl_transpose_h_ 00003 #define vnl_transpose_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Efficient matrix transpose 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 23 Dec 96 00012 // 00013 // \verbatim 00014 // Modifications 00015 // LSB (Manchester) 19/3/01 Tidied documentation 00016 // \endverbatim 00017 00018 #include <vcl_iostream.h> 00019 #include <vnl/vnl_fastops.h> 00020 00021 //: Efficient matrix transpose 00022 // vnl_transpose is an efficient way to write C = vnl_transpose(A) * B. 00023 // The vnl_transpose class holds a reference to the original matrix 00024 // and when involved in an operation for which it has been specialized, 00025 // performs the operation without copying. 00026 // 00027 // If the operation has not been specialized, the vnl_transpose performs 00028 // a copying conversion to a matrix, printing a message to stdout. 00029 // At that stage, the user may choose to implement the particular operation 00030 // or use vnl_transpose::asMatrix() to clear the warning. 00031 // 00032 // NOTE: This is a reference class, so should be shorter-lived than the 00033 // matrix to which it refers. 00034 // 00035 // NOTE: This only works for arguments of type vnl_matrix<double> 00036 00037 class vnl_transpose 00038 { 00039 const vnl_matrix<double>& M_; 00040 public: 00041 00042 //: Make a vnl_transpose object referring to matrix M 00043 vnl_transpose(const vnl_matrix<double>& M): M_(M) {} 00044 00045 //: Noisily convert a vnl_transpose to a matrix 00046 operator vnl_matrix<double> () const { 00047 vcl_cerr << "vnl_transpose being converted to matrix -- help! I don't wanna go!\n"; 00048 return M_.transpose(); 00049 } 00050 00051 //: Quietly convert a vnl_transpose to a matrix 00052 vnl_matrix<double> asMatrix () const { return M_.transpose(); } 00053 00054 //: Return M' * O 00055 vnl_matrix<double> operator* (const vnl_matrix<double>& O) { 00056 vnl_matrix<double> ret(M_.columns(), O.columns()); 00057 vnl_fastops::AtB(ret, M_, O); 00058 return ret; 00059 } 00060 00061 //: Return M' * O 00062 vnl_vector<double> operator* (const vnl_vector<double>& O) { 00063 vnl_vector<double> ret(M_.columns()); 00064 vnl_fastops::AtB(ret, M_, O); 00065 return ret; 00066 } 00067 00068 //: Return A * B' 00069 friend vnl_matrix<double> operator* (const vnl_matrix<double>& A, const vnl_transpose& B) { 00070 vnl_matrix<double> ret(A.rows(), B.M_.rows()); 00071 vnl_fastops::ABt(ret, A, B.M_); 00072 return ret; 00073 } 00074 }; 00075 00076 #endif // vnl_transpose_h_