📄 vnl_matrix_fixed.h
字号:
//: Return Frobenius norm of matrix (sqrt of sum of squares of its elements)
abs_t fro_norm() const { return frobenius_norm(); }
//: Return RMS of all elements
abs_t rms() const { return vnl_c_vector<T>::rms_norm(begin(), size()); }
//: Return minimum value of elements
T min_value() const { return vnl_c_vector<T>::min_value(begin(), size()); }
//: Return maximum value of elements
T max_value() const { return vnl_c_vector<T>::max_value(begin(), size()); }
//: Return mean of all matrix elements
T mean() const { return vnl_c_vector<T>::mean(begin(), num_rows*num_cols /*size()*/); }
// size() call in this method causes an ICE for MSVC when instantating 1x1 matrix
// predicates
//: Return true iff the size is zero.
bool empty() const { return num_rows==0 && num_cols==0; }
//: Return true if all elements equal to identity.
bool is_identity() const;
//: Return true if all elements equal to identity, within given tolerance
bool is_identity(double tol) const;
//: Return true if all elements equal to zero.
bool is_zero() const;
//: Return true if all elements equal to zero, within given tolerance
bool is_zero(double tol) const;
//: Return true if finite
bool is_finite() const;
//: Return true if matrix contains NaNs
bool has_nans() const;
//: abort if size is not as expected
// This function does or tests nothing if NDEBUG is defined
void assert_size(unsigned nr_rows, unsigned nr_cols) const
{
#ifndef NDEBUG
assert_size_internal(nr_rows, nr_cols);
#endif
}
//: abort if matrix contains any INFs or NANs.
// This function does or tests nothing if NDEBUG is defined
void assert_finite() const
{
#ifndef NDEBUG
assert_finite_internal();
#endif
}
////----------------------- Input/Output ----------------------------
// : Read a vnl_matrix from an ascii vcl_istream, automatically determining file size if the input matrix has zero size.
bool read_ascii(vcl_istream& s);
//--------------------------------------------------------------------------------
//: Access the contiguous block storing the elements in the matrix row-wise. O(1).
// 1d array, row-major order.
T const* data_block () const { return data_[0]; }
//: Access the contiguous block storing the elements in the matrix row-wise. O(1).
// 1d array, row-major order.
T * data_block () { return data_[0]; }
//----------------------------------------------------------------------
// Conversion to vnl_matrix_ref.
// The const version of as_ref should return a const vnl_matrix_ref
// so that the vnl_matrix_ref::non_const() cannot be used on
// it. This prevents a const vnl_matrix_fixed from being cast into a
// non-const vnl_matrix reference, giving a slight increase in type safety.
//: Explicit conversion to a vnl_matrix_ref.
// This is a cheap conversion for those functions that have an interface
// for vnl_matrix but not for vnl_matrix_fixed. There is also a
// conversion operator that should work most of the time.
// \sa vnl_matrix_ref::non_const
vnl_matrix_ref<T> as_ref() { return vnl_matrix_ref<T>( num_rows, num_cols, data_block() ); }
//: Explicit conversion to a vnl_matrix_ref.
// This is a cheap conversion for those functions that have an interface
// for vnl_matrix but not for vnl_matrix_fixed. There is also a
// conversion operator that should work most of the time.
// \sa vnl_matrix_ref::non_const
const vnl_matrix_ref<T> as_ref() const { return vnl_matrix_ref<T>( num_rows, num_cols, const_cast<T*>(data_block()) ); }
//: Cheap conversion to vnl_matrix_ref
// Sometimes, such as with templated functions, the compiler cannot
// use this user-defined conversion. For those cases, use the
// explicit as_ref() method instead.
operator const vnl_matrix_ref<T>() const { return vnl_matrix_ref<T>( num_rows, num_cols, const_cast<T*>(data_block()) ); }
//: Convert to a vnl_matrix.
const vnl_matrix<T> as_matrix() const { return vnl_matrix<T>(const_cast<T*>(data_block()),num_rows,num_cols); }
//----------------------------------------------------------------------
typedef T element_type;
//: Iterators
typedef T *iterator;
//: Iterator pointing to start of data
iterator begin() { return data_[0]; }
//: Iterator pointing to element beyond end of data
iterator end() { return begin() + size(); }
//: Const iterators
typedef T const *const_iterator;
//: Iterator pointing to start of data
const_iterator begin() const { return data_[0]; }
//: Iterator pointing to element beyond end of data
const_iterator end() const { return begin() + size(); }
//--------------------------------------------------------------------------------
//: Return true if *this == rhs
bool operator_eq (vnl_matrix_fixed const & rhs) const
{
return equal( this->data_block(), rhs.data_block() );
}
//: Equality operator
bool operator==(vnl_matrix<T> const &that) const { return this->operator_eq(that); }
//: Inequality operator
bool operator!=(vnl_matrix<T> const &that) const { return !this->operator_eq(that); }
//: Print matrix to os in some hopefully sensible format
void print(vcl_ostream& os) const;
//--------------------------------------------------------------------------------
// Helper routines for arithmetic. These routines know the size from
// the template parameters. The vector-vector operations are
// element-wise.
static void add( const T* a, const T* b, T* r );
static void add( const T* a, T b, T* r );
static void sub( const T* a, const T* b, T* r );
static void sub( const T* a, T b, T* r );
static void sub( T a, const T* b, T* r );
static void mul( const T* a, const T* b, T* r );
static void mul( const T* a, T b, T* r );
static void div( const T* a, const T* b, T* r );
static void div( const T* a, T b, T* r );
static bool equal( const T* a, const T* b );
private:
void assert_finite_internal() const;
void assert_size_internal(unsigned, unsigned) const;
};
#undef VNL_MATRIX_FIXED_VCL60_WORKAROUND
// Make the operators below inline because (1) they are small and
// (2) we then have less explicit instantiation trouble.
// --- Matrix-scalar -------------------------------------------------------------
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator+( const vnl_matrix_fixed<T,m,n>& mat1, const vnl_matrix_fixed<T,m,n>& mat2 )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::add( mat1.data_block(), mat2.data_block(), r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator+( const vnl_matrix_fixed<T,m,n>& mat, T s )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::add( mat.data_block(), s, r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator+( const T& s,
const vnl_matrix_fixed<T,m,n>& mat )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::add( mat.data_block(), s, r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator-( const vnl_matrix_fixed<T,m,n>& mat1, const vnl_matrix_fixed<T,m,n>& mat2 )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::sub( mat1.data_block(), mat2.data_block(), r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator-( const vnl_matrix_fixed<T,m,n>& mat, T s )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::sub( mat.data_block(), s, r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator-( const T& s,
const vnl_matrix_fixed<T,m,n>& mat )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::sub( s, mat.data_block(), r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator*( const vnl_matrix_fixed<T,m,n>& mat, T s )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::mul( mat.data_block(), s, r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator*( const T& s,
const vnl_matrix_fixed<T,m,n>& mat )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::mul( mat.data_block(), s, r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> operator/( const vnl_matrix_fixed<T,m,n>& mat, T s )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::div( mat.data_block(), s, r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> element_product( const vnl_matrix_fixed<T,m,n>& mat1,
const vnl_matrix_fixed<T,m,n>& mat2 )
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::mul( mat1.data_block(), mat2.data_block(), r.data_block() );
return r;
}
template <class T, unsigned m, unsigned n>
inline
vnl_matrix_fixed<T,m,n> element_quotient( const vnl_matrix_fixed<T,m,n>& mat1,
const vnl_matrix_fixed<T,m,n>& mat2)
{
vnl_matrix_fixed<T,m,n> r;
vnl_matrix_fixed<T,m,n>::div( mat1.data_block(), mat2.data_block(), r.data_block() );
return r;
}
// The following two functions are helper functions keep the
// matrix-matrix and matrix-vector multiplication code in one place,
// so that bug fixes, etc, can be localized.
template <class T, unsigned M, unsigned N>
inline
vnl_vector_fixed<T, M>
vnl_matrix_fixed_mat_vec_mult(const vnl_matrix_fixed<T, M, N>& a,
const vnl_vector_fixed<T, N>& b)
{
vnl_vector_fixed<T, M> out;
for (unsigned i = 0; i < M; ++i)
{
T accum = a(i,0) * b(0);
for (unsigned k = 1; k < N; ++k)
accum += a(i,k) * b(k);
out(i) = accum;
}
return out;
}
// see comment above
template <class T, unsigned M, unsigned N, unsigned O>
inline
vnl_matrix_fixed<T, M, O>
vnl_matrix_fixed_mat_mat_mult(const vnl_matrix_fixed<T, M, N>& a,
const vnl_matrix_fixed<T, N, O>& b)
{
vnl_matrix_fixed<T, M, O> out;
for (unsigned i = 0; i < M; ++i)
for (unsigned j = 0; j < O; ++j)
{
T accum = a(i,0) * b(0,j);
for (unsigned k = 1; k < N; ++k)
accum += a(i,k) * b(k,j);
out(i,j) = accum;
}
return out;
}
#ifndef VCL_VC_6
// The version for correct compilers
//: Multiply conformant vnl_matrix_fixed (M x N) and vector_fixed (N)
// \relates vnl_vector_fixed
// \relates vnl_matrix_fixed
template <class T, unsigned M, unsigned N>
inline
vnl_vector_fixed<T, M> operator*(const vnl_matrix_fixed<T, M, N>& a, const vnl_vector_fixed<T, N>& b)
{
return vnl_matrix_fixed_mat_vec_mult(a,b);
}
//: Multiply two conformant vnl_matrix_fixed (M x N) times (N x O)
// \relates vnl_matrix_fixed
template <class T, unsigned M, unsigned N, unsigned O>
inline
vnl_matrix_fixed<T, M, O> operator*(const vnl_matrix_fixed<T, M, N>& a, const vnl_matrix_fixed<T, N, O>& b)
{
return vnl_matrix_fixed_mat_mat_mult(a,b);
}
#endif // VCL_VC_6
// These overloads for the common case of mixing a fixed with a
// non-fixed. Because the operator* are templated, the fixed will not
// be automatically converted to a non-fixed-ref. These do it for you.
template <class T, unsigned m, unsigned n>
inline vnl_matrix<T> operator+( const vnl_matrix_fixed<T,m,n>& a, const vnl_matrix<T>& b )
{
return a.as_ref() + b;
}
template <class T, unsigned m, unsigned n>
inline vnl_matrix<T> operator+( const vnl_matrix<T>& a, const vnl_matrix_fixed<T,m,n>& b )
{
return a + b.as_ref();
}
template <class T, unsigned m, unsigned n>
inline vnl_matrix<T> operator-( const vnl_matrix_fixed<T,m,n>& a, const vnl_matrix<T>& b )
{
return a.as_ref() - b;
}
template <class T, unsigned m, unsigned n>
inline vnl_matrix<T> operator-( const vnl_matrix<T>& a, const vnl_matrix_fixed<T,m,n>& b )
{
return a - b.as_ref();
}
template <class T, unsigned m, unsigned n>
inline vnl_matrix<T> operator*( const vnl_matrix_fixed<T,m,n>& a, const vnl_matrix<T>& b )
{
return a.as_ref() * b;
}
template <class T, unsigned m, unsigned n>
inline vnl_matrix<T> operator*( const vnl_matrix<T>& a, const vnl_matrix_fixed<T,m,n>& b )
{
return a * b.as_ref();
}
template <class T, unsigned m, unsigned n>
inline vnl_vector<T> operator*( const vnl_matrix_fixed<T,m,n>& a, const vnl_vector<T>& b )
{
return a.as_ref() * b;
}
template <class T, unsigned n>
inline vnl_vector<T> operator*( const vnl_matrix<T>& a, const vnl_vector_fixed<T,n>& b )
{
return a * b.as_ref();
}
// --- I/O operations ------------------------------------------------------------
template <class T, unsigned m, unsigned n>
inline
vcl_ostream& operator<< (vcl_ostream& os, vnl_matrix_fixed<T,m,n> const& mat)
{
mat.print(os);
return os;
}
template <class T, unsigned m, unsigned n>
inline
vcl_istream& operator>> (vcl_istream& is, vnl_matrix_fixed<T,m,n>& mat)
{
mat.read_ascii(is);
return is;
}
// More workarounds for Visual C++ 6.0. The problem is that VC6 cannot
// automatically determine the m of the second parameter, for some
// reason. Also, VC6 can't figure out that vector_fixed::SIZE is a
// compile time constant when used in the return parameter. So, we
// have to introduce a helper class to do it.
//
#if defined(VCL_VC_6) && !defined(__GCCXML__)
template<class T, unsigned m, class FixedVector>
struct outer_product_fixed_type_helper
{
typedef vnl_matrix_fixed<T,m,FixedVector::SIZE> result_matrix;
};
template<class V1, class V2, class RM>
struct outer_product_fixed_calc_helper
{
static RM calc( V1 const& a, V2 const& b );
};
template <class T, unsigned m, class SecondFixedVector>
outer_product_fixed_type_helper<T,m,SecondFixedVector>::result_matrix
outer_product(vnl_vector_fixed<T,m> const& a, SecondFixedVector const& b)
{
typedef vnl_vector_fixed<T,m> VecA;
typedef vnl_vector_fixed<T,SecondFixedVector::SIZE> VecB;
typedef outer_product_fixed_type_helper<T,m,SecondFixedVector>::result_matrix ResultMat;
return outer_product_fixed_calc_helper<VecA,VecB,ResultMat>::calc(a,b);
}
#else // no need for VC6 workaround for outer_product
//:
// \relates vnl_vector_fixed
template <class T, unsigned m, unsigned n>
vnl_matrix_fixed<T,m,n> outer_product(vnl_vector_fixed<T,m> const& a, vnl_vector_fixed<T,n> const& b);
#endif // VC6 workaround for outer_product
#define VNL_MATRIX_FIXED_INSTANTIATE(T, M, N) \
extern "please include vnl/vnl_matrix_fixed.txx instead"
#endif // vnl_matrix_fixed_h_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -