m_vector.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 570 行 · 第 1/2 页
C
570 行
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<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::post_multiply (const CoolMatrix<Type>& m) {
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<Type>& mm = (CoolMatrix<Type>&) m; // Drop const for get()
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::operator- () const {
CoolM_Vector<Type> temp(this->num_elmts);
for (int i = 0; i < this->num_elmts; i++)
temp.data[i] = - this->data[i]; // negate element
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
return result; // copy of envelope
}
// operator+ -- Non-destructive vector addition of a scalar.
// Input: *this, scalar value
// Output: New vector
template<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::operator+ (const Type& value) const {
CoolM_Vector<Type> temp(this->num_elmts);
for (int i = 0; i < this->num_elmts; i++) // For each index
temp.data[i] = (this->data[i] + value); // Add scalar
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
return result; // copy of envelope
}
// operator* -- Non-destructive vector multiply by a scalar.
// Input: *this, scalar value
// Output: New vector
template<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::operator* (const Type& value) const {
CoolM_Vector<Type> temp(this->num_elmts);
for (int i = 0; i < this->num_elmts; i++) // For each index
temp.data[i] = (this->data[i] * value); // Multiply
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
return result; // copy of envelope
}
// operator/ -- Non-destructive vector division by a scalar.
// Input: *this, scalar value
// Output: New vector
template<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::operator/ (const Type& value) const {
CoolM_Vector<Type> temp(this->num_elmts);
for (int i = 0; i < this->num_elmts; i++) // For each index
temp.data[i] = (this->data[i] / value); // Divide
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > operator* (const CoolMatrix<Type>& m, const CoolM_Vector<Type>& v) {
if (m.columns() != v.num_elmts) // dimensions do not match?
v.dimension_error ("operator*", "Type",
m.columns(), v.num_elmts);
CoolM_Vector<Type> temp(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.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<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > operator* (const CoolM_Vector<Type>& v, const CoolMatrix<Type>&m) {
if (v.num_elmts != m.rows()) // dimensions do not match?
v.dimension_error ("operator*", "Type",
v.num_elmts, m.rows());
CoolM_Vector<Type> temp(m.columns()); // Temporary
CoolMatrix<Type>& mm = (CoolMatrix<Type>&) m; // Drop const for get()
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<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
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<class Type>
CoolM_Vector<Type>& CoolM_Vector<Type>::update (const CoolM_Vector<Type>& v,
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::extract (unsigned int len, unsigned int start) const{
unsigned int end = start + len;
if (this->num_elmts < end)
this->dimension_error ("extract", "Type",
end-start, len);
CoolM_Vector<Type> temp(len);
for (int i = 0; i < len; i++)
temp.data[i] = data[start+i];
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
return result; // copy of envelope
}
// abs -- Return vector of absolute values. v[i] = abs(v[i])
// Input: *this
// Ouput: new vector
template<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::abs() const {
CoolM_Vector<Type> temp(this->num_elmts);
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<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::sign () const {
CoolM_Vector<Type> temp(this->num_elmts);
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<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > element_product (const CoolM_Vector<Type>& v1, const CoolM_Vector<Type>& v2) {
if (v1.num_elmts != v2.num_elmts) // Size?
v1.dimension_error ("element_product", "Type",
v1.num_elmts, v2.num_elmts);
CoolM_Vector<Type> temp(v1.num_elmts);
for (int i = 0; i < v1.num_elmts; i++)
temp.data[i] = v1.data[i] * v2.data[i];
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > element_quotient (const CoolM_Vector<Type>& v1, const CoolM_Vector<Type>& v2) {
if (v1.num_elmts != v2.num_elmts) // Size?
v1.dimension_error ("element_quotient", "Type",
v1.num_elmts, v2.num_elmts);
CoolM_Vector<Type> temp(v1.num_elmts);
for (int i = 0; i < v1.num_elmts; i++)
temp.data[i] = v1.data[i] / v2.data[i];
CoolEnvelope< CoolM_Vector<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
return result; // copy of envelope
}
// dot_product -- Return the dot product of the vectors
// Input: 2 vectors by reference
// Ouput: dot product value
template<class Type>
Type dot_product (const CoolM_Vector<Type>& v1, const CoolM_Vector<Type>& v2) {
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<class Type>
Type cross_2d (const CoolM_Vector<Type>& v1, const CoolM_Vector<Type>& v2) {
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<class Type>
CoolEnvelope< CoolM_Vector<Type> > cross_3d (const CoolM_Vector<Type>& v1, const CoolM_Vector<Type>& v2) {
if (v1.num_elmts != 3 || v2.num_elmts != 3)
v1.dimension_error ("cross_3d", "Type",
v1.num_elmts, v2.num_elmts);
CoolM_Vector<Type> temp(v1.num_elmts);
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<Type> >& result = (CoolEnvelope< CoolM_Vector<Type> >&) temp; // same physical object
return result; // copy of envelope
}
//## hack to workaround BC++ 3.1 Envelope bug
#undef CoolEnvelope
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?