Пример #1
0
void MatrixMxN<Scalar>::singularValueDecomposition(MatrixMxN<Scalar> &left_singular_vectors,
                                                   VectorND<Scalar> &singular_values,
                                                   MatrixMxN<Scalar> &right_singular_vectors) const
{
#ifdef PHYSIKA_USE_EIGEN_MATRIX
    //hack: Eigen::SVD does not support integer types, hence we cast Scalar to long double for decomposition
    unsigned int rows = this->rows(), cols = this->cols();
    Eigen::Matrix<long double,Eigen::Dynamic,Eigen::Dynamic> temp_matrix(rows,cols);
    for(unsigned int i = 0; i < rows; ++i)
        for(unsigned int j = 0; j < cols; ++j)          
                temp_matrix(i,j) = static_cast<long double>((*ptr_eigen_matrix_MxN_)(i,j));
    Eigen::JacobiSVD<Eigen::Matrix<long double,Eigen::Dynamic,Eigen::Dynamic> > svd(temp_matrix,Eigen::ComputeThinU|Eigen::ComputeThinV);
    const Eigen::Matrix<long double,Eigen::Dynamic,Eigen::Dynamic> &left = svd.matrixU(), &right = svd.matrixV();
    const Eigen::Matrix<long double,Eigen::Dynamic,1> &values = svd.singularValues();
    //resize if have to
    if(left_singular_vectors.rows() != left.rows() || left_singular_vectors.cols() != left.cols())
        left_singular_vectors.resize(left.rows(),left.cols());
    if(right_singular_vectors.rows() != right.rows() || right_singular_vectors.cols() != right.cols())
        right_singular_vectors.resize(right.rows(),right.cols());
    if(singular_values.dims() != values.rows())
        singular_values.resize(values.rows());
    //copy the result
    for(unsigned int i = 0; i < left.rows(); ++i)
        for(unsigned int j = 0; j < left.cols(); ++j)
            left_singular_vectors(i,j) = static_cast<Scalar>(left(i,j));
    for(unsigned int i = 0; i < right.rows(); ++i)
        for(unsigned int j = 0; j < right.cols(); ++j)
            right_singular_vectors(i,j) = static_cast<Scalar>(right(i,j));
    for(unsigned int i = 0; i < values.rows(); ++i)
        singular_values[i] = static_cast<Scalar>(values(i,0));
#elif defined(PHYSIKA_USE_BUILT_IN_MATRIX)
    std::cerr<<"SVD not implemeted for built in matrix!\n";
    std::exit(EXIT_FAILURE);
#endif
}
Пример #2
0
const MatrixMxN<Scalar> VectorND<Scalar>::outerProduct(const VectorND<Scalar> &vec2) const
{
    MatrixMxN<Scalar> result(this->dims(),vec2.dims());
    for(unsigned int i = 0; i < result.rows(); ++i)
        for(unsigned int j = 0; j < result.cols(); ++j)
            result(i,j) = (*this)[i]*vec2[j];
    return result;
}
Пример #3
0
void MatrixMxN<Scalar>::eigenDecomposition(VectorND<Scalar> &eigen_values_real, VectorND<Scalar> &eigen_values_imag,
                                           MatrixMxN<Scalar> &eigen_vectors_real, MatrixMxN<Scalar> &eigen_vectors_imag)
{
    unsigned int rows = this->rows(), cols = this->cols();
    if(rows != cols)
    {
        std::cerr<<"Eigen decomposition is only valid for square matrix!\n";
        std::exit(EXIT_FAILURE);
    }
#ifdef PHYSIKA_USE_EIGEN_MATRIX
    //hack: Eigen::EigenSolver does not support integer types, hence we cast Scalar to long double for decomposition
    Eigen::Matrix<long double,Eigen::Dynamic,Eigen::Dynamic> temp_matrix(rows,cols);
    for(unsigned int i = 0; i < rows; ++i)
        for(unsigned int j = 0; j < cols; ++j)          
                temp_matrix(i,j) = static_cast<long double>((*ptr_eigen_matrix_MxN_)(i,j));
    Eigen::EigenSolver<Eigen::Matrix<long double,Eigen::Dynamic,Eigen::Dynamic> > eigen(temp_matrix);
    Eigen::Matrix<std::complex<long double>,Eigen::Dynamic,Eigen::Dynamic> vectors = eigen.eigenvectors();
    const Eigen::Matrix<std::complex<long double>,Eigen::Dynamic,1> &values = eigen.eigenvalues();
    //resize if have to
    if(eigen_vectors_real.rows() != vectors.rows() || eigen_vectors_real.cols() != vectors.cols())
        eigen_vectors_real.resize(vectors.rows(),vectors.cols());
    if(eigen_vectors_imag.rows() != vectors.rows() || eigen_vectors_imag.cols() != vectors.cols())
        eigen_vectors_imag.resize(vectors.rows(),vectors.cols());
    if(eigen_values_real.dims() != values.rows())
        eigen_values_real.resize(values.rows());
    if(eigen_values_imag.dims() != values.rows())
        eigen_values_imag.resize(values.rows());
    //copy the result
    for(unsigned int i = 0; i < vectors.rows(); ++i)
        for(unsigned int j = 0; j < vectors.cols(); ++j)
        {
            eigen_vectors_real(i,j) = static_cast<Scalar>(vectors(i,j).real());
            eigen_vectors_imag(i,j) = static_cast<Scalar>(vectors(i,j).imag());
        }
    for(unsigned int i = 0; i < values.rows(); ++i)
    {
        eigen_values_real[i] = static_cast<Scalar>(values(i,0).real());
        eigen_values_imag[i] = static_cast<Scalar>(values(i,0).imag());
    }
#elif defined(PHYSIKA_USE_BUILT_IN_MATRIX)
    std::cerr<<"Eigen decomposition not implemeted for built in matrix!\n";
    std::exit(EXIT_FAILURE);
#endif
}
Пример #4
0
VectorND<Scalar>::VectorND(const VectorND<Scalar> &vec2)
#ifdef PHYSIKA_USE_EIGEN_VECTOR
    :eigen_vector_Nx_(vec2.eigen_vector_Nx_)
#endif 
{
#ifdef PHYSIKA_USE_BUILT_IN_VECTOR
    allocMemory(vec2.dims());
    *this = vec2;
#endif  
}
Пример #5
0
Scalar VectorND<Scalar>::dot(const VectorND<Scalar> &vec2) const
{
    unsigned int dim1 = (*this).dims();
    unsigned int dim2 = vec2.dims();
    if(dim1 != dim2)
        throw PhysikaException("vector dimension mismatch!");
    Scalar result = static_cast<Scalar>(0.0);
    for(unsigned int i = 0; i < dim1; ++i)
        result += (*this)[i]*vec2[i];
    return result;
}
Пример #6
0
VectorND<Scalar> MatrixMxN<Scalar>::operator* (const VectorND<Scalar> &vec) const
{
    unsigned int mat_row = (*this).rows();
    unsigned int mat_col = (*this).cols();
    unsigned int vec_dim = vec.dims();
    if(mat_col!=vec_dim)
    {
        std::cerr<<"Matrix*Vector: Matrix and vector sizes do not match!\n";
        std::exit(EXIT_FAILURE);
    }
    VectorND<Scalar> result(mat_row,0.0);
    for(unsigned int i = 0; i < mat_row; ++i)
    {
        for(unsigned int j = 0; j < mat_col; ++j)
            result[i] += (*this)(i,j)*vec[j];
    }
    return result;
}
Пример #7
0
bool VectorND<Scalar>::operator== (const VectorND<Scalar> &vec2) const
{
    unsigned int dim1 = (*this).dims();
    unsigned int dim2 = vec2.dims();
    if(dim1 != dim2)
        return false;
    for(unsigned int i = 0; i < dim1; ++i)
    {
        if(is_floating_point<Scalar>::value)
        {
            if(isEqual((*this)[i],vec2[i])==false)
                return false;
        }
        else
        {
            if((*this)[i] != vec2[i])
                return false;
        }
    }
    return true;
}