int matrix_square_root_n(int n, double *X, double *I, double *Y) { /* This function calculates one of the square roots of the matrix X and stores it in Y: X = sqrt(Y); X needs to be a symmetric positive definite matrix of dimension n*n in Fortran vector format. Y is of course a vector of similar size, and will contain the result on exit. Y will be used as a workspace variable in the meantime. The variable I is a vector of length n containing +1 and -1 elements. It can be used to select one of the 2^n different square roots of X This function first calculates the eigenvalue decomposition of X: X = U*D*U^T A new matrix F is then calculated with on the diagonal the square roots of D, with signs taken from I. The square root is then obtained by calculating U*F*U^T */ if (check_input(X, Y, "matrix_square_root_n")) return 1; double *eigval, *eigvec, *temp; int info = 0, i, j; /* Memory allocation */ eigval=(double*) malloc(n*sizeof(double)); eigvec=(double*) malloc(n*n*sizeof(double)); temp=(double*) malloc(n*n*sizeof(double)); if ((eigval==NULL)||(eigvec==NULL)||(temp==NULL)) { printf("malloc failed in matrix_square_root_n\n"); return 2; } /* Eigen decomposition */ info=eigen_decomposition(n, X, eigvec, eigval); if (info != 0) return info; /* Check for positive definitiveness*/ for (i=0; i<n; i++) if (eigval[i]<0) { fprintf(stderr, "In matrix_square_root_n: Matrix is not positive definite.\n"); return 1; } /* Build square rooted diagonal matrix, with sign signature I */ for (i=0; i<n; i++) for (j=0; j<n; j++) Y[i*n+j] = 0.0; for (i=0; i<n; i++) Y[i*n+i] = I[i]*sqrt(eigval[i]); /* Multiply the eigenvectors with this diagonal matrix Y. Store back in Y */ matrix_matrix_mult(n, n, n, 1.0, 0, eigvec, Y, temp); vector_copy(n*n, temp, Y); /* Transpose eigenvectors. Store in temp */ matrix_transpose(n, n, eigvec, temp); /* Multiply Y with this temp. Store in eigvec which is no longer required. Copy to Y */ matrix_matrix_mult(n, n, n, 1.0, 0, Y, temp, eigvec); vector_copy(n*n, eigvec, Y); /* Cleanup and exit */ free(eigvec); free(eigval); free(temp); return info; }
void matrix_vect3_rotate ( const float in[16], const float vect[3], float t, float out[16] ) { const float x = vect[0], y = vect[1], z = vect[2]; const float sin_t = sinf( t ), cos_t = cosf( t ); float res[16]; const float matrix[16] = { cos_t + ( 1.0f - cos_t ) * x * x, ( 1.0f - cos_t ) * x * y - sin_t * z, ( 1.0f - cos_t ) * x * z + sin_t * y, 0.0f, ( 1.0f - cos_t ) * y * x + sin_t * z, cos_t + ( 1.0f - cos_t ) * y * y, ( 1.0f - cos_t ) * y * z - sin_t * x, 0.0f, ( 1.0f - cos_t ) * z * x - sin_t * y, ( 1.0f - cos_t ) * z * y + sin_t * x, cos_t + ( 1.0f - cos_t ) * z * z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; matrix_matrix_mult( in, matrix, res ); vect4_copy( &in[4 * 3], &res[4 * 3] ); matrix_copy( res, out ); }
void form_svd_product_matrix(mat *U, mat *S, mat *V, mat *P){ int k,m,n; double alpha, beta; alpha = 1.0; beta = 0.0; m = P->nrows; n = P->ncols; k = S->nrows; mat * SVt = matrix_new(k,n); // form SVt = S*V^T matrix_matrix_transpose_mult(S,V,SVt); // form P = U*S*V^T matrix_matrix_mult(U,SVt,P); }
void estimate_rank_and_buildQ2(mat *M, int kblock, double TOL, mat **Y, mat **Q, int *good_rank){ int m,n,i,j,ind,exit_loop = 0; double error_norm; mat *RN,*Y_new,*Y_big,*QtM,*QQtM; vec *vi,*vj,*p,*p1; m = M->nrows; n = M->ncols; // build random matrix printf("form RN..\n"); RN = matrix_new(n,kblock); initialize_random_matrix(RN); // multiply to get matrix of random samples Y printf("form Y: %d x %d..\n",m,kblock); *Y = matrix_new(m, kblock); matrix_matrix_mult(M, RN, *Y); ind = 0; while(!exit_loop){ printf("form Q..\n"); if(ind > 0){ matrix_delete(*Q); } *Q = matrix_new((*Y)->nrows, (*Y)->ncols); QR_factorization_getQ(*Y, *Q); // compute QtM QtM = matrix_new((*Q)->ncols, M->ncols); matrix_transpose_matrix_mult(*Q,M,QtM); // compute QQtM QQtM = matrix_new(M->nrows, M->ncols); matrix_matrix_mult(*Q,QtM,QQtM); error_norm = 0.01*get_percent_error_between_two_mats(QQtM, M); printf("Y is of size %d x %d and error_norm = %f\n", (*Y)->nrows, (*Y)->ncols, error_norm); *good_rank = (*Y)->ncols; // add more samples if needed if(error_norm > TOL){ Y_new = matrix_new(m, kblock); initialize_random_matrix(RN); matrix_matrix_mult(M, RN, Y_new); Y_big = matrix_new((*Y)->nrows, (*Y)->ncols + Y_new->ncols); append_matrices_horizontally(*Y, Y_new, Y_big); matrix_delete(*Y); *Y = matrix_new(Y_big->nrows,Y_big->ncols); matrix_copy(*Y,Y_big); matrix_delete(Y_big); matrix_delete(Y_new); matrix_delete(QtM); matrix_delete(QQtM); ind++; } else{ matrix_delete(RN); exit_loop = 1; } } }
void estimate_rank_and_buildQ(mat *M, double frac_of_max_rank, double TOL, mat **Q, int *good_rank){ int m,n,i,j,ind,maxdim; double vec_norm; mat *RN,*Y,*Qbig,*Qsmall; vec *vi,*vj,*p,*p1; m = M->nrows; n = M->ncols; maxdim = round(min(m,n)*frac_of_max_rank); vi = vector_new(m); vj = vector_new(m); p = vector_new(m); p1 = vector_new(m); // build random matrix printf("form RN..\n"); RN = matrix_new(n, maxdim); initialize_random_matrix(RN); // multiply to get matrix of random samples Y printf("form Y: %d x %d..\n",m,maxdim); Y = matrix_new(m, maxdim); matrix_matrix_mult(M, RN, Y); // estimate rank k and build Q from Y printf("form Qbig..\n"); Qbig = matrix_new(m, maxdim); matrix_copy(Qbig, Y); printf("estimate rank with TOL = %f..\n", TOL); *good_rank = maxdim; int forbreak = 0; for(j=0; !forbreak && j<maxdim; j++){ matrix_get_col(Qbig, j, vj); for(i=0; i<j; i++){ matrix_get_col(Qbig, i, vi); project_vector(vj, vi, p); vector_sub(vj, p); if(vector_get2norm(p) < TOL && vector_get2norm(p1) < TOL){ *good_rank = j; forbreak = 1; break; } vector_copy(p1,p); } vec_norm = vector_get2norm(vj); vector_scale(vj, 1.0/vec_norm); matrix_set_col(Qbig, j, vj); } printf("estimated rank = %d\n", *good_rank); Qsmall = matrix_new(m, *good_rank); *Q = matrix_new(m, *good_rank); matrix_copy_first_columns(Qsmall, Qbig); QR_factorization_getQ(Qsmall, *Q); matrix_delete(RN); matrix_delete(Y); matrix_delete(Qsmall); matrix_delete(Qbig); }
void estimate_rank_and_buildQ2(gsl_matrix *M, int kblock, double TOL, gsl_matrix **Y, gsl_matrix **Q, int *good_rank){ int m,n,i,j,ind,exit_loop = 0; double error_norm; gsl_matrix *RN,*Y_new,*Y_big,*QtM,*QQtM; gsl_vector *vi,*vj,*p,*p1; m = M->size1; n = M->size2; // build random matrix printf("form RN..\n"); RN = gsl_matrix_calloc(n,kblock); initialize_random_matrix(RN); // multiply to get matrix of random samples Y printf("form Y: %d x %d..\n",m,kblock); *Y = gsl_matrix_calloc(m, kblock); matrix_matrix_mult(M, RN, *Y); ind = 0; while(!exit_loop){ printf("form Q..\n"); if(ind > 0){ gsl_matrix_free(*Q); } *Q = gsl_matrix_calloc((*Y)->size1, (*Y)->size2); QR_factorization_getQ(*Y, *Q); // compute QtM QtM = gsl_matrix_calloc((*Q)->size2, M->size2); matrix_transpose_matrix_mult(*Q,M,QtM); // compute QQtM QQtM = gsl_matrix_calloc(M->size1, M->size2); matrix_matrix_mult(*Q,QtM,QQtM); error_norm = 0.01*get_percent_error_between_two_mats(QQtM, M); printf("Y is of size %d x %d and error_norm = %f\n", (*Y)->size1, (*Y)->size2, error_norm); *good_rank = (*Y)->size2; // add more samples if needed if(error_norm > TOL){ Y_new = gsl_matrix_calloc(m, kblock); initialize_random_matrix(RN); matrix_matrix_mult(M, RN, Y_new); Y_big = gsl_matrix_calloc((*Y)->size1, (*Y)->size2 + Y_new->size2); append_matrices_horizontally(*Y, Y_new, Y_big); gsl_matrix_free(*Y); *Y = gsl_matrix_calloc(Y_big->size1,Y_big->size2); gsl_matrix_memcpy(*Y,Y_big); gsl_matrix_free(Y_new); gsl_matrix_free(Y_big); gsl_matrix_free(QtM); gsl_matrix_free(QQtM); ind++; } else{ gsl_matrix_free(RN); exit_loop = 1; } } }
void estimate_rank_and_buildQ(gsl_matrix *M, double frac_of_max_rank, double TOL, gsl_matrix **Q, int *good_rank){ int m,n,i,j,ind,maxdim; double vec_norm; gsl_matrix *RN,*Y,*Qbig,*Qsmall; gsl_vector *vi,*vj,*p,*p1; m = M->size1; n = M->size2; maxdim = round(min(m,n)*frac_of_max_rank); vi = gsl_vector_calloc(m); vj = gsl_vector_calloc(m); p = gsl_vector_calloc(m); p1 = gsl_vector_calloc(m); // build random matrix printf("form RN..\n"); RN = gsl_matrix_calloc(n, maxdim); initialize_random_matrix(RN); // multiply to get matrix of random samples Y printf("form Y: %d x %d..\n",m,maxdim); Y = gsl_matrix_calloc(m, maxdim); matrix_matrix_mult(M, RN, Y); // estimate rank k and build Q from Y printf("form Qbig..\n"); Qbig = gsl_matrix_calloc(m, maxdim); gsl_matrix_memcpy(Qbig, Y); printf("estimate rank with TOL = %f..\n", TOL); *good_rank = maxdim; int forbreak = 0; for(j=0; !forbreak && j<maxdim; j++){ gsl_matrix_get_col(vj, Qbig, j); for(i=0; i<j; i++){ gsl_matrix_get_col(vi, Qbig, i); project_vector(vj, vi, p); gsl_vector_sub(vj, p); if(gsl_blas_dnrm2(p) < TOL && gsl_blas_dnrm2(p1) < TOL){ *good_rank = j; forbreak = 1; break; } gsl_vector_memcpy(p1,p); } vec_norm = gsl_blas_dnrm2(vj); gsl_vector_scale(vj, 1.0/vec_norm); gsl_matrix_set_col(Qbig, j, vj); } printf("estimated rank = %d\n", *good_rank); Qsmall = gsl_matrix_calloc(m, *good_rank); *Q = gsl_matrix_calloc(m, *good_rank); matrix_copy_first_columns(Qsmall, Qbig); QR_factorization_getQ(Qsmall, *Q); gsl_matrix_free(RN); gsl_matrix_free(Y); gsl_matrix_free(Qbig); gsl_matrix_free(Qsmall); gsl_vector_free(p); gsl_vector_free(p1); gsl_vector_free(vi); gsl_vector_free(vj); }
Table_quadruplet least_squares_approximation(Table_triplet points, Booleen uniformConf) { int i, j; Table_quadruplet res; res.nb = points.nb; ALLOUER(res.table, points.nb); Table_flottant steps = steps_computation(points, uniformConf); double ** B; ALLOUER(B, points.nb); for(i = 0; i < points.nb; i++) ALLOUER(B[i], points.nb); B[0][0] = B[points.nb - 1][points.nb - 1] = 1; for(i = 1; i < points.nb; i++) B[0][i] = 0; for(i = 0; i < points.nb; i++) { for(j = 1; j < points.nb - 1; j++) { B[j][i] = bernsteinPolynomial(i, points.nb - 1, steps.table[j]); } } for(i = 0; i < points.nb - 1; i++) B[points.nb - 1][i] = 0; double ** BT = transposedMatrix(B, points.nb); Grille_flottant Aprime; Aprime.nb_lignes = Aprime.nb_colonnes = points.nb; Aprime.grille = matrix_matrix_mult(B, BT, points.nb); for(i = 0; i < points.nb; i++) free(BT[i]); free(BT); double * pointsX, * pointsY, * pointsZ; ALLOUER(pointsX, points.nb); ALLOUER(pointsY, points.nb); ALLOUER(pointsZ, points.nb); split_x_y_z(points, pointsX, pointsY, pointsZ); Table_flottant BprimeX, BprimeY, BprimeZ; BprimeX.nb = BprimeY.nb = BprimeZ.nb = points.nb; BprimeX.table = matrix_vector_mult(B, pointsX, points.nb); BprimeY.table = matrix_vector_mult(B, pointsY, points.nb); BprimeZ.table = matrix_vector_mult(B, pointsZ, points.nb); free(pointsX); free(pointsY); free(pointsZ); for(i = 0; i < points.nb; i++) free(B[i]); free(B); Table_flottant resX, resY, resZ; resX.nb = resY.nb = resZ.nb = points.nb; ALLOUER(resX.table, points.nb); ALLOUER(resY.table, points.nb); ALLOUER(resZ.table, points.nb); resolution_systeme_lineaire(&Aprime, &BprimeX, &resX); resolution_systeme_lineaire(&Aprime, &BprimeY, &resY); resolution_systeme_lineaire(&Aprime, &BprimeZ, &resZ); for(i = 0; i < points.nb; i++) { res.table[i].x = resX.table[i]; res.table[i].y = resY.table[i]; res.table[i].z = resZ.table[i]; res.table[i].h = 1; } free(BprimeX.table); free(BprimeY.table); free(BprimeZ.table); free(resX.table); free(resY.table); free(resZ.table); for(i = 0; i < Aprime.nb_lignes; i++) free(Aprime.grille[i]); free(Aprime.grille); return res; }