Example #1
0
  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;
  }
Example #2
0
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);
}
Example #8
0
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;
}