示例#1
0
Basis Basis::diagonalize() {

	//NOTE: only implemented for symmetric matrices
	//with the Jacobi iterative method method
	
	ERR_FAIL_COND_V(!is_symmetric(), Basis());

	const int ite_max = 1024;

	real_t off_matrix_norm_2 = elements[0][1] * elements[0][1] + elements[0][2] * elements[0][2] + elements[1][2] * elements[1][2]; 

	int ite = 0;
	Basis acc_rot;
	while (off_matrix_norm_2 > CMP_EPSILON2 && ite++ < ite_max ) {
		real_t el01_2 = elements[0][1] * elements[0][1];
		real_t el02_2 = elements[0][2] * elements[0][2];
		real_t el12_2 = elements[1][2] * elements[1][2];
		// Find the pivot element
		int i, j;
		if (el01_2 > el02_2) {
			if (el12_2 > el01_2) {
				i = 1;
				j = 2;
			} else {
				i = 0;
				j = 1;
			}	
		} else {
			if (el12_2 > el02_2) {
				i = 1;
				j = 2;
			} else {
				i = 0;
				j = 2;
			}
		}

		// Compute the rotation angle
	    real_t angle;
		if (Math::abs(elements[j][j] - elements[i][i]) < CMP_EPSILON) {
			angle = Math_PI / 4;
		} else {
			angle = 0.5 * Math::atan(2 * elements[i][j] / (elements[j][j] - elements[i][i]));		
		}

		// Compute the rotation matrix
		Basis rot;
		rot.elements[i][i] = rot.elements[j][j] = Math::cos(angle);
		rot.elements[i][j] = - (rot.elements[j][i] = Math::sin(angle));

		// Update the off matrix norm
		off_matrix_norm_2 -= elements[i][j] * elements[i][j];

		// Apply the rotation
		*this = rot * *this * rot.transposed();
		acc_rot = rot * acc_rot;
	}

	return acc_rot;
}
示例#2
0
static void validate_matrices(const SparseMatrix *L, const SparseMatrix *P)
{
    EXPENSIVE_ASSERT(is_lower(L));
    EXPENSIVE_ASSERT(check_symbolic_zeros(L));
    EXPENSIVE_ASSERT(is_symmetric(P));

    assert(L->N == P->N);
    assert(P->nz == NZ_SYM(L->nz, L->N));
}
示例#3
0
        int cholesky_basic_checked(ublas::matrix<double,F,A> &m, const bool upper)
            // Perform Cholesky decomposition, but do not zero out other-triangular part.
            // Returns 0 if matrix was actual positive-definite, otherwise it returns a
            // LAPACK info value.
        {
            if (m.size1() != m.size2())
                throw LogicalError(ERROR_INFO("Matrix is not square"));
            assert(is_symmetric(m)); 

            // Call LAPACK routine
            int info;
            char uplo = detail::uplo_flag(m, upper);
            int size = static_cast<int>(m.size1());
            detail::dpotrf_( &uplo, &size, &m.data()[0], &size, &info );

            // Check validity of result
            if (info < 0) 
                throw LogicalError(ERROR_INFO("Invalid argument"), info);

            return info;
        }
示例#4
0
	void run() {
		// Do some validation of the arguments
		if (graph.rows() != graph.cols()) {
			throw std::invalid_argument("Matrix must be square");
		}
		if (graph.any_element_is_inf_or_nan()) {
			throw std::invalid_argument("Matrix includes Inf or NaN values");
		}
		if (graph.any_element_is_negative()) {
			throw std::invalid_argument("Matrix includes negative values");
		}
		if (!is_symmetric(graph)) {
			throw std::invalid_argument("Matrix must be symmetric");
		}
		if (!clustering.empty() && (int)clustering.size() != graph.rows()) {
			throw std::invalid_argument("Initial value must have same size as the matrix");
		}
		
		// initialize Clustering object
		params.lossfun = lossfun.get();
		srand(seed);
		Clustering clus(graph,params);
		if (!clustering.empty()) {
			clus.set_clustering(clustering);
		}
		
		// perform clustering
		if (optimize) {
			clus.optimize();
		}
		
		// outputs
		clustering = clus.get_clustering();
		loss = clus.get_loss();
		num_clusters = clus.num_clusters();
	}
示例#5
0
/*
 * Is this matrix hermitian?
 *
 * Definition: http://en.wikipedia.org/wiki/Hermitian_matrix
 *
 * For non-complex matrices, this function should return the same result as symmetric?.
 */
static VALUE nm_hermitian(VALUE self) {
  return is_symmetric(self, true);
}
示例#6
0
int main()
{
  is_symmetric("abcba");

  return 0;
}