示例#1
0
void
matrix_ADJUST(Matrix *xx, index_t kk)
{
  //  A function needed to sweep a matrix.  See Goodnight,
  //  33(3) Am. Stat. 149 (1979) for complete explanation.
  //  Function performs ADJUST(kk) on matrix xx.

  index_t ii, jj;
  double aa, aa_kk, aa_ik;
  index_t nrow_xx = numrows(xx);
  index_t ncol_xx = numcols(xx);

  //  Adjust row kk.
  aa_kk = matrix_get_element(xx, kk, kk);
  for (jj=(kk+1); jj<ncol_xx; jj++){
    aa = matrix_get_element(xx, kk, jj);
    matrix_set_element(xx, kk, jj, aa/aa_kk);
  }
  matrix_set_element(xx, kk, kk, 1.0);

  //  Adjust rows != kk.
  for (ii=0; ii<nrow_xx; ii++){
    if (ii == kk) 
	continue;
    aa_ik = matrix_get_element(xx, ii, kk);
    matrix_set_element(xx, ii, kk, 0.0);
    for (jj=(kk+1); jj<ncol_xx; jj++){
      aa = matrix_get_element(xx, ii, jj);
      matrix_set_element(xx, ii, jj, aa-(aa_ik * matrix_get_element(xx, kk, jj)));
    }
  }
}
示例#2
0
void
matrix_subtract(Matrix *xx, Matrix *yy, Matrix *zz)
{
  //  In R notation, implements zz <- xx - yy
  index_t ii, jj, nrow_xx = numrows(xx), ncol_xx = numcols(xx);
  for (ii=0; ii<nrow_xx; ii++)
    for (jj=0; jj<ncol_xx; jj++)
      matrix_set_element(zz, ii, jj, matrix_get_element(xx, ii, jj) - matrix_get_element(yy, ii, jj));
  return;
}
示例#3
0
double matrix_quadform(Matrix *x, Matrix *A, Matrix *y)
{
  // Computes x^{T}Ay
  index_t i,j, nrowy=numrows(y), nrowx=numrows(x);
  double ret=0.0;
  if ((nrowy!=numcols(A)) || (nrowx!=numrows(A)))
    error("Incompatible dims in matrix_quadform()");
  for (i=0; i<nrowx; i++)
    for (j=0; j<nrowy; j++)
      ret += (matrix_get_element(x,i,0)*matrix_get_element(A,i,j)*matrix_get_element(y,j,0));
  return ret;
}
/* append matrices vertically: C = [A; B] */
void append_matrices_vertically(mat *A, mat *B, mat *C){
    int i,j;

    for(i=0; i<A->nrows; i++){
        for(j=0; j<A->ncols; j++){
            matrix_set_element(C,i,j,matrix_get_element(A,i,j));
        }
    }

    for(i=0; i<B->nrows; i++){
        for(j=0; j<B->ncols; j++){
            matrix_set_element(C,A->nrows+i,j,matrix_get_element(B,i,j));
        }
    }
}
/* Performs [Q,R] = qr(M,'0') compact QR factorization 
M is mxn ; Q is mxn ; R is min(m,n) x min(m,n) */ 
void compact_QR_factorization(mat *M, mat *Q, mat *R){
    int i,j,m,n,k;
    m = M->nrows; n = M->ncols;
    k = min(m,n);
    mat *R_full = matrix_new(m,n);
    matrix_copy(R_full,M);
    vec *tau = vector_new(m);

    // get R
    //LAPACKE_dgeqrf(CblasRowMajor, m, n, R_full->d, n, tau->d);
    culaDgeqrf(m, n, R_full->d, m, tau->d);
    
    for(i=0; i<k; i++){
        for(j=0; j<k; j++){
            if(j>=i){
                matrix_set_element(R,i,j,matrix_get_element(R_full,i,j));
            }
        }
    }

    // get Q
    matrix_copy(Q,R_full); 
    //LAPACKE_dorgqr(CblasRowMajor, m, n, n, Q->d, n, tau->d);
    culaDorgqr(m, n, n, Q->d, m, tau->d);

    // clean up
    matrix_delete(R_full);
    vector_delete(tau);
}
/* build transpose of matrix : Mt = M^T */
void matrix_build_transpose(mat *Mt, mat *M){
    int i,j;
    for(i=0; i<(M->nrows); i++){
        for(j=0; j<(M->ncols); j++){
            matrix_set_element(Mt,j,i,matrix_get_element(M,i,j)); 
        }
    }
}
/* copy contents of mat S to D */
void matrix_copy_first_columns_with_param(mat *D, mat *S, int num_columns){
    int i,j;
    for(i=0; i<(S->nrows); i++){
        for(j=0; j<num_columns; j++){
            matrix_set_element(D,i,j,matrix_get_element(S,i,j));
        }
    }
}
/* A = A - u*v where u is a column vec and v is a row vec */
void matrix_sub_column_times_row_vector(mat *A, vec *u, vec *v){
    int i,j;
    #pragma omp parallel for shared(A,u,v) private(j)
    for(i=0; i<(A->nrows); i++){
        for(j=0; j<(A->ncols); j++){
            matrix_set_element(A,i,j,matrix_get_element(A,i,j) - vector_get_element(u,i)*vector_get_element(v,j));
        }
    }
}
/* M_out = M(:,k+1:end) */
void matrix_copy_all_rows_and_last_columns_from_indexk(mat *M_out, mat *M, int k){
    int i,j,i_out,j_out;
    for(i=0; i<(M->nrows); i++){
        for(j=k; j<(M->ncols); j++){
            i_out = i; j_out = j - k;
            matrix_set_element(M_out,i_out,j_out,matrix_get_element(M,i,j));
        }
    }
}
/* copy the first k rows and columns of M into M_out is kxk where k = M_out->ncols (M_out pre-initialized) 
M_out = M(1:k,1:k) */
void matrix_copy_first_k_rows_and_columns(mat *M_out, mat *M){
    int i,j,k;
    k = M_out->ncols;
    for(i=0; i<k; i++){
        for(j=0; j<k; j++){
            matrix_set_element(M_out,i,j,matrix_get_element(M,i,j));
        }
    }
} 
示例#11
0
void
matrix_transpose_same(Matrix *xx)
{
  //  In R notation, xx<-t(xx), but ONLY FOR SQUARE xx.
  //  Second function written for speed.

  double aa;
  index_t ii, jj, nrow_xx = numrows(xx), ncol_xx = numcols(xx);

  for (ii=0; ii<nrow_xx; ii++){
    for (jj=(ii+1); jj<ncol_xx; jj++){
      aa = matrix_get_element(xx, ii, jj);
      matrix_set_element(xx, ii, jj, matrix_get_element(xx, jj, ii));
      matrix_set_element(xx, jj, ii, aa);
    }
  }
  return;
}
/* invert diagonal matrix */
void invert_diagonal_matrix(mat *Dinv, mat *D){
    int i;
    #pragma omp parallel shared(D,Dinv) private(i)
    {
    #pragma omp parallel for
    for(i=0; i<(D->nrows); i++){
        matrix_set_element(Dinv,i,i,1.0/(matrix_get_element(D,i,i)));
    }
    }
}
/* extract column of a matrix into a vector */
void matrix_get_col(mat *M, int j, vec *column_vec){
    int i;
    #pragma omp parallel shared(column_vec,M,j) private(i) 
    {
    #pragma omp parallel for
    for(i=0; i<M->nrows; i++){ 
        vector_set_element(column_vec,i,matrix_get_element(M,i,j));
    }
    }
}
/* extract row i of a matrix into a vector */
void matrix_get_row(mat *M, int i, vec *row_vec){
    int j;
    #pragma omp parallel shared(row_vec,M,i) private(j) 
    {
    #pragma omp parallel for
    for(j=0; j<M->ncols; j++){ 
        vector_set_element(row_vec,j,matrix_get_element(M,i,j));
    }
    }
}
示例#15
0
void
matrix_cholesky(Matrix  *xx, Matrix *yy)
{
  //  Sets yy equal to the cholesky decomp of xx.  Note per the definition,
  //  the cholesky decomp is an upper triangular matrix.

  index_t kk, jj;
  double aa;

  matrix_get_set_block(yy, 0, numrows(yy)-1, 0, numcols(yy)-1, xx, 0, numrows(xx)-1, 0, numcols(xx)-1);
  for (kk=0; kk<(numrows(yy)-1); kk++){
    matrix_DOOLITTLE(yy, kk);
    aa = matrix_get_element(yy, kk, kk);
    for (jj=kk; jj<numcols(yy); jj++){
      matrix_set_element(yy, kk, jj, matrix_get_element(yy, kk, jj)/sqrt(aa));
    }
  }
  matrix_set_element(yy, numcols(yy)-1, numcols(yy)-1,
		     sqrt(matrix_get_element(yy, numcols(yy)-1, numcols(yy)-1)));
}
/* Mout = M((k+1):end,(k+1):end) in matlab notation */
void fill_matrix_from_lower_right_corner(mat *M, int k, mat *M_out){
    int i,j,i_out,j_out;
    for(i=k; i<M->nrows; i++){
        for(j=k; j<M->ncols; j++){
            i_out = i-k;
            j_out = j-k;
            //printf("setting element %d, %d of M_out\n", i_out, j_out);
            matrix_set_element(M_out,i_out,j_out,matrix_get_element(M,i,j));
        }
    }
}
void matrix_print(mat * M){
    int i,j;
    double val;
    for(i=0; i<M->nrows; i++){
        for(j=0; j<M->ncols; j++){
            val = matrix_get_element(M, i, j);
            printf("%f  ", val);
        }
        printf("\n");
    }
}
double get_matrix_column_norm_squared(mat *M, int colnum){
    int i, m, n;
    double val,colnorm;
    m = M->nrows;
    n = M->ncols;
    colnorm = 0;
    for(i=0; i<m; i++){
        val = matrix_get_element(M,i,colnum);
        colnorm += val*val;
    }
    return colnorm;
}
/* copy only upper triangular matrix part as for symmetric matrix */
void matrix_copy_symmetric(mat *S, mat *M){
    int i,j,n,m;
    m = M->nrows;
    n = M->ncols;
    for(i=0; i<m; i++){
        for(j=0; j<n; j++){
            if(j>=i){
                matrix_set_element(S,i,j,matrix_get_element(M,i,j));
            }
        }
    }
}
示例#20
0
void
matrix_DOOLITTLE(Matrix *xx, index_t kk)
{
  //  A function needed to find the determinant and to
  //  find the cholesky decomposition of a matrix.  See Goodnight,
  //  33(3) Am. Stat. 149 (1979) for complete explanation.
  //  Function performs DOOLITTLE(kk) on matrix xx.
  //  Function will only work on a square matrix.

  double aa_ij, aa_ik, aa_kk, aa_kj;
  index_t ii, jj, nrow_xx = numrows(xx), ncol_xx = numcols(xx);

  //  Adjust rows below kk
  aa_kk = matrix_get_element(xx, kk, kk);
  for (ii=(kk+1); ii<nrow_xx; ii++){
    aa_ik = matrix_get_element(xx, ii, kk);
    for(jj=(kk+1); jj<ncol_xx; jj++){
      aa_ij = matrix_get_element(xx, ii, jj);
      aa_kj = matrix_get_element(xx, kk, jj);
      matrix_set_element(xx, ii, jj, aa_ij - ((aa_ik/aa_kk)*aa_kj));
    }
    matrix_set_element(xx, ii, kk, 0.0);
  }
}
/* write matrix to binary file 
 * the nonzeros are in order of double loop over rows and columns
format:
num_rows (int) 
num_columns (int)
nnz (double)
...
nnz (double)
*/
void matrix_write_to_binary_file(mat *M, char *fname){
    int i, j, num_rows, num_columns, row_num, col_num;
    double nnz_val;
    size_t one = 1;
    FILE *fp;
    num_rows = M->nrows; num_columns = M->ncols;
    
    fp = fopen(fname,"w");
    fwrite(&num_rows,sizeof(int),one,fp); //write m
    fwrite(&num_columns,sizeof(int),one,fp); //write n

    // write the elements
    for(i=0; i<num_rows; i++){
        for(j=0; j<num_columns; j++){
            nnz_val = matrix_get_element(M,i,j);
            fwrite(&nnz_val,sizeof(double),one,fp); //write nnz
        }
    }
    fclose(fp);
}
示例#22
0
/*
void
matrix_get_row(Matrix *m, index_t i, Matrix *v)
{
  // Extracts the ith row of m to the column vector v
  index_t j;
  const index_t nc=numcols(m);
#ifdef _DBG_
 len=numrows(v), 
  if (len!=nc)
    error("Incompatible dimensions in matrix_get_row()");
#endif
  for (j=0; j<nc; j++)
    matrix_set_element(v,j,0, matrix_get_element(m,i,j));
  return;
}
*/
int
matrix_is_symmetric(Matrix *xx)
{
  //  Checks a matrix for symmetry, aindex_t with other basic checks.
  //  Returns 1 if the matrix is
  //  symmetric, 0 if not symmetric (if something else is wrong).

  int retval = 1;
  index_t ii, jj, nrow_xx = numrows(xx), ncol_xx = numcols(xx);

  Matrix *yy = matrix_new(nrow_xx, ncol_xx);

  matrix_transpose(xx, yy);
  matrix_scalar_multiply(yy, -1.0, yy);
  matrix_add(xx, yy, yy);
  for (ii=0; ii<nrow_xx; ii++)
    for (jj=0; jj<ncol_xx; jj++)
      if (matrix_get_element(yy, ii, jj) > DBL_EPSILON) 
	retval = 0;

  matrix_free(yy);
  return retval;
}
示例#23
0
void
matrix_print_element(Matrix const * const xx, index_t row, index_t col)
{
  Rprintf("%g\t", matrix_get_element(xx, row, col));
  return;
}