m_vector.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 570 行 · 第 1/2 页
C
570 行
//
// Copyright (C) 1991 Texas Instruments Incorporated.
// Copyright (C) 1992 General Electric Company.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated, General Electric Company,
// provides this software "as is" without express or implied warranty.
//
#include <cool/M_Vector.h> // header of vector and its envelope
//## hack to workaround BC++ 3.1 Envelope bug
#define CoolEnvelope CoolEnvelope_M_Vector
// compare_s -- Function used by == test
template <class Type>
Boolean (*CoolM_Vector<Type>::compare_s)(const Type&, const Type&) = &CoolM_Vector_is_data_equal;
// CoolM_Vector -- constructor specifiying size of CoolM_Vector
// Input: Length
// Output: None
template<class Type>
CoolM_Vector<Type>::CoolM_Vector(unsigned int len)
: CoolBase_M_Vector(len)
{
this->data = new Type[len]; // Allocate the elements
}
// CoolM_Vector -- constructor specifiying size of vector and initial value
// Input: Length and initial value
// Output: None
template<class Type>
CoolM_Vector<Type>::CoolM_Vector(unsigned int len, const Type& value)
: CoolBase_M_Vector(len)
{
this->data = new Type[len]; // Allocate the elements
for (int i = 0; i < len; i ++) { // For each elmt in the CoolM_Vector
this->data[i] = value; // Assign initial value
}
}
// CoolM_Vector -- constructor specifiying size of vector and initial values
// Input: Length and initial values
// Output: None
// Note: Arguments in ... can only be pointers, primitive types like int,
// and NOT OBJECTS, passed by reference or value, like vectors, matrices;
// because constructors must be known and called at compile time!!!
// Cannot have char in ..., because char is 1 instead of 4 bytes, and
// va_arg expects sizeof(Type) a multiple of 4 bytes.
template<class Type>
CoolM_Vector<Type>::CoolM_Vector(unsigned int len, int n, Type v00, ...)
: CoolBase_M_Vector(len)
{
#if ERROR_CHECKING
if (((sizeof(Type) % 4) != 0) || // Cause alignment problems
(sizeof(Type) > 8)) // User defined classes?
this->va_arg_error("Type", sizeof(Type)); // So, cannot use this constructor
#endif
this->data = new Type[len]; // Allocate the elements
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, Type); // Extract and assign
va_end(argp);
}
}
// CoolM_Vector -- constructor for reference to another CoolM_Vector object
// Input: CoolM_Vector reference
// Output: None
template<class Type>
CoolM_Vector<Type>::CoolM_Vector(const CoolM_Vector<Type>& v)
: CoolBase_M_Vector(v)
{
this->data = new Type[this->num_elmts]; // Allocate the elements
for (int i = 0; i < this->num_elmts; i ++) { // For each element in the CoolM_Vector
this->data[i] = v.data[i]; // Copy value
}
}
// ~CoolM_Vector -- Destructor for CoolM_Vector class that frees up storage
// Input: *this
// Output: None
template<class Type>
CoolM_Vector<Type>::~CoolM_Vector() {
delete this->data; // Free up the data space
}
// fill -- Set all elements of a vector to a specified fill value
// Input: *this, reference to fill value
// Output: None
template<class Type>
void CoolM_Vector<Type>::fill (const Type& value) {
for (int i = 0; i < this->num_elmts; i++) // For each index in the CoolM_Vector
this->data[i] = value; // Assign fill value
}
// operator= -- Overload the assignment operator to assign a single
// value to the elements of a CoolM_Vector.
// Input: *this, reference to a value
// Output: Reference to updated CoolM_Vector object
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator= (const Type& value) {
for (int i = 0; i < this->num_elmts; i++) // For each index in CoolM_Vector
this->data[i] = value; // Assign value
return *this; // Return CoolM_Vector reference
}
// operator= -- Overload the assignment operator to copy the elements
// in one CoolM_Vector to another. The existing storage for the
// destination vector is freed up and new storage of the same
// size as the source is allocated.
// Input: *this, reference to CoolM_Vector
// Output: Reference to copied CoolM_Vector object
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator= (const CoolM_Vector<Type>& v) {
if (this != &v) { // make sure *this != m
if (this->num_elmts != v.num_elmts) {
delete this->data; // Free up the data space
this->num_elmts = v.num_elmts; // Copy index specification
this->data = new Type[this->num_elmts]; // Allocate the elements
}
for (int i = 0; i < this->num_elmts; i++) // For each index
this->data[i] = v.data[i]; // Copy value
}
return *this; // Return CoolM_Vector reference
}
// operator== -- Compare the elements of two Matrices of Type Type using
// the Compare pointer to funtion (default is ==). If one
// CoolM_Vector has more elements than the other, the
// result is FALSE
// Input: Reference to CoolM_Vector of Type Type
// Output: TRUE/FALSE
template<class Type>
Boolean CoolM_Vector<Type>::operator== (const CoolM_Vector<Type>& v) const {
if (this->num_elmts != v.num_elmts) // Size?
return FALSE; // Then not equal
for (int i = 0; i < this->num_elmts; i++) // For each index
if ((*this->compare_s)(this->data[i],v.data[i]) == FALSE) // Same?
return FALSE; // Then no match
return TRUE; // Else same, so return TRUE
}
// is_data_equal -- Default data comparison function if user has not provided
// another one. Note that this is not inline because we need
// to take the address of it for the compare static variable
// Input: Two Type references
// Output: TRUE/FALSE
template<class Type>
Boolean CoolM_Vector_is_data_equal (const Type& t1, const Type& t2) {
return (t1 == t2);
}
// set_compare -- Specify the comparison function to be used
// in logical tests of vector elements
// Input: Pointer to a compare function
// Output: None
template<class Type>
void CoolM_Vector<Type>::set_compare (register Boolean (*c) (const Type&, const Type&)) {
if (c == NULL) // If no argument supplied
this->compare_s = &CoolM_Vector_is_data_equal; // Default is_equal
else
this->compare_s = c; // Else set to user function
}
// operator<< -- Overload the output operator to print a vector
// Input: ostream reference, CoolM_Vector reference
// Output: ostream reference
template<class Type>
ostream& operator<< (ostream& s, const CoolM_Vector<Type>& v) {
for (int i = 0; i < v.num_elmts; i++) { // For each index in vector
s << v.data[i] << " "; // Output data element
}
return (s); // Return ostream reference
}
// operator+= -- Destructive vector addition of a scalar.
// Input: *this, scalar value
// Output: New vector reference
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator+= (const Type& value) {
for (int i = 0; i < this->num_elmts; i++) // For each index
this->data[i] += value; // Add scalar
return *this;
}
// operator*= -- Destructive vector multiplication by a scalar.
// Input: *this, scalar value
// Output: New vector reference
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator*= (const Type& value) {
for (int i = 0; i < this->num_elmts; i++) // For each index
this->data[i] *= value; // Multiply by scalar
return *this;
}
// operator/= -- Destructive vector division by a scalar.
// Input: *this, scalar value
// Output: New vector reference
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator/= (const Type& value) {
for (int i = 0; i < this->num_elmts; i++) // For each index
this->data[i] /= value; // division by scalar
return *this;
}
// operator+= -- Destructive vector addition with assignment. Note that the
// dimensions of each vector must be identical
// Input: *this, vector reference
// Output: Updated *this vector reference
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator+= (const CoolM_Vector<Type>& v) {
if (this->num_elmts != v.num_elmts) // Size?
this->dimension_error ("operator+=", "Type",
this->num_elmts, v.num_elmts);
for (int i = 0; i < this->num_elmts; i++) // For each index
this->data[i] += v.data[i]; // Add elements
return *this;
}
// operator-= -- Destructive vector subtraction with assignment. Note that the
// dimensions of each vector must be identical
// Input: *this, vector reference
// Output: Updated *this vector reference
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::operator-= (const CoolM_Vector<Type>& v) {
if (this->num_elmts != v.num_elmts) // Size?
this->dimension_error ("operator-=", "Type",
this->num_elmts, v.num_elmts);
for (int i = 0; i < this->num_elmts; i++)
this->data[i] -= v.data[i];
return *this;
}
// pre_multiply -- Destructive pre_multiply vector with matrix. v = m * v
// num_cols of matrix must match num_elmts of vector
// Input: *this, matrix reference
// Output: Updated *this vector reference
template<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::pre_multiply (const CoolMatrix<Type>& m) {
if (m.columns() != this->num_elmts) // dimensions do not match?
this->dimension_error ("operator*=", "Type",
this->num_elmts, m.columns());
Type* temp= new Type[m.rows()]; // Temporary
CoolMatrix<Type>& mm = (CoolMatrix<Type>&) m; // Drop const for get()
for (int i = 0; i < m.rows(); i++) { // For each index
temp[i] = (Type) 0.0; // Initialize element value
for (int k = 0; k < this->num_elmts; k++) // Loop over column values
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?