Пример #1
0
mzd_t *mzd_kernel_left_pluq(mzd_t *A, int const cutoff) {
  mzp_t *P = mzp_init(A->nrows);
  mzp_t *Q = mzp_init(A->ncols);

  rci_t r = mzd_pluq(A, P, Q, cutoff);

  if (r == A->ncols) {
    mzp_free(P);
    mzp_free(Q);
    __M4RI_DD_MZD(A);
    return NULL;
  }

  mzd_t *U = mzd_init_window(A, 0, 0, r, r);
  mzd_t *B = mzd_init_window(A, 0, r, r, A->ncols);

  mzd_trsm_upper_left(U, B, cutoff);

  mzd_t *R = mzd_init(A->ncols, A->ncols - r);
  mzd_t *RU = mzd_init_window(R, 0, 0, r, R->ncols);
  mzd_copy(RU, B);
  for(rci_t i = 0; i < R->ncols; ++i) {
    mzd_write_bit(R, r + i, i, 1);
  }
  mzd_apply_p_left_trans(R, Q);
  mzp_free(P);
  mzp_free(Q);
  mzd_free_window(RU);
  mzd_free_window(U);
  mzd_free_window(B);

  __M4RI_DD_MZD(A);
  __M4RI_DD_MZD(R);
  return R;
}
Пример #2
0
int test_pluq_solve_left(rci_t m, rci_t n, int offsetA, int offsetB) {
    mzd_t* Abase = mzd_init(2048, 2048);
    mzd_t* Bbase = mzd_init(2048, 2048);
    mzd_randomize(Abase);
    mzd_randomize(Bbase);

    mzd_t* A = mzd_init_window(Abase, 0, offsetA, m, m + offsetA);
    mzd_t* B = mzd_init_window(Bbase, 0, offsetB, m, n + offsetB);

    // copy B
    mzd_t* Bcopy = mzd_init(B->nrows, B->ncols);
    for (rci_t i = 0; i < B->nrows; ++i)
        for (rci_t j = 0; j < B->ncols; ++j)
            mzd_write_bit(Bcopy,i,j, mzd_read_bit (B,i,j));

    for (rci_t i = 0; i < m; ++i) {
        mzd_write_bit(A,i,i, 1);
    }

    mzd_t *Acopy = mzd_copy(NULL, A);
    rci_t r = mzd_echelonize(Acopy,1);
    printf("solve_left m: %4d, n: %4d, r: %4d da: %4d db: %4d ", m, n, r, offsetA, offsetB);
    mzd_free(Acopy);
    Acopy = mzd_copy(NULL, A);

    int consistency = mzd_solve_left(A, B, 0, 1);

    //copy B
    mzd_t *X = mzd_init(B->nrows,B->ncols);
    for (rci_t i = 0; i < B->nrows; ++i)
        for (rci_t j = 0; j < B->ncols; ++j)
            mzd_write_bit(X,i,j, mzd_read_bit (B,i,j));

    mzd_t *B1 = mzd_mul(NULL, Acopy, X, 0);
    mzd_t *Z = mzd_add(NULL, Bcopy, B1);

    int status = 0;

    if(consistency == 0) {
        status = 1 - mzd_is_zero(Z);
        if (status == 0) {
            printf("passed\n");
        }  else {
            printf("FAILED\n");
        }
    } else {
        printf("skipped (no solution)\n");
    }
    mzd_free(Bcopy);
    mzd_free(B1);
    mzd_free(Z);

    mzd_free_window(A);
    mzd_free_window(B);
    mzd_free(Acopy);
    mzd_free(Abase);
    mzd_free(Bbase);
    mzd_free(X);
    return status;
}
Пример #3
0
int test_trsm_upper_right (int m, int n, int offset, const char* description){
  printf("upper_right: %s  m: %4d n: %4d offset: %4d ... ",description, m, n, offset);

  mzd_t* Ubase = mzd_init (2048,2048);
  mzd_t* Bbase = mzd_init (2048,2048);
  mzd_randomize (Ubase);
  mzd_randomize (Bbase);
  mzd_t* Bbasecopy = mzd_copy (NULL, Bbase);

  mzd_t* U = mzd_init_window (Ubase, 0, offset, n, offset + n);
  mzd_t* B = mzd_init_window (Bbase, 0, offset, m, offset + n);
  mzd_t* W = mzd_copy (NULL, B);

  size_t i,j;
  for (i=0; i<n; ++i){
    for (j=0; j<i;++j)
      mzd_write_bit(U,i,j, 0);
    mzd_write_bit(U,i,i, 1);
  }
  mzd_trsm_upper_right (U, B, 2048);

  mzd_addmul(W, B, U, 2048);

  int status = 0;
  for ( i=0; i<m; ++i)
    for ( j=0; j<n; ++j){
      if (mzd_read_bit (W,i,j)){
	status = 1;
      }
    }

  // Verifiying that nothing has been changed around the submatrices
  mzd_addmul(W, B, U, 2048);
  mzd_copy (B, W);

  for ( i=0; i<2048; ++i)
    for ( j=0; j<2048/RADIX; ++j){
      if (Bbase->rows[i][j] != Bbasecopy->rows[i][j]){
	status = 1;
      }
    }
  mzd_free_window (U);
  mzd_free_window (B);
  mzd_free (W);
  mzd_free(Ubase);
  mzd_free(Bbase);
  mzd_free(Bbasecopy);

  if (!status)
    printf("passed\n");
  else
    printf("FAILED\n");
  return status;
}
Пример #4
0
int test_trsm_lower_left (int m, int n, int offsetL, int offsetB){
  mzd_t* Lbase = mzd_init (2048,2048);
  mzd_t* Bbase = mzd_init (2048,2048);
  mzd_randomize (Lbase);
  mzd_randomize (Bbase);
  mzd_t* Bbasecopy = mzd_copy (NULL, Bbase);

  mzd_t* L = mzd_init_window (Lbase, 0, offsetL, m, offsetL + m);
  mzd_t* B = mzd_init_window (Bbase, 0, offsetB, m, offsetB + n);
  mzd_t* W = mzd_copy (NULL, B);

  size_t i,j;
  for (i=0; i<m; ++i){
    for (j=i+1; j<m;++j)
      mzd_write_bit(L,i,j, 0);
    mzd_write_bit(L,i,i, 1);
  }
  mzd_trsm_lower_left(L, B, 2048);
  
  mzd_addmul(W, L, B, 2048);

  int status = 0;
  for ( i=0; i<m; ++i)
    for ( j=0; j<n; ++j){
      if (mzd_read_bit (W,i,j)){
	status = 1;
      }
    }

  // Verifiying that nothing has been changed around the submatrices
  mzd_addmul(W, L, B, 2048);

  mzd_copy (B, W);

  for ( i=0; i<2048; ++i)
    for ( j=0; j<2048/RADIX; ++j){
      if (Bbase->rows[i][j] != Bbasecopy->rows[i][j]){
	status = 1;
      }
    }
  mzd_free_window (L);
  mzd_free_window (B);
  mzd_free_window (W);
  mzd_free(Lbase);
  mzd_free(Bbase);
  mzd_free(Bbasecopy);

  if (!status)
    printf(" ... passed\n");
  else
    printf(" ... FAILED\n");
  return status;
}
Пример #5
0
int _mzd_pluq_solve_left(mzd_t const *A, rci_t rank, 
                         mzp_t const *P, mzp_t const *Q, 
                         mzd_t *B, int const cutoff, int const inconsistency_check) {
  /** A is supposed to store L lower triangular and U upper triangular
   *  B is modified in place 
   *  (Bi's in the comments are just modified versions of B)
   *  PLUQ = A
   *  1) P B2 = B1
   *  2) L B3 = B2
   *  3) U B4 = B3
   *  4) Q B5 = B4
   */

  int retval = 0;

  /* P B2 = B1 or B2 = P^T B1 */
  mzd_apply_p_left(B, P);
  
  /* L B3 = B2 */
  
  /* view on the upper part of L */
  mzd_t const *LU = mzd_init_window_const(A, 0, 0, rank, rank);
  mzd_t *Y1 = mzd_init_window(B, 0, 0, rank, B->ncols);
  mzd_trsm_lower_left(LU, Y1, cutoff);

  if (inconsistency_check) { /* Check for inconsistency */    
    /** FASTER without this check; update with the lower part of L
     */
    mzd_t const *H  = mzd_init_window_const(A, rank, 0, A->nrows, rank);
    mzd_t *Y2 = mzd_init_window(B, rank, 0, A->nrows, B->ncols);
    if(A->nrows < B->nrows) {
      mzd_t *Y3 = mzd_init_window(B, A->nrows, 0, B->nrows, B->ncols);
      mzd_set_ui(Y3, 0);
      mzd_free_window(Y3);
    }
    mzd_addmul(Y2, H, Y1, cutoff);
    /*
     * test whether Y2 is the zero matrix
     */
    if(!mzd_is_zero(Y2)) {
      retval = -1;
    }
    mzd_free_window((mzd_t*)H);
    mzd_free_window(Y2);
  }
  /* U B4 = B3 */
  mzd_trsm_upper_left(LU, Y1, cutoff);
  mzd_free_window((mzd_t*)LU);
  mzd_free_window(Y1);
  
  if (!inconsistency_check) {
    /** Default is to set the undefined bits to zero if inconsistency
     * has been checked then Y2 bits are already all zeroes thus this
     * clearing is not needed
     */
    for(rci_t i = rank; i < B->nrows; ++i) {
      for(rci_t j = 0; j < B->ncols; j += m4ri_radix) {
        mzd_clear_bits(B, i, j, MIN(m4ri_radix, B->ncols - j));
      }
    }
  }
  /* Q B5 = B4 or B5 = Q^T B4 */
  mzd_apply_p_left_trans(B, Q);

  /* P L U Q B5 = B1 */
  __M4RI_DD_MZD(B); 
  __M4RI_DD_INT(retval);
  return retval;
}