/* build orthonormal basis matrix Q = Y; for j=1:k vj = Q(:,j); for i=1:(j-1) vi = Q(:,i); vj = vj - project_vec(vj,vi); end vj = vj/norm(vj); Q(:,j) = vj; end */ void build_orthonormal_basis_from_mat(mat *A, mat *Q){ int m,n,i,j,ind,num_ortos=2; double vec_norm; vec *vi,*vj,*p; m = A->nrows; n = A->ncols; vi = vector_new(m); vj = vector_new(m); p = vector_new(m); matrix_copy(Q, A); for(ind=0; ind<num_ortos; ind++){ for(j=0; j<n; j++){ matrix_get_col(Q, j, vj); for(i=0; i<j; i++){ matrix_get_col(Q, i, vi); project_vector(vj, vi, p); vector_sub(vj, p); } vec_norm = vector_get2norm(vj); vector_scale(vj, 1.0/vec_norm); matrix_set_col(Q, j, vj); } } vector_delete(vi); vector_delete(vj); vector_delete(p); }
/* copy the first k columns of M into M_out where k = M_out->ncols (M_out pre-initialized) */ void matrix_copy_first_columns(mat *M_out, mat *M){ int i,k; k = M_out->ncols; vec * col_vec; for(i=0; i<k; i++){ col_vec = vector_new(M->nrows); matrix_get_col(M,i,col_vec); matrix_set_col(M_out,i,col_vec); vector_delete(col_vec); } }
void fill_matrix_from_last_columns(mat *M, int k, mat *M_k){ int i,ind; vec *col_vec; ind = 0; for(i=k; i<M->ncols; i++){ col_vec = vector_new(M->nrows); matrix_get_col(M,i,col_vec); matrix_set_col(M_k,ind,col_vec); vector_delete(col_vec); ind++; } }
void fill_matrix_from_first_columns(mat *M, int k, mat *M_k){ int i; vec *col_vec; //#pragma omp parallel shared(M,M_k,k) private(i,col_vec) { //#pragma omp for for(i=0; i<k; i++){ col_vec = vector_new(M->nrows); matrix_get_col(M,i,col_vec); matrix_set_col(M_k,i,col_vec); vector_delete(col_vec); } } }
/* M(:,inds) = Mc */ void matrix_set_selected_columns(mat *M, int *inds, mat *Mc){ int i; vec *col_vec; #pragma omp parallel shared(M,Mc,inds) private(i,col_vec) { #pragma omp parallel for for(i=0; i<(Mc->ncols); i++){ col_vec = vector_new(M->nrows); matrix_get_col(Mc,i,col_vec); matrix_set_col(M,inds[i],col_vec); vector_delete(col_vec); } } }
/* * Do keyboard routine jobs: scan mantrix, light LEDs, ... * This is repeatedly called as fast as possible. */ void keyboard_task(void) { static matrix_col_t matrix_prev[MATRIX_COLS]; #ifdef MATRIX_HAS_GHOST static matrix_col_t matrix_ghost[MATRIX_COLS]; #endif static uint8_t led_status = 0; matrix_col_t matrix_col = 0; matrix_col_t matrix_change = 0; matrix_scan(); for (uint8_t c = 0; c < MATRIX_COLS; c++) { matrix_col = matrix_get_col(c); matrix_change = matrix_col ^ matrix_prev[c]; if (matrix_change) { #ifdef MATRIX_HAS_GHOST if (has_ghost_in_col(c)) { /* Keep track of whether ghosted status has changed for * debugging. But don't update matrix_prev until un-ghosted, or * the last key would be lost. */ if (debug_matrix && matrix_ghost[c] != matrix_col) { matrix_print(); } matrix_ghost[c] = matrix_col; continue; } matrix_ghost[c] = matrix_col; #endif if (debug_matrix) matrix_print(); for (uint8_t r = 0; r < MATRIX_ROWS; r++) { if (matrix_change & ((matrix_col_t)1<<r)) { keyevent_t e = (keyevent_t){ .key = (keypos_t){ .row = r, .col = c }, .pressed = (matrix_col & ((matrix_col_t)1<<r)), .time = (timer_read() | 1) /* time should not be 0 */ }; action_exec(e); hook_matrix_change(e); // record a processed key matrix_prev[c] ^= ((matrix_col_t)1<<r); // process a key per task call goto MATRIX_LOOP_END; } } } }
double matrix_getmaxcolnorm(mat *M){ int i,m,n; vec *col_vec; double vecnorm, maxnorm; m = M->nrows; n = M->ncols; col_vec = vector_new(m); maxnorm = 0; #pragma omp parallel for for(i=0; i<n; i++){ matrix_get_col(M,i,col_vec); vecnorm = vector_get2norm(col_vec); #pragma omp critical if(vecnorm > maxnorm){ maxnorm = vecnorm; } } vector_delete(col_vec); return maxnorm; }
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); }