コード例 #1
0
ファイル: Affine.cpp プロジェクト: novas0x2a/isis3
/**
 * @brief Compute the inverse of a matrix
 *
 * This method will compute the inverse of an affine matrix for purposes of
 * forward and inverse Affine computations.
 *
 * @param a Matrix to invert
 *
 * @return Affine::AMatrix The inverted matrix
 */
Affine::AMatrix Affine::invert(const AMatrix &a) const throw (iException &) {
    // Now compute the inverse affine matrix using singular value
    // decomposition A = USV'.  So invA = V invS U'.  Where ' represents
    // the transpose of a matrix and invS is S with the recipricol of the
    // diagonal elements
    JAMA::SVD<double> svd(a);

    AMatrix V;
    svd.getV(V);

    // The inverse of S is 1 over each diagonal element of S
    AMatrix invS;
    svd.getS(invS);
    for (int i=0; i<invS.dim1(); i++) {
        if (invS[i][i] == 0.0) {
            string msg = "Affine transform not invertible";
            throw iException::Message(iException::Math,msg,_FILEINFO_);
        }
        invS[i][i] = 1.0 / invS[i][i];
    }

    // Transpose U
    AMatrix U;
    svd.getU(U);
    AMatrix transU(U.dim2(),U.dim1());
    for (int r=0; r<U.dim1(); r++) {
        for (int c=0; c<U.dim2(); c++) {
            transU[c][r] = U[r][c];
        }
    }

    // Multiply stuff together to get the inverse of the affine
    AMatrix VinvS = TNT::matmult(V,invS);
    return (TNT::matmult(VinvS,transU));
}
コード例 #2
0
ファイル: Affine.cpp プロジェクト: novas0x2a/isis3
/**
 * @brief Checks affine matrix to ensure it is a 3x3 standard form transform
 *
 * @param am Affine matrix to validate
 */
void Affine::checkDims(const AMatrix &am) const throw (iException &) {
    if ((am.dim1() != 3) && (am.dim2() != 3)) {
        ostringstream mess;
        mess << "Affine matrices must be 3x3 - this one is " << am.dim1()
             << "x" << am.dim2();
        throw iException::Message(iException::Programmer, mess.str(), _FILEINFO_);
    }
    return;
}