Category : C++ Source Code
Archive   : JCOOL01.ZIP
Filename : M_VECTOR.C
// 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
//## hack to workaround BC++ 3.1 Envelope bug
#define CoolEnvelope CoolEnvelope_M_Vector
// compare_s -- Function used by == test
template
Boolean (*CoolM_Vector
// CoolM_Vector -- constructor specifiying size of CoolM_Vector
// Input: Length
// Output: None
template
CoolM_Vector
: 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
CoolM_Vector
: 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
CoolM_Vector
: 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
CoolM_Vector
: 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
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
void CoolM_Vector
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
CoolM_Vector
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
CoolM_Vector
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
Boolean CoolM_Vector
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
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
void CoolM_Vector
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
ostream& operator<< (ostream& s, const CoolM_Vector
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
CoolM_Vector
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
CoolM_Vector
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
CoolM_Vector
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
CoolM_Vector
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
CoolM_Vector
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
CoolM_Vector
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
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
temp[i] += (mm.get(i,k) * this->data[k]); // Multiply
}
delete this->data; // Free up the data space
num_elmts = m.rows(); // Set new num_elmts
this->data = temp; // Pointer to new storage
return *this; // Return vector reference
}
// post_multiply -- Destructive post_multiply vector with matrix. v = v * m
// num_elmts of vector must match num_rows of matrix
// Input: *this, matrix reference
// Output: Updated *this vector reference
template
CoolM_Vector
if (this->num_elmts != m.rows()) // dimensions do not match?
this->dimension_error ("operator*=", "Type",
this->num_elmts, m.rows());
Type* temp= new Type[m.columns()]; // Temporary
CoolMatrix
for (int i = 0; i < m.columns(); 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
temp[i] += (this->data[k] * mm.get(k,i)); // Multiply
}
delete this->data; // Free up the data space
num_elmts = m.columns(); // Set new num_elmts
this->data = temp; // Pointer to new storage
return *this; // Return vector reference
}
// operator- -- Non-destructive vector negation. a = -b;
// Input: *this
// Output: New vector
template
CoolEnvelope< CoolM_Vector
CoolM_Vector
for (int i = 0; i < this->num_elmts; i++)
temp.data[i] = - this->data[i]; // negate element
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// operator+ -- Non-destructive vector addition of a scalar.
// Input: *this, scalar value
// Output: New vector
template
CoolEnvelope< CoolM_Vector
CoolM_Vector
for (int i = 0; i < this->num_elmts; i++) // For each index
temp.data[i] = (this->data[i] + value); // Add scalar
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// operator* -- Non-destructive vector multiply by a scalar.
// Input: *this, scalar value
// Output: New vector
template
CoolEnvelope< CoolM_Vector
CoolM_Vector
for (int i = 0; i < this->num_elmts; i++) // For each index
temp.data[i] = (this->data[i] * value); // Multiply
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// operator/ -- Non-destructive vector division by a scalar.
// Input: *this, scalar value
// Output: New vector
template
CoolEnvelope< CoolM_Vector
CoolM_Vector
for (int i = 0; i < this->num_elmts; i++) // For each index
temp.data[i] = (this->data[i] / value); // Divide
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// operator* -- Non-destructive multiply matrix with vector: vb = m * va
// num_cols of first matrix must match num_elmts of second vector.
// Input: matrix, vector reference
// Output: New vector
template
CoolEnvelope< CoolM_Vector
if (m.columns() != v.num_elmts) // dimensions do not match?
v.dimension_error ("operator*", "Type",
m.columns(), v.num_elmts);
CoolM_Vector
CoolMatrix
for (int i = 0; i < m.rows(); i++) { // For each index
temp.data[i] = (Type) 0.0; // Initialize element value
for (int k = 0; k < v.num_elmts; k++) // Loop over column values
temp.data[i] += (mm.get(i,k) * v.data[k]); // Multiply
}
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// operator* -- Non-destructive multiply vector with matrix: vb = va * m
// num_elmts of first vector must match num_rows of second matrix.
// Input: vector, matrix reference
// Output: New vector
template
CoolEnvelope< CoolM_Vector
if (v.num_elmts != m.rows()) // dimensions do not match?
v.dimension_error ("operator*", "Type",
v.num_elmts, m.rows());
CoolM_Vector
CoolMatrix
for (int i = 0; i < m.columns(); i++) { // For each index
temp.data[i] = (Type) 0.0; // Initialize element value
for (int k = 0; k < v.num_elmts; k++) // Loop over column values
temp.data[i] += (v.data[k] * mm.get(k,i)); // Multiply
}
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// update -- replace a subvector of this, by the actual argument.
// Input: *this, starting corner specified by top and left.
// Ouput: mutated reference.
template
CoolM_Vector
unsigned int start) {
unsigned int end = start + v.num_elmts;
if (this->num_elmts < end)
this->dimension_error ("update", "Type",
end-start, v.num_elmts);
for (int i = start; i < end; i++)
this->data[i] = v.data[i-start];
return *this;
}
// extract -- Return a subvector specified by the start-left corner and size.
// Input: *this, starting corner specified by start and left, and size.
// Ouput: new vector
template
CoolEnvelope< CoolM_Vector
unsigned int end = start + len;
if (this->num_elmts < end)
this->dimension_error ("extract", "Type",
end-start, len);
CoolM_Vector
for (int i = 0; i < len; i++)
temp.data[i] = data[start+i];
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// abs -- Return vector of absolute values. v[i] = abs(v[i])
// Input: *this
// Ouput: new vector
template
CoolEnvelope< CoolM_Vector
CoolM_Vector
for (int i = 0; i < this->num_elmts; i++)
if (this->data[i] < 0)
temp.data[i] = - this->data[i];
else
temp.data[i] = this->data[i];
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// sign -- Mutate *this to store signs, either -1,1 or 0, depending on
// whether the corresponding values are negative, positive, or 0.
// Input: *this
// Ouput: *this mutated.
template
CoolEnvelope< CoolM_Vector
CoolM_Vector
for (int i = 0; i < this->num_elmts; i++)
if (this->data[i] == 0) // test fuzz equality to 0
temp.data[i] = 0; // first.
else
if (this->data[i] < 0)
temp.data[i] = -1;
else
temp.data[i] = 1;
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// element_product -- return the vector whose elements are the products
// Input: 2 vectors v1, v2 by reference
// Output: New vector, whose elements are v1[i]*v2[i].
template
CoolEnvelope< CoolM_Vector
if (v1.num_elmts != v2.num_elmts) // Size?
v1.dimension_error ("element_product", "Type",
v1.num_elmts, v2.num_elmts);
CoolM_Vector
for (int i = 0; i < v1.num_elmts; i++)
temp.data[i] = v1.data[i] * v2.data[i];
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// element_quotient -- return the vector whose elements are the quotients
// Input: 2 vectors v1, v2 by reference
// Output: New vector, whose elements are v1[i]/v2[i].
template
CoolEnvelope< CoolM_Vector
if (v1.num_elmts != v2.num_elmts) // Size?
v1.dimension_error ("element_quotient", "Type",
v1.num_elmts, v2.num_elmts);
CoolM_Vector
for (int i = 0; i < v1.num_elmts; i++)
temp.data[i] = v1.data[i] / v2.data[i];
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
// dot_product -- Return the dot product of the vectors
// Input: 2 vectors by reference
// Ouput: dot product value
template
Type dot_product (const CoolM_Vector
if (v1.num_elmts != v2.num_elmts) // Size?
v1.dimension_error ("dot_product", "Type",
v1.num_elmts, v2.num_elmts);
Type dot = 0;
for (int i = 0; i < v1.num_elmts; i++)
dot += v1.data[i] * v2.data[i]; // of vectors
return dot;
}
// cross_2d -- Return the 2X1 cross-product of 2 2d-vectors
// Input: 2 vectors by reference
// Ouput: cross product value
template
Type cross_2d (const CoolM_Vector
if (v1.num_elmts != 2 || v2.num_elmts != 2)
v1.dimension_error ("cross_2d", "Type",
v1.num_elmts, v2.num_elmts);
return (v1.x() * v2.y()
-
v1.y() * v2.x());
}
// cross_3d -- Return the 3X1 cross-product of 2 3d-vectors
// Input: 2 vectors by reference
// Ouput: 3d cross product vector
template
CoolEnvelope< CoolM_Vector
if (v1.num_elmts != 3 || v2.num_elmts != 3)
v1.dimension_error ("cross_3d", "Type",
v1.num_elmts, v2.num_elmts);
CoolM_Vector
temp.x() = v1.y() * v2.z() - v1.z() * v2.y(); // work for both col/row
temp.y() = v1.z() * v2.x() - v1.x() * v2.z(); // representation
temp.z() = v1.x() * v2.y() - v1.y() * v2.x();
CoolEnvelope< CoolM_Vector
return result; // copy of envelope
}
//## hack to workaround BC++ 3.1 Envelope bug
#undef CoolEnvelope
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/