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