Practical guidelines for writing correct and efficient MtxVec code.
1. Always use try/finally with CreateIt/FreeIt:
TVec* a = nullptr;
TVec* b = nullptr;
CreateIt(a, b);
try
{
// ... use a, b ...
}
catch (...)
{
FreeIt(a, b); // runs when an exception leaves the block ...
throw;
}
FreeIt(a, b); // ... and this one on the normal path
In C++ both FreeIt calls are required — the one in the catch (...) block and the one after it — or an exception leaks pool objects. Vector and Matrix need neither.
2. Mixing Vector and TVec in the same code:
Vector v; // automatic lifetime
v.Size(100); // v manages itself
TVec* t = nullptr;
CreateIt(t);
try
{
t->Size(100);
t->Sin(v); // OK: Vector converts to TVec* implicitly
}
catch (...)
{
FreeIt(t);
throw;
}
FreeIt(t);
3. Avoid element-by-element loops:
// BAD — slow, not vectorized
for (int i = 0; i < a.GetLength(); i++)
a.Values(i) = std::sin(a.Values(i));
// GOOD — vectorized, SIMD, potentially multithreaded
a.Sin();
The vectorized form is 10-100x faster depending on array size and operation.
4. Use compound operations when formula matches:
// BAD — 3 passes through memory, 2 temporaries
c.Mul(a, b);
c.Add(d);
// GOOD — 1 pass, no temporaries
c.MulAndAdd(a, b, d); // c = a * b + d
5. Handle exceptions — they signal contract violations only:
An exception is raised only when a genuine violation of an operation's contract occurs. Exceptions are never used to report normal processing results:
Size(0)is legal — an empty vector or matrix is a valid state, not an error.NANandINFare valid floating-point values — they propagate through computations normally and raise nothing.
| Class | Raised when |
|---|---|
EMtxVecException | base class of all MtxVec exceptions |
EMtxVecRangeError | an index or length falls outside the valid range |
EMtxVecInvalidArgument | a parameter violates the method's contract |
EOutOfMemory | allocation failure |
In C++ the exceptions are thrown by value and derive from Dew::tException, whose Message field holds the text; catch them by const reference: catch (const EMtxVecException& e). A singular matrix is not an exception: LUSolve reports it through Info — m->GetInfo() is non-zero — and leaves x unchanged, so check Info after the call.
// A matrix product requires A.Cols == B.Rows
try
{
C.Mul(A, B);
}
catch (const EMtxVecException& e)
{
std::printf("Mul failed: %s\n", e.Message.c_str());
}
6. Sizing is automatic:
You never need to call Size() before writing to a vector or matrix — every operation that writes a result calls Size() on the destination implicitly, matching it to its inputs.