#ifndef __JMATRIX2D__ #define __JMATRIX2D__ #include #include #include #include #include "JIO/JSerialisable.hh" #include "JLang/JEquals.hh" #include "JLang/JManip.hh" #include "JMath/JMath.hh" /** * \author mdejong */ namespace JMATH {} namespace JPP { using namespace JMATH; } namespace JMATH { using JIO::JReader; using JIO::JWriter; using JLANG::JEquals; /** * 2 x 2 matrix */ class JMatrix2D : public JMath , public JEquals { public: using JMath::mul; /** * Default constructor. */ JMatrix2D() : a00(0.0), a01(0.0), a10(0.0), a11(0.0) {} /** * Contructor. * * \param __a00 (0,0) * \param __a01 (0,1) * \param __a10 (1,0) * \param __a11 (1,1) */ JMatrix2D(const double __a00, const double __a01, const double __a10, const double __a11) : a00(__a00), a01(__a01), a10(__a10), a11(__a11) {} /** * Get reference to unique instance of this class object. * * \return zero matrix */ static const JMatrix2D& getInstance() { static JMatrix2D matrix; return matrix; } /** * Set to identity matrix. * * \return this matrix */ JMatrix2D& setIdentity() { a00 = 1.0; a01 = 0.0; a10 = 0.0; a11 = 1.0; return *this; } /** * Get reference to unique instance of this class object. * * \return identity matrix */ static const JMatrix2D& getIdentity() { static JMatrix2D matrix(JMatrix2D().setIdentity()); return matrix; } /** * Set matrix. * * \param A matrix */ void set(const JMatrix2D& A) { static_cast(*this) = A; } /** * Set matrix to the null matrix. * * \return this matrix */ JMatrix2D& reset() { *this = JMatrix2D(); return *this; } /** * Transpose. * * \return this matrix */ JMatrix2D& transpose() { using std::swap; swap(a10, a01); return *this; } /** * Negate matrix. * * \return -this matrix */ JMatrix2D& negate() { a00 = -a00; a01 = -a01; a10 = -a10; a11 = -a11; return *this; } /** * Matrix addition. * * \param A matrix * \return this matrix + A */ JMatrix2D& add(const JMatrix2D& A) { a00 += A.a00; a01 += A.a01; a10 += A.a10; a11 += A.a11; return *this; } /** * Matrix subtraction. * * \param A matrix * \return this matrix - A */ JMatrix2D& sub(const JMatrix2D& A) { a00 -= A.a00; a01 -= A.a01; a10 -= A.a10; a11 -= A.a11; return *this; } /** * Scale matrix. * * \param factor factor * \return this matrix * factor */ JMatrix2D& mul(const double factor) { a00 *= factor; a01 *= factor; a10 *= factor; a11 *= factor; return *this; } /** * Scale matrix. * * \param factor factor * \return this matrix / factor */ JMatrix2D& div(const double factor) { a00 /= factor; a01 /= factor; a10 /= factor; a11 /= factor; return *this; } /** * Matrix multiplication. * * \param A matrix * \param B matrix * \return this matrix */ JMatrix2D& mul(const JMatrix2D& A, const JMatrix2D& B) { a00 = A.a00 * B.a00 + A.a01 * B.a10; a01 = A.a00 * B.a01 + A.a01 * B.a11; a10 = A.a10 * B.a00 + A.a11 * B.a10; a11 = A.a10 * B.a01 + A.a11 * B.a11; return *this; } /** * Equality. * * \param A matrix * \param eps numerical precision * \return true if matrices identical; else false */ bool equals(const JMatrix2D& A, const double eps = std::numeric_limits::min()) const { return (fabs(a00 - A.a00) <= eps && fabs(a01 - A.a01) <= eps && fabs(a10 - A.a10) <= eps && fabs(a11 - A.a11) <= eps); } /** * Test identity. * * \param eps numerical precision * \return true if identity matrix; else false */ bool isIdentity(const double eps = std::numeric_limits::min()) const { return equals(getIdentity(), eps); } /** * Get determinant of matrix. * * \return determinant of matrix */ double getDeterminant() const { return a00 * a11 - a01 * a10; } /** * Transform. * * \param __x x value * \param __y y value */ void transform(double& __x, double& __y) const { const double x = a00 * __x + a01 * __y; const double y = a10 * __x + a11 * __y; __x = x; __y = y; } /** * Read matrix from input. * * \param in reader * \param matrix matrix * \return reader */ friend inline JReader& operator>>(JReader& in, JMatrix2D& matrix) { in >> matrix.a00; in >> matrix.a01; in >> matrix.a10; in >> matrix.a11; return in; } /** * Write matrix to output. * * \param out writer * \param matrix matrix * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JMatrix2D& matrix) { out << matrix.a00; out << matrix.a01; out << matrix.a10; out << matrix.a11; return out; } /** * Print ASCII formatted output. * * \param out output stream * \param A matrix * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JMatrix2D& A) { using namespace std; const JFormat format(out, getFormat(JFormat_t(10, 3, std::ios::fixed | std::ios::showpos))); out << format << A.a00 << ' ' << format << A.a01 << endl; out << format << A.a10 << ' ' << format << A.a11 << endl; return out; } double a00, a01; double a10, a11; }; } #endif