core/vnl/vnl_transpose.h
Go to the documentation of this file.
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_