C++ Builder specific features of MtxVec
TVec and TMtx classes are written in Delphi and C++ Builder generates appropriate header files automatically. However C++ syntax allows more flexible language constructs than pascal. MtxVecCpp.h is designed to merge native C++ coding style and part of MtxVec library, which is coded in Delphi. C++ developers may easily declare vectors and matrices as local variables and enjoy the support for operator overloading.
Extra features for C++ developers
By analogy with smart pointers in C++, MtxVec library defines shell classes in MtxVecCpp.h Vector and Matrix for TVec and TMtx classes respectively. Pascal style forces to declare variables as below:
TVec* v;
CreateIt (v);
try {
v->Sin();
} __finally { FreeIt (v);}
C++ style looks much simpler:
{
Vector v;
v->Sin();
}
Constructor creates actual object, destructor releases it and operator ->() provides access to actual TVec object. Vector and Matrix classes use reference counting mechanism to optimize assignment operations and when working with subranges.
Introduced classes
Classes Vector, Matrix, SparseMatrix are smart shells for classes TVec, TMtx, TSparseMtx respectively. Classes CVector and CMatrix are defined to allow a more comfortable access to complex elements via the [ ] operator, but are otherwise identical as Vector and Matrix.
Examples of definitions:
Vector v1(10); // real vector of ten elements
Vector v2(10,true); // complex vector of ten elements
CVector v3(10); // complex vector of ten elements
Matrix m1(10,10); // real matrix 10x10
Matrix m2(10,10,true); // complex matrix 10x10
CMatrix m3(10,10); // complex matrix 10x10
Operator overloading
Classes Vector and Matrix overload many operators: +, -, *, /, =, etc. They enable the use of vectors and matrices in arithmetic expressions next to integers, doubles and complex numbers.
Vector v(10); // vector of ten elements;
v=1.23; // assign 1.23 to each element of vector
v=v+v; // double each element
v=v*2; // double each element again
v*=2; // and again
To get access to elements of the vector we can use operator[](int):
v[0] = v[1] + v[2];
or
v.Values(0) = v.Values(1) + v.Values(2);
Matrix requires the long form to access the elements:
m.Values(0,0) = m.Values(1,1)+ m.Values(1,2);
Differentiating between elements and objects
All operators, which are defined for Vector and Matrix classes, work with elements. The next expression applies multiplication element by element instead of multiplying two matrices:
Matrix a(2,2),b(2,2),c;
c = a * b;
To apply multiplication of two matrices its necessary to call method TMtx::Mul:
c->Mul(a,b);
Subranges
MtxVec library allows the programmer to work with a selected range of the vector or matrix. For this purpose the following functions exist: SetSubrange / SetSubindex / SetFullRange. However, C++ syntax allows the use of more compact constructs. For example, operator()(int,int) of Vector represents a view of a part of the source vector:
Vector v(6);
v->Ramp(); // v = [0,1,2,3,4,5]
v(0,1) = v(2,3) + v(4,5); // v[0]=v[2]+v[4], v[1]=[3]+v[4]
// v = [6,8,2,3,4,5]
The good thing about this is that subranges are implemented in a manner so efficient that the traditional loop based code will in most cases execute substantially slower. Another example is operator()(int) of Matrix, which obtains a vector view of a row of the matrix:
Matrix m(3,3); // matrix 3x3
m->SetZero(); // set all elements of matrix to zero
m(1)->Ramp(1,1); // set second row to 1,2,3 (TVec method!)
// m is (0,0,0,
// 1,2,3,
// 0,0,0);
Operator ()(void) maps the whole matrix to vector:
Matrix m(3,3); // matrix 3x3
m()->Ramp(); // m =[0,1,2,
//3,4,5,
//6,7,8];
m() *= 2; // double each element
// m = [0,2,4,
// 6,8,10,
// 12,14,16];
Methods and functions
Almost all methods can be replaced with functions. The next line:
v->Sin(x);
Is equivalent to:
y = Sin(x);
All standard function from <math> header file also defined in MtxVecCpp.h.
So, the next syntax is allowed as well:
y = sin(x);
Range Checking
All Value access methods are range checked, when debugging is active. MtxVecCPP.h holds the following definition:
#ifdef _DEBUG
#define MTXVEC_RANGE_CHECKING 1
#else
#undef MTXVEC_RANGE_CHECKING
#endif
Active range checking can have a noticeable effect on performance