コード例 #1
0
/*******************************************************************************
* int fit_ellipsoid(matrix_t points, vector_t* center, vector_t* lengths)
*
* Fits an ellipsoid to a set of points in 3D space. The principle axes of the
* fitted ellipsoid align with the global coordinate system. Therefore there are
* 6 degrees of freedom defining the ellipsoid: the x,y,z coordinates of the
* centroid and the lengths from the centroid to the surfance in each of the 3
* directions. 
*
* matrix_t points is a tall matrix with 3 columns and at least 6 rows. Each row
* must contain the xy&z components of each individual point to be fit. If only 
* 6 rows are provided, the resulting ellipsoid will be an exact fit. Otherwise
* the result is a least-squares fit to the overdefined dataset.
*
* vector_t* center is a pointer to a user-created vector which will contain the
* x,y,z position of the centroid of the fit ellipsoid.
*
* vector_t* lengths is a pointer to a user-created vector which will be 
* populated with the 3 distances from the surface to the centroid in each of the 
* 3 directions.
*******************************************************************************/
int fit_ellipsoid(matrix_t points, vector_t* center, vector_t* lengths){
	int i,p;
	matrix_t A;
	vector_t b;
	if(!points.initialized){
		printf("ERROR: matrix_t points not initialized\n");
		return -1;
	}
	if(points.cols!=3){
		printf("ERROR: matrix_t points must have 3 columns\n");
		return -1;
	}
	p = points.rows;
	if(p<6){
		printf("ERROR: matrix_t points must have at least 6 rows\n");
		return -1;
	}
	
	b = create_vector_of_ones(p);
	A = create_matrix(p,6);
	for(i=0;i<p;i++){
		A.data[i][0] = points.data[i][0] * points.data[i][0];
		A.data[i][1] = points.data[i][0];
		A.data[i][2] = points.data[i][1] * points.data[i][1];
		A.data[i][3] = points.data[i][1];
		A.data[i][4] = points.data[i][2] * points.data[i][2];
		A.data[i][5] = points.data[i][2];
	}
	
	vector_t f = lin_system_solve_qr(A,b);
	destroy_matrix(&A);
	destroy_vector(&b);
	
	// compute center 
	*center = create_vector(3);
	center->data[0] = -f.data[1]/(2*f.data[0]);
	center->data[1] = -f.data[3]/(2*f.data[2]);
	center->data[2] = -f.data[5]/(2*f.data[4]);
	
	// Solve for lengths
	A = create_square_matrix(3);
	b = create_vector(3);
	
	// fill in A
	A.data[0][0] = (f.data[0] * center->data[0] * center->data[0]) + 1.0;
	A.data[0][1] = (f.data[0] * center->data[1] * center->data[1]);
	A.data[0][2] = (f.data[0] * center->data[2] * center->data[2]);
	
	A.data[1][0] = (f.data[2] * center->data[0] * center->data[0]);
	A.data[1][1] = (f.data[2] * center->data[1] * center->data[1]) + 1.0;
	A.data[1][2] = (f.data[2] * center->data[2] * center->data[2]);
	
	A.data[2][0] = (f.data[4] * center->data[0] * center->data[0]);
	A.data[2][1] = (f.data[4] * center->data[1] * center->data[1]);
	A.data[2][2] = (f.data[4] * center->data[2] * center->data[2]) + 1.0;
	
	// fill in b
	b.data[0] = f.data[0];
	b.data[1] = f.data[2];
	b.data[2] = f.data[4];

	// solve for lengths
	vector_t scales = lin_system_solve(A, b);
	
	*lengths = create_vector(3);
	lengths->data[0] = 1.0/sqrt(scales.data[0]);
	lengths->data[1] = 1.0/sqrt(scales.data[1]);
	lengths->data[2] = 1.0/sqrt(scales.data[2]);
	// cleanup
	destroy_vector(&scales);
	destroy_matrix(&A);
	destroy_vector(&b);
	return 0;
}
コード例 #2
0
int main(){
	printf("Let's test some linear algebra functions....\n\n");
	
	// create a random nxn matrix for later use
	matrix_t A = create_random_matrix(DIM,DIM);
	printf("New Random Matrix A:\n");
	print_matrix(A);
	
	// also create random vector
	vector_t b = create_random_vector(DIM);
	printf("\nNew Random Vector b:\n");
	print_vector(b);
	
	// do an LUP decomposition on A
	matrix_t L,U,P;
	LUP_decomposition(A,&L,&U,&P);
	printf("\nL:\n");
	print_matrix(L);
	printf("U:\n");
	print_matrix(U);
	printf("P:\n");
	print_matrix(P);
	
	// do a QR decomposition on A
	matrix_t Q,R;
	QR_decomposition(A,&Q,&R);
	printf("\nQR Decomposition of A\n");
	printf("Q:\n");
	print_matrix(Q);
	printf("R:\n");
	print_matrix(R);
	
	// get determinant of A
	float det = matrix_determinant(A);
	printf("\nDeterminant of A : %8.4f\n", det);
	
	// get an inverse for A
	matrix_t Ainv = invert_matrix(A);
	if(A.initialized != 1) return -1;
	printf("\nAinverse\n");
	print_matrix(Ainv);
	
	// multiply A times A inverse
	matrix_t AA = multiply_matrices(A,Ainv);
	if(AA.initialized!=1) return -1;
	printf("\nA * Ainverse:\n");
	print_matrix(AA);
	
	// solve a square linear system
	vector_t x = lin_system_solve(A, b);
	printf("\nGaussian Elimination solution x to the equation Ax=b:\n");
	print_vector(x);
	
	// now do again but with qr decomposition method
	vector_t xqr = lin_system_solve_qr(A, b);
	printf("\nQR solution x to the equation Ax=b:\n");
	print_vector(xqr);
	
	// If b are the coefficients of a polynomial, get the coefficients of the
	// new polynomial b^2
	vector_t bb = poly_power(b,2);
	printf("\nCoefficients of polynomial b times itself\n");
	print_vector(bb);
	
	// clean up all the allocated memory. This isn't strictly necessary since
	// we are already at the end of the program, but good practice to do.
	destroy_matrix(&A);
	destroy_matrix(&AA);
	destroy_vector(&b);
	destroy_vector(&bb);
	destroy_vector(&x);
	destroy_vector(&xqr);
	destroy_matrix(&Q);
	destroy_matrix(&R);

	printf("DONE\n");
	return 0;
}