You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
12 KiB
353 lines
12 KiB
// matrix/kaldi-vector.h
|
|
|
|
// Copyright 2009-2012 Ondrej Glembek; Microsoft Corporation; Lukas Burget;
|
|
// Saarland University (Author: Arnab Ghoshal);
|
|
// Ariya Rastrow; Petr Schwarz; Yanmin Qian;
|
|
// Karel Vesely; Go Vivace Inc.; Arnab Ghoshal
|
|
// Wei Shi;
|
|
// 2015 Guoguo Chen
|
|
// 2017 Daniel Galvez
|
|
// 2019 Yiwen Shao
|
|
|
|
// See ../../COPYING for clarification regarding multiple authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
// WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
// MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
// See the Apache 2 License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef KALDI_MATRIX_KALDI_VECTOR_H_
|
|
#define KALDI_MATRIX_KALDI_VECTOR_H_ 1
|
|
|
|
#include "matrix/matrix-common.h"
|
|
|
|
namespace kaldi {
|
|
|
|
/// \addtogroup matrix_group
|
|
/// @{
|
|
|
|
/// Provides a vector abstraction class.
|
|
/// This class provides a way to work with vectors in kaldi.
|
|
/// It encapsulates basic operations and memory optimizations.
|
|
template <typename Real>
|
|
class VectorBase {
|
|
public:
|
|
/// Set vector to all zeros.
|
|
void SetZero();
|
|
|
|
/// Returns true if matrix is all zeros.
|
|
bool IsZero(Real cutoff = 1.0e-06) const; // replace magic number
|
|
|
|
/// Set all members of a vector to a specified value.
|
|
void Set(Real f);
|
|
|
|
/// Returns the dimension of the vector.
|
|
inline MatrixIndexT Dim() const { return dim_; }
|
|
|
|
/// Returns the size in memory of the vector, in bytes.
|
|
inline MatrixIndexT SizeInBytes() const { return (dim_ * sizeof(Real)); }
|
|
|
|
/// Returns a pointer to the start of the vector's data.
|
|
inline Real *Data() { return data_; }
|
|
|
|
/// Returns a pointer to the start of the vector's data (const).
|
|
inline const Real *Data() const { return data_; }
|
|
|
|
/// Indexing operator (const).
|
|
inline Real operator()(MatrixIndexT i) const {
|
|
KALDI_PARANOID_ASSERT(static_cast<UnsignedMatrixIndexT>(i) <
|
|
static_cast<UnsignedMatrixIndexT>(dim_));
|
|
return *(data_ + i);
|
|
}
|
|
|
|
/// Indexing operator (non-const).
|
|
inline Real &operator()(MatrixIndexT i) {
|
|
KALDI_PARANOID_ASSERT(static_cast<UnsignedMatrixIndexT>(i) <
|
|
static_cast<UnsignedMatrixIndexT>(dim_));
|
|
return *(data_ + i);
|
|
}
|
|
|
|
/** @brief Returns a sub-vector of a vector (a range of elements).
|
|
* @param o [in] Origin, 0 < o < Dim()
|
|
* @param l [in] Length 0 < l < Dim()-o
|
|
* @return A SubVector object that aliases the data of the Vector object.
|
|
* See @c SubVector class for details */
|
|
SubVector<Real> Range(const MatrixIndexT o, const MatrixIndexT l) {
|
|
return SubVector<Real>(*this, o, l);
|
|
}
|
|
|
|
/** @brief Returns a const sub-vector of a vector (a range of elements).
|
|
* @param o [in] Origin, 0 < o < Dim()
|
|
* @param l [in] Length 0 < l < Dim()-o
|
|
* @return A SubVector object that aliases the data of the Vector object.
|
|
* See @c SubVector class for details */
|
|
const SubVector<Real> Range(const MatrixIndexT o,
|
|
const MatrixIndexT l) const {
|
|
return SubVector<Real>(*this, o, l);
|
|
}
|
|
|
|
/// Copy data from another vector (must match own size).
|
|
void CopyFromVec(const VectorBase<Real> &v);
|
|
|
|
/// Copy data from another vector of different type (double vs. float)
|
|
template <typename OtherReal>
|
|
void CopyFromVec(const VectorBase<OtherReal> &v);
|
|
|
|
/// Performs a row stack of the matrix M
|
|
void CopyRowsFromMat(const MatrixBase<Real> &M);
|
|
template <typename OtherReal>
|
|
void CopyRowsFromMat(const MatrixBase<OtherReal> &M);
|
|
|
|
/// Performs a column stack of the matrix M
|
|
void CopyColsFromMat(const MatrixBase<Real> &M);
|
|
|
|
/// Extracts a row of the matrix M. Could also do this with
|
|
/// this->Copy(M[row]).
|
|
void CopyRowFromMat(const MatrixBase<Real> &M, MatrixIndexT row);
|
|
/// Extracts a row of the matrix M with type conversion.
|
|
template <typename OtherReal>
|
|
void CopyRowFromMat(const MatrixBase<OtherReal> &M, MatrixIndexT row);
|
|
|
|
/// Extracts a column of the matrix M.
|
|
template <typename OtherReal>
|
|
void CopyColFromMat(const MatrixBase<OtherReal> &M, MatrixIndexT col);
|
|
|
|
/// Reads from C++ stream (option to add to existing contents).
|
|
/// Throws exception on failure
|
|
void Read(std::istream &in, bool binary);
|
|
|
|
/// Writes to C++ stream (option to write in binary).
|
|
void Write(std::ostream &Out, bool binary) const;
|
|
|
|
friend class VectorBase<double>;
|
|
friend class VectorBase<float>;
|
|
|
|
protected:
|
|
/// Destructor; does not deallocate memory, this is handled by child
|
|
/// classes.
|
|
/// This destructor is protected so this object can only be
|
|
/// deleted via a child.
|
|
~VectorBase() {}
|
|
|
|
/// Empty initializer, corresponds to vector of zero size.
|
|
explicit VectorBase() : data_(NULL), dim_(0) {
|
|
KALDI_ASSERT_IS_FLOATING_TYPE(Real);
|
|
}
|
|
|
|
/// data memory area
|
|
Real *data_;
|
|
/// dimension of vector
|
|
MatrixIndexT dim_;
|
|
KALDI_DISALLOW_COPY_AND_ASSIGN(VectorBase);
|
|
}; // class VectorBase
|
|
|
|
/** @brief A class representing a vector.
|
|
*
|
|
* This class provides a way to work with vectors in kaldi.
|
|
* It encapsulates basic operations and memory optimizations. */
|
|
template <typename Real>
|
|
class Vector : public VectorBase<Real> {
|
|
public:
|
|
/// Constructor that takes no arguments. Initializes to empty.
|
|
Vector() : VectorBase<Real>() {}
|
|
|
|
/// Constructor with specific size. Sets to all-zero by default
|
|
/// if set_zero == false, memory contents are undefined.
|
|
explicit Vector(const MatrixIndexT s,
|
|
MatrixResizeType resize_type = kSetZero)
|
|
: VectorBase<Real>() {
|
|
Resize(s, resize_type);
|
|
}
|
|
|
|
/// Copy constructor from CUDA vector
|
|
/// This is defined in ../cudamatrix/cu-vector.h
|
|
// template<typename OtherReal>
|
|
// explicit Vector(const CuVectorBase<OtherReal> &cu);
|
|
|
|
/// Copy constructor. The need for this is controversial.
|
|
Vector(const Vector<Real> &v)
|
|
: VectorBase<Real>() { // (cannot be explicit)
|
|
Resize(v.Dim(), kUndefined);
|
|
this->CopyFromVec(v);
|
|
}
|
|
|
|
/// Copy-constructor from base-class, needed to copy from SubVector.
|
|
explicit Vector(const VectorBase<Real> &v) : VectorBase<Real>() {
|
|
Resize(v.Dim(), kUndefined);
|
|
this->CopyFromVec(v);
|
|
}
|
|
|
|
/// Type conversion constructor.
|
|
template <typename OtherReal>
|
|
explicit Vector(const VectorBase<OtherReal> &v) : VectorBase<Real>() {
|
|
Resize(v.Dim(), kUndefined);
|
|
this->CopyFromVec(v);
|
|
}
|
|
|
|
// Took this out since it is unsafe : Arnab
|
|
// /// Constructor from a pointer and a size; copies the data to a location
|
|
// /// it owns.
|
|
// Vector(const Real* Data, const MatrixIndexT s): VectorBase<Real>() {
|
|
// Resize(s);
|
|
// CopyFromPtr(Data, s);
|
|
// }
|
|
|
|
|
|
/// Swaps the contents of *this and *other. Shallow swap.
|
|
void Swap(Vector<Real> *other);
|
|
|
|
/// Destructor. Deallocates memory.
|
|
~Vector() { Destroy(); }
|
|
|
|
/// Read function using C++ streams. Can also add to existing contents
|
|
/// of matrix.
|
|
void Read(std::istream &in, bool binary);
|
|
|
|
/// Set vector to a specified size (can be zero).
|
|
/// The value of the new data depends on resize_type:
|
|
/// -if kSetZero, the new data will be zero
|
|
/// -if kUndefined, the new data will be undefined
|
|
/// -if kCopyData, the new data will be the same as the old data in any
|
|
/// shared positions, and zero elsewhere.
|
|
/// This function takes time proportional to the number of data elements.
|
|
void Resize(MatrixIndexT length, MatrixResizeType resize_type = kSetZero);
|
|
|
|
/// Remove one element and shifts later elements down.
|
|
void RemoveElement(MatrixIndexT i);
|
|
|
|
/// Assignment operator.
|
|
Vector<Real> &operator=(const Vector<Real> &other) {
|
|
Resize(other.Dim(), kUndefined);
|
|
this->CopyFromVec(other);
|
|
return *this;
|
|
}
|
|
|
|
/// Assignment operator that takes VectorBase.
|
|
Vector<Real> &operator=(const VectorBase<Real> &other) {
|
|
Resize(other.Dim(), kUndefined);
|
|
this->CopyFromVec(other);
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
/// Init assumes the current contents of the class are invalid (i.e. junk or
|
|
/// has already been freed), and it sets the vector to newly allocated
|
|
/// memory
|
|
/// with the specified dimension. dim == 0 is acceptable. The memory
|
|
/// contents
|
|
/// pointed to by data_ will be undefined.
|
|
void Init(const MatrixIndexT dim);
|
|
|
|
/// Destroy function, called internally.
|
|
void Destroy();
|
|
};
|
|
|
|
|
|
/// Represents a non-allocating general vector which can be defined
|
|
/// as a sub-vector of higher-level vector [or as the row of a matrix].
|
|
template <typename Real>
|
|
class SubVector : public VectorBase<Real> {
|
|
public:
|
|
/// Constructor from a Vector or SubVector.
|
|
/// SubVectors are not const-safe and it's very hard to make them
|
|
/// so for now we just give up. This function contains const_cast.
|
|
SubVector(const VectorBase<Real> &t,
|
|
const MatrixIndexT origin,
|
|
const MatrixIndexT length)
|
|
: VectorBase<Real>() {
|
|
// following assert equiv to origin>=0 && length>=0 &&
|
|
// origin+length <= rt.dim_
|
|
KALDI_ASSERT(static_cast<UnsignedMatrixIndexT>(origin) +
|
|
static_cast<UnsignedMatrixIndexT>(length) <=
|
|
static_cast<UnsignedMatrixIndexT>(t.Dim()));
|
|
VectorBase<Real>::data_ = const_cast<Real *>(t.Data() + origin);
|
|
VectorBase<Real>::dim_ = length;
|
|
}
|
|
|
|
/// This constructor initializes the vector to point at the contents
|
|
/// of this packed matrix (SpMatrix or TpMatrix).
|
|
// SubVector(const PackedMatrix<Real> &M) {
|
|
// VectorBase<Real>::data_ = const_cast<Real*> (M.Data());
|
|
// VectorBase<Real>::dim_ = (M.NumRows()*(M.NumRows()+1))/2;
|
|
//}
|
|
|
|
/// Copy constructor
|
|
SubVector(const SubVector &other) : VectorBase<Real>() {
|
|
// this copy constructor needed for Range() to work in base class.
|
|
VectorBase<Real>::data_ = other.data_;
|
|
VectorBase<Real>::dim_ = other.dim_;
|
|
}
|
|
|
|
/// Constructor from a pointer to memory and a length. Keeps a pointer
|
|
/// to the data but does not take ownership (will never delete).
|
|
/// Caution: this constructor enables you to evade const constraints.
|
|
SubVector(const Real *data, MatrixIndexT length) : VectorBase<Real>() {
|
|
VectorBase<Real>::data_ = const_cast<Real *>(data);
|
|
VectorBase<Real>::dim_ = length;
|
|
}
|
|
|
|
/// This operation does not preserve const-ness, so be careful.
|
|
SubVector(const MatrixBase<Real> &matrix, MatrixIndexT row) {
|
|
VectorBase<Real>::data_ = const_cast<Real *>(matrix.RowData(row));
|
|
VectorBase<Real>::dim_ = matrix.NumCols();
|
|
}
|
|
|
|
~SubVector() {} ///< Destructor (does nothing; no pointers are owned here).
|
|
|
|
private:
|
|
/// Disallow assignment operator.
|
|
SubVector &operator=(const SubVector &other) {}
|
|
};
|
|
|
|
/// @} end of "addtogroup matrix_group"
|
|
/// \addtogroup matrix_funcs_io
|
|
/// @{
|
|
/// Output to a C++ stream. Non-binary by default (use Write for
|
|
/// binary output).
|
|
template <typename Real>
|
|
std::ostream &operator<<(std::ostream &out, const VectorBase<Real> &v);
|
|
|
|
/// Input from a C++ stream. Will automatically read text or
|
|
/// binary data from the stream.
|
|
template <typename Real>
|
|
std::istream &operator>>(std::istream &in, VectorBase<Real> &v);
|
|
|
|
/// Input from a C++ stream. Will automatically read text or
|
|
/// binary data from the stream.
|
|
template <typename Real>
|
|
std::istream &operator>>(std::istream &in, Vector<Real> &v);
|
|
/// @} end of \addtogroup matrix_funcs_io
|
|
|
|
/// \addtogroup matrix_funcs_scalar
|
|
/// @{
|
|
|
|
|
|
// template<typename Real>
|
|
// bool ApproxEqual(const VectorBase<Real> &a,
|
|
// const VectorBase<Real> &b, Real tol = 0.01) {
|
|
// return a.ApproxEqual(b, tol);
|
|
//}
|
|
|
|
// template<typename Real>
|
|
// inline void AssertEqual(VectorBase<Real> &a, VectorBase<Real> &b,
|
|
// float tol = 0.01) {
|
|
// KALDI_ASSERT(a.ApproxEqual(b, tol));
|
|
//}
|
|
|
|
|
|
} // namespace kaldi
|
|
|
|
// we need to include the implementation
|
|
#include "matrix/kaldi-vector-inl.h"
|
|
|
|
|
|
#endif // KALDI_MATRIX_KALDI_VECTOR_H_
|