📄 vnl_vector.txx
字号:
// This is vxl/vnl/vnl_vector.txx
#ifndef vnl_vector_txx_
#define vnl_vector_txx_
//:
// \file
//
// Created: VDN 02/21/92 new lite version adapted from Matrix.h
//
// The parameterized vnl_vector<T> class implements 1D arithmetic vectors of a
// user specified type. The only constraint placed on the type is that
// it must overload the following operators: +, -, *, and /. Thus, it will
// be possible to have a vnl_vector over vcl_complex<T>. The vnl_vector<T>
// class is static in size, that is once a vnl_vector<T> of a particular
// size has been declared, elements cannot be added or removed. Using the
// make_size() method causes the vector to resize, but the contents will be
// lost.
//
// Each vector contains a protected data section that has a T* slot that
// points to the physical memory allocated for the one dimensional array. In
// addition, an integer specifies the number of elements for the
// vector. These values are provided in the constructors.
//
// Several constructors are provided. See .h file for descriptions.
//
// Methods are provided for destructive scalar and vector addition,
// multiplication, check for equality and inequality, fill, reduce, and access
// and set individual elements. Finally, both the input and output operators
// are overloaded to allow for fomatted input and output of vector elements.
//
// vnl_vector is a special type of matrix, and is implemented for space and time
// efficiency. When vnl_vector is pre_multiplied by/with matrix, m*v, vnl_vector is
// implicitly a column matrix. When vnl_vector is post_multiplied by/with matrix
// v*m, vnl_vector is implicitly a row matrix.
//
#include "vnl_vector.h"
#include <vcl_cstdlib.h> // abort()
#include <vcl_vector.h>
#include <vcl_iostream.h>
#include <vcl_algorithm.h>
#include <vnl/vnl_math.h>
#include <vnl/vnl_matrix.h>
#include <vnl/vnl_c_vector.h>
#include <vnl/vnl_numeric_traits.h>
//--------------------------------------------------------------------------------
// This macro allocates the dynamic storage used by a vnl_vector.
#define vnl_vector_alloc_blah(size) \
do { \
this->num_elmts = (size); \
this->data = vnl_c_vector<T>::allocate_T(this->num_elmts); \
} while (false)
// This macro deallocates the dynamic storage used by a vnl_vector.
#define vnl_vector_free_blah \
do { \
vnl_c_vector<T>::deallocate(this->data, this->num_elmts); \
} while (false)
//: Creates a vector with specified length. O(n).
// Elements are not initialized.
template<class T>
vnl_vector<T>::vnl_vector (unsigned len)
{
vnl_vector_alloc_blah(len);
}
//: Creates a vector of specified length, and initialize all elements with value. O(n).
template<class T>
vnl_vector<T>::vnl_vector (unsigned len, T const& value)
{
vnl_vector_alloc_blah(len);
for (unsigned i = 0; i < len; i ++) // For each elmt
this->data[i] = value; // Assign initial value
}
//: Creates a vector of specified length and initialize first n elements with values. O(n).
template<class T>
vnl_vector<T>::vnl_vector (unsigned len, int n, T const values[])
{
vnl_vector_alloc_blah(len);
if (n > 0) { // If user specified values
for (unsigned i = 0; i < len && n; i++, n--) // Initialize first n elements
this->data[i] = values[i]; // with values
}
}
//: Creates a vector of length 3 and initializes with the arguments, x,y,z.
template<class T>
vnl_vector<T>::vnl_vector (T const& px, T const& py, T const& pz)
{
vnl_vector_alloc_blah(3);
this->data[0] = px;
this->data[1] = py;
this->data[2] = pz;
}
#if 0 // commented out
//: Creates a vector of specified length and initialize first n elements with values in ... O(n).
// Arguments in ... can only be pointers, primitive types like int,
// and NOT OBJECTS passed by value, like vectors, matrices,
// because constructors must be known and called at compile time!!!
template<class T>
vnl_vector<T>::vnl_vector (unsigned len, int n, T v00, ...)
: num_elmts(len), data(vnl_c_vector<T>::allocate_T(len))
{
vcl_cerr << "Please use automatic arrays instead variable arguments\n";
if (n > 0) { // If user specified values
va_list argp; // Declare argument list
va_start (argp, v00); // Initialize macro
for (int i = 0; i < len && n; i++, n--) // For remaining values given
if (i == 0)
this->data[0] = v00; // Hack for v00 ...
else
this->data[i] = va_arg(argp, T); // Extract and assign
va_end(argp);
}
}
template<class T>
vnl_vector<T>::vnl_vector (unsigned len, int n, T v00, ...)
: num_elmts(len), data(vnl_c_vector<T>::allocate_T(len))
{
vcl_cerr << "Please use automatic arrays instead variable arguments\n";
if (n > 0) { // If user specified values
va_list argp; // Declare argument list
va_start (argp, v00); // Initialize macro
for (int i = 0; i < len && n; i++, n--) // For remaining values given
if (i == 0)
this->data[0] = v00; // Hack for v00 ...
else
this->data[i] = va_arg(argp, T); // Extract and assign
va_end(argp);
}
}
#endif
//: Creates a new copy of vector v. O(n).
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const& v)
{
vnl_vector_alloc_blah(v.num_elmts);
for (unsigned i = 0; i < v.num_elmts; i ++) // For each element in v
this->data[i] = v.data[i]; // Copy value
}
//: Creates a vector from a block array of data, stored row-wise.
// Values in datablck are copied. O(n).
template<class T>
vnl_vector<T>::vnl_vector (T const* datablck, unsigned len)
{
vnl_vector_alloc_blah(len);
for (unsigned i = 0; i < len; ++i) // Copy data from datablck
this->data[i] = datablck[i];
}
//------------------------------------------------------------
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &u, vnl_vector<T> const &v, vnl_tag_add)
{
vnl_vector_alloc_blah(u.num_elmts);
#if VNL_CONFIG_CHECK_BOUNDS && (!defined NDEBUG)
if (u.size() != v.size())
vnl_error_vector_dimension ("vnl_vector<>::vnl_vector(v, v, vnl_vector_add_tag)", u.size(), v.size());
#endif
for (unsigned int i=0; i<num_elmts; ++i)
data[i] = u[i] + v[i];
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &u, vnl_vector<T> const &v, vnl_tag_sub)
{
vnl_vector_alloc_blah(u.num_elmts);
#if VNL_CONFIG_CHECK_BOUNDS && (!defined NDEBUG)
if (u.size() != v.size())
vnl_error_vector_dimension ("vnl_vector<>::vnl_vector(v, v, vnl_vector_sub_tag)", u.size(), v.size());
#endif
for (unsigned int i=0; i<num_elmts; ++i)
data[i] = u[i] - v[i];
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &u, T s, vnl_tag_mul)
{
vnl_vector_alloc_blah(u.num_elmts);
for (unsigned int i=0; i<num_elmts; ++i)
data[i] = u[i] * s;
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &u, T s, vnl_tag_div)
{
vnl_vector_alloc_blah(u.num_elmts);
for (unsigned int i=0; i<num_elmts; ++i)
data[i] = u[i] / s;
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &u, T s, vnl_tag_add)
{
vnl_vector_alloc_blah(u.num_elmts);
for (unsigned int i=0; i<num_elmts; ++i)
data[i] = u[i] + s;
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &u, T s, vnl_tag_sub)
{
vnl_vector_alloc_blah(u.num_elmts);
for (unsigned int i=0; i<num_elmts; ++i)
data[i] = u[i] - s;
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_matrix<T> const &M, vnl_vector<T> const &v, vnl_tag_mul)
{
vnl_vector_alloc_blah(M.rows());
#ifndef NDEBUG
if (M.cols() != v.size())
vnl_error_vector_dimension ("vnl_vector<>::vnl_vector(M, v, vnl_vector_mul_tag)", M.cols(), v.size());
#endif
for (unsigned int i=0; i<num_elmts; ++i) {
T sum(0);
for (unsigned int j=0; j<M.cols(); ++j)
sum += M[i][j] * v[j];
data[i] = sum;
}
}
template<class T>
vnl_vector<T>::vnl_vector (vnl_vector<T> const &v, vnl_matrix<T> const &M, vnl_tag_mul)
{
vnl_vector_alloc_blah(M.cols());
#ifndef NDEBUG
if (v.size() != M.rows())
vnl_error_vector_dimension ("vnl_vector<>::vnl_vector(v, M, vnl_vector_mul_tag)", v.size(), M.rows());
#endif
for (unsigned int j=0; j<num_elmts; ++j) {
T sum(0);
for (unsigned int i=0; i<M.rows(); ++i)
sum += v[i] * M[i][j];
data[j] = sum;
}
}
//: Frees up the array inside vector. O(1).
template<class T>
void vnl_vector<T>::destroy()
{
vnl_vector_free_blah;
}
template<class T>
void vnl_vector<T>::clear()
{
if (data) {
destroy();
num_elmts = 0;
data = 0;
}
}
template<class T>
bool vnl_vector<T>::make_size(unsigned n)
{
if (this->data) {
// if no change in size, do not reallocate.
if (this->num_elmts == n)
return false;
vnl_vector_free_blah;
vnl_vector_alloc_blah(n);
}
else {
// this happens if the vector is default constructed.
vnl_vector_alloc_blah(n);
}
return true;
}
#undef vnl_vector_alloc_blah
#undef vnl_vector_free_blah
//------------------------------------------------------------
//: Read a vnl_vector from an ascii vcl_istream.
// If the vector has nonzero size on input, read that many values.
// Otherwise, read to EOF.
template <class T>
bool vnl_vector<T>::read_ascii(vcl_istream& s)
{
bool size_known = (this->size() != 0);
if (size_known) {
for (unsigned i = 0; i < this->size(); ++i)
s >> (*this)(i);
return s.good() || s.eof();
}
// Just read until EOF
vcl_vector<T> allvals;
unsigned n = 0;
while (!s.eof()) {
T value;
s >> value;
if (!s.good())
break;
allvals.push_back(value);
++n;
}
this->make_size(n); //*this = vnl_vector<T>(n);
for (unsigned i = 0; i < n; ++i)
(*this)[i] = allvals[i];
return true;
}
template <class T>
vnl_vector<T> vnl_vector<T>::read(vcl_istream& s)
{
vnl_vector<T> V;
V.read_ascii(s);
return V;
}
//: Sets all elements of a vector to a specified fill value. O(n).
template<class T>
void vnl_vector<T>::fill (T const& value) {
for (unsigned i = 0; i < this->num_elmts; i++)
this->data[i] = value;
}
//: Sets elements of a vector to those in an array. O(n).
template<class T>
void vnl_vector<T>::copy_in (T const *ptr) {
for (unsigned i = 0; i < num_elmts; ++i)
data[i] = ptr[i];
}
//: Sets elements of an array to those in vector. O(n).
template<class T>
void vnl_vector<T>::copy_out (T *ptr) const {
for (unsigned i = 0; i < num_elmts; ++i)
ptr[i] = data[i];
}
//: Copies rhs vector into lhs vector. O(n).
// Changes the dimension of lhs vector if necessary.
template<class T>
vnl_vector<T>& vnl_vector<T>::operator= (vnl_vector<T> const& rhs) {
if (this != &rhs) { // make sure *this != m
if (rhs.data) {
if (this->num_elmts != rhs.num_elmts)
this->make_size(rhs.size());
for (unsigned i = 0; i < this->num_elmts; i++)
this->data[i] = rhs.data[i];
}
else {
// rhs is default-constructed.
clear();
}
}
return *this;
}
//: Increments all elements of vector with value. O(n).
template<class T>
vnl_vector<T>& vnl_vector<T>::operator+= (T value) {
for (unsigned i = 0; i < this->num_elmts; i++)
this->data[i] += value;
return *this;
}
//: Multiplies all elements of vector with value. O(n).
template<class T>
vnl_vector<T>& vnl_vector<T>::operator*= (T value) {
for (unsigned i = 0; i < this->num_elmts; i++)
this->data[i] *= value;
return *this;
}
//: Divides all elements of vector by value. O(n).
template<class T>
vnl_vector<T>& vnl_vector<T>::operator/= (T value) {
for (unsigned i = 0; i < this->num_elmts; i++)
this->data[i] /= value;
return *this;
}
//: Mutates lhs vector with its addition with rhs vector. O(n).
template<class T>
vnl_vector<T>& vnl_vector<T>::operator+= (vnl_vector<T> const& rhs) {
#ifndef NDEBUG
if (this->num_elmts != rhs.num_elmts)
vnl_error_vector_dimension ("operator+=", this->num_elmts, rhs.num_elmts);
#endif
for (unsigned i = 0; i < this->num_elmts; i++)
this->data[i] += rhs.data[i];
return *this;
}
//: Mutates lhs vector with its substraction with rhs vector. O(n).
template<class T>
vnl_vector<T>& vnl_vector<T>::operator-= (vnl_vector<T> const& rhs) {
#ifndef NDEBUG
if (this->num_elmts != rhs.num_elmts)
vnl_error_vector_dimension ("operator-=", this->num_elmts, rhs.num_elmts);
#endif
for (unsigned i = 0; i < this->num_elmts; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -