int palindrome(int number) { if (number == inversed(number)) return 1; else return 0; }
Matrix Matrix::getInversed() const { Matrix::value_type det = determinant(); if (util::equals(det, 0.0)) { ERR("Determinant is zero!"); throw MatrixInversionException(); } Matrix inversed(m_size); for (size_t row = 0; row < m_size; ++row) { for (size_t col = 0; col < m_size; ++col) { Matrix adjugate(*this, col, row); // note the inversion of 'row' and 'col' Matrix::value_type cofactor = adjugate.determinant(); double sign = util::equals(cofactor, 0.0) ? 1.0 : std::pow(-1.0, row + col); inversed[row][col] = sign * cofactor / det; } } return inversed; }
/* This function is intended to be used on a ModelView MutableMatrix44D. ModelView = Projection * Model */ Vector3D MutableMatrix44D::unproject(const Vector3D& pixel3D, const int vpLeft, const int vpTop, const int vpWidth, const int vpHeight) const { int TODO_Remove_UNPROJECT;//!!!! const double winx = pixel3D._x; const double winy = pixel3D._y; const double winz = pixel3D._z; const double in0 = (winx - vpLeft) * 2 / vpWidth - 1.0; const double in1 = (winy - vpTop) * 2 / vpHeight - 1.0; const double in2 = 2 * winz - 1.0; const double in3 = 1.0; //Inverse MutableMatrix44D m = inversed(); //To object coordinates //Transformating point const double out0 = m._m00 * in0 + m._m01 * in1 + m._m02 * in2 + m._m03 * in3; const double out1 = m._m10 * in0 + m._m11 * in1 + m._m12 * in2 + m._m13 * in3; const double out2 = m._m20 * in0 + m._m21 * in1 + m._m22 * in2 + m._m23 * in3; const double out3 = m._m30 * in0 + m._m31 * in1 + m._m32 * in2 + m._m33 * in3; if (out3 == 0.0) { return Vector3D::nan(); } const double objx = out0 / out3; const double objy = out1 / out3; const double objz = out2 / out3; return Vector3D(objx, objy, objz); }
void Matrix<T>::invert() { *this = inversed(); }
Matrix<double> Matrix<double>::Inverse(void) const { if ( GetColumnLength() != GetRowLength() ) { return *this; } // Calculate Inversed-Matrix<double> by Cofactors. const size_t rowCount = GetRowLength(); const size_t colCount = GetColumnLength(); Matrix<double> inversed(rowCount, colCount); #if 0 double det = Determinant(); if ( 0 == det ) { return *this; } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = 0; col < colCount; ++col) { int sign = ((row + col) & 1) ? -1 : 1; Matrix<double> m(GetCofactorMatrix(row, col)); inversed[col][row] = GetCofactor(row, col) / det; } } #else //-------------------------------- // Gauss-Jordan //-------------------------------- const double threshold = 1.0e-10; // TBD Matrix<double> m(rowCount, colCount * 2); if ( m.IsNull() ) { return m; } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = 0; col < colCount; ++col) { m[row][col] = (*this)[row][col]; } } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = colCount; col < colCount * 2; ++col) { if (row == (col - colCount)) { m[row][col] = 1.0; } else { m[row][col] = 0.0; } } } // 各行を正規化 for (size_t r = 0; r < m.GetRowLength(); ++r ) { m[r] /= m[r].GetMaximumAbsolute(); } for (size_t r = 0; r < m.GetRowLength(); ++r ) { // 注目している列の中で、最大値を持つ列を探す。 size_t index = r; double maximum = fabs(m[r][r]); // "k < m.GetRowLength() - 1" となっていたが、意図不明なので修正。 for (size_t k = index + 1; k < m.GetRowLength(); ++k ) { if ( fabs(m[k][r]) > maximum ) { index = k; maximum = fabs(m[k][r]); } } if ( maximum < threshold ) { // ここに到達することはないはず。 DEBUG_LOG(" ~ 0 at r=%d\n", static_cast<int>(r)); m.Resize(0, 0); // NULL を返す。 return m; } // 必要なら入れ替える if ( r != index ) { const Vectord tmp(m[r]); m[r] = m[index]; m[index] = tmp; } // 上で入れ替えたので 以降では index は不要、r を使用する。 // 注目している行の、注目している列の値を 1.0 にする m[r] /= m[r][r]; // /= maximum; // maximum では符号が考慮されない。 // 他の行から引く。 for (size_t k = 0; k < m.GetRowLength(); ++k ) { if ( k == r ) { continue; } const Vectord tmp(m[r]); m[k] -= (tmp * m[k][r]); } } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = 0; col < colCount; ++col) { inversed[row][col] = m[row][col+colCount]; } } #endif return inversed; }