コード例 #1
0
ファイル: hb2mtxstrm.c プロジェクト: nschloe/hbio
FILE * readHB_newind(
    const char* filename,
    int* M,
    int* N, int* nonzeros, int** colptr, int** rowind
    )
{
  FILE *in_file;
  int Nrhs;
  int Ptrcrd, Indcrd, Valcrd;
  int Rhscrd = 0;
  char Title[73], Key[9], Type[4], Rhstype[4];
  char Ptrfmt[17], Indfmt[17], Rhsfmt[21],Valfmt[21];

  if ((in_file = fopen( filename, "r")) == NULL) {
    fprintf(stderr,"Error: Cannot open file: %s\n",filename);
    return 0;
  }

  readHB_header(
      in_file, Title, Key, Type, M, N, nonzeros, &Nrhs,
      Ptrfmt, Indfmt, Valfmt, Rhsfmt,
      &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype
      );
  fclose(in_file);

  *colptr = (int *)malloc((*N+1)*sizeof(int));
  if ( *colptr == NULL )
    IOHBTerminate("Insufficient memory for colptr.\nhb2mtxstrm.c: Line 279 approx.");
  *rowind = (int *)malloc(*nonzeros*sizeof(int));
  if ( *rowind == NULL )
    IOHBTerminate("Insufficient memory for rowind.\nhb2mtxstrm.c: Line 281 approx.");
  return readHB_ind(filename, *colptr, *rowind);
}
コード例 #2
0
void Trilinos_Util_read_hb(char *data_file, int MyPID,
	      int *N_global, int *n_nonzeros, 
	      double **val, int **bindx,
	      double **x, double **b, double **xexact)
#undef DEBUG 
     /*  read ASCII data file:
	 line 1: N_global, number of entries (%d,%d)
	 line 2-...: i,j,real (%d, %d, %f)
     */

{
  FILE *in_file ;
  char Title[73], Key[9], Rhstype[4];
  char Type[4] = "XXX";
  char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
  int Ptrcrd, Indcrd, Valcrd, Rhscrd;

  int i, n_entries=0, N_columns=0, Nrhs=0;
  int isym;
  double res;
  int *pntr, *indx1, *pntr1;
  double *val1;

  int MAXBLOCKSIZE = 1;
  
  if(MyPID == 0)  { 
      
      /* Get information about the array stored in the file specified in the  */
      /* argument list:                                                       */

      printf("Reading matrix info from %s...\n",data_file);
      
      in_file = fopen( data_file, "r");
      if (in_file == NULL)
	{
	  printf("Error: Cannot open file: %s\n",data_file);
	  exit(1);
	}

      readHB_header(in_file, Title, Key, Type, N_global, &N_columns, 
		    &n_entries, &Nrhs,
		    Ptrfmt, Indfmt, Valfmt, Rhsfmt,
		    &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
      fclose(in_file);

      if (Nrhs < 0 ) Nrhs = 0;

      printf("%s", "***************************************************************\n");
      printf("Matrix in file %s is %d x %d, \n",data_file, *N_global, N_columns);
      printf("with %d nonzeros with type %3s;\n", n_entries, Type);
      printf("%s", "***************************************************************\n");
      printf("Title: %72s\n",Title);
      printf("%s", "***************************************************************\n");
      /*Nrhs = 0; */
      printf("%d right-hand-side(s) available.\n",Nrhs);

      if (Type[0] != 'R') perror("Can only handle real valued matrices");
      isym = 0;
      if (Type[1] == 'S') 
	{
	  printf("%s", "Converting symmetric matrix to nonsymmetric storage\n");
	  n_entries = 2*n_entries - N_columns;
	  isym = 1;
	}
      if (Type[2] != 'A') perror("Can only handle assembled matrices");
      if (N_columns != *N_global) perror("Matrix dimensions must be the same");
      *n_nonzeros = n_entries;
      
      /* Read the matrix information, generating the associated storage arrays  */
      printf("Reading the matrix from %s...\n",data_file);

      /* Allocate space.  Note that we add extra storage in case of zero
	 diagonals.  This is necessary for conversion to MSR format. */

      pntr   = (int    *) calloc(N_columns+1,sizeof(int)) ;
      *bindx = (int    *) calloc(n_entries+N_columns+1,sizeof(int)) ;
      *val   = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ;
      
      readHB_mat_double(data_file, pntr, *bindx, *val);

      for (i = 0; i <= *N_global; i++) pntr[i]--;
      for (i = 0; i <= n_entries; i++) (*bindx)[i]--;

      /* If a rhs is specified in the file, read one, 
	 generating the associate storage */
      if (Nrhs > 0 && Rhstype[2] =='X')
	{
	  printf("Reading right-hand-side vector(s) from %s...\n",data_file);
	  *b = (double *) calloc(N_columns,sizeof(double));
	  readHB_aux_double(data_file, 'F', (*b));
	  printf("Reading exact solution  vector(s) from %s...\n",data_file);
	  *xexact = (double *) calloc(N_columns,sizeof(double));
	      readHB_aux_double(data_file, 'X', (*xexact));

	}
      else
	{
	  
	  /* Set Xexact to a random vector */

	  printf("%s", "Setting  random exact solution  vector\n");
	  *xexact = (double *) calloc(N_columns,sizeof(double));
	  
	  for (i=0;i<*N_global;i++)	 (*xexact)[i] =
                                       ((double)rand())/((double) RAND_MAX);
	  
	  /* Compute b to match xexact */
	  
	  *b = (double   *) calloc(N_columns*MAXBLOCKSIZE,sizeof(double)) ;
	  if ((*b) == NULL) perror("Error: Not enough space to create rhs");
 

      Trilinos_Util_scscmv (isym, N_columns, N_columns, (*val), (*bindx), pntr, (*xexact), (*b));
	}

      /* Compute residual using CSC format */

      res = Trilinos_Util_scscres(isym, *N_global, *N_global, (*val), (*bindx), pntr, 
		    (*xexact), (*b));
      printf(
	      "The residual using CSC format and exact solution is %12.4g\n",
	      res);

      
      /* Set initial guess to zero */
      
      *x = (double   *) calloc((*N_global)*MAXBLOCKSIZE,sizeof(double)) ;
      
      if ((*x) == NULL) 
	perror("Error: Not enough space to create guess");
      
      
      /* Set RHS to a random vector, initial guess to zero */
      for (i=0;i<*N_global;i++) (*x)[i] = 0.0;
      
      
      /* Allocate temporary space */
      
      pntr1 = (int   *) calloc(N_columns+1,sizeof(int)) ;
      indx1 = (int   *) calloc(n_entries+N_columns+1,sizeof(int)) ;
      val1 = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ;
      
      
      /* Convert in the following way:
	 - CSC to CSR 
	 - CSR to MSR
      */
      Trilinos_Util_csrcsc(*N_global, *N_global, 0, 0, *val, *bindx, pntr, val1, indx1, pntr1);
      
      if (Type[1] == 'S') 
	{
	  int *indu, *iwk;
	  int ierr;
	  indu = new int[N_columns];
	  iwk = new int[N_columns+1];
	  ierr = Trilinos_Util_ssrcsr(3, 1, N_columns, val1, indx1, pntr1, n_entries,
	  		  val1, indx1, pntr1, indu, iwk);
	  delete [] indu;
	  delete [] iwk;
	  if (ierr !=0 ) 
	    {
	    printf(" Error in converting from symmetric form\n  IERR = %d\n",ierr);
	    abort();
	    }
	}

      Trilinos_Util_csrmsr(*N_global, val1, indx1, pntr1, *val, *bindx, *val, *bindx);
      
      /* Recompute number of nonzeros in case there were zero diagonals */
      
      *n_nonzeros = (*bindx)[*N_global] - 1; /* Still in Fortran mode so -2 */
            

      printf("The residual using MSR format and exact solution is %12.4g\n",
	      Trilinos_Util_smsrres (*N_global, *N_global, (*val), (*bindx), 
		       (*xexact), (*xexact), (*b)));

      /* Release unneeded space */

      free((void *) val1);
      free((void *) indx1);
      free((void *) pntr1);
      free((void *) pntr);
    }
  
  /* end read_hb */
}
コード例 #3
0
ファイル: dmio.c プロジェクト: dawuweijun/otpo
int
dspio_readHB_mat_double( const char* filename,
                         int row_i, int row_f,
                         int** p_rowptr,
                         int* p_nnz,
                         int** p_colind,
                         double** p_val )
{
/****************************************************************************/
/*  This function opens and reads the specified file, interpreting its      */
/*  contents as a sparse matrix stored in the Harwell/Boeing standard       */
/*  format and creating compressed column storage scheme vectors to hold    */
/*  the index and nonzero value information.                                */
/*                                                                          */
/*    ----------                                                            */
/*    **CAVEAT**                                                            */
/*    ----------                                                            */
/*  Parsing real formats from Fortran is tricky, and this file reader       */
/*  does not claim to be foolproof.   It has been tested for cases when     */
/*  the real values are printed consistently and evenly spaced on each      */
/*  line, with Fixed (F), and Exponential (E or D) formats.                 */
/*                                                                          */
/*  **  If the input file does not adhere to the H/B format, the  **        */
/*  **             results will be unpredictable.                 **        */
/*                                                                          */
/****************************************************************************/
  FILE *in_file;
  int i,j,ind,col,offset,count,last,Nrhs;
  int Ptrcrd, Indcrd, Valcrd, Rhscrd;
  int Nrow, Ncol, Nnzero;
  int Ptrperline, Ptrwidth, Indperline, Indwidth;
  int Valperline, Valwidth, Valprec;
  int Valflag;           /* Indicates 'E','D', or 'F' float format */
  char* ThisElement;
  char Title[73], Key[9], Type[4], Rhstype[4];
  char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
  char line[BUFSIZ];

  int* rowptr;
  int* colind;
  int  len_colind;
  double* val;
  int  nr = row_f - row_i + 1;
  int  temp_elem;
  int  rownum;
  int  running_offset;
  int  new_insert_pos;

  list_t* symm_entries;    /* store list of symmetric entries to add */
  int* all_rowptr;
  int len_extra_symm;   /* # of extra entries due to symmetry */
  fpos_t save_pos;

  dlist_t* symm_vals;
  fpos_t val_save_pos;
  FILE*  val_in_file;
  char val_line[BUFSIZ];
  int val_col;
  int val_ind;
  int val_i;
  int val_skip_lines;
  char* val_ThisElement;
  double val_temp_elem;

  in_file = fopen( filename, "r");
  assert( in_file != NULL );

  readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
                Ptrfmt, Indfmt, Valfmt, Rhsfmt,
                &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);

  assert( Nrow == Ncol );
  assert( Type[0] == 'R' || Type[0] == 'r' );
  assert( Type[1] == 'S' || Type[1] == 's' );
  assert( Type[2] == 'A' || Type[2] == 'a' );

  /*  Parse the array input formats from Line 3 of HB file  */
  ParseIfmt(Ptrfmt,&Ptrperline,&Ptrwidth);
  ParseIfmt(Indfmt,&Indperline,&Indwidth);
  ParseRfmt(Valfmt,&Valperline,&Valwidth,&Valprec,&Valflag);

  /*  Read row pointer array:   */
  offset = 1;

  rowptr = (int *)malloc( sizeof(int)*(nr + 1) );
  *p_rowptr = rowptr;
  if( rowptr == NULL )
    IOHBTerminate( "Out of memory allocating row pointer" );

  all_rowptr = (int *)malloc( sizeof(int)*(row_f+2) );
  if( all_rowptr == NULL )
    IOHBTerminate( "Out of memory allocating all row pointer" );

  symm_entries = (list_t *)malloc( sizeof(list_t)*(row_f+1) );
  symm_vals = (dlist_t *)malloc( sizeof(dlist_t)*(row_f+1) );
  if( symm_entries == NULL || symm_vals == NULL )
    IOHBTerminate( "Out of memory allocating symmetric entries" );
  for( i = 0; i < (row_f+1); i++ ) {
    lst_init( &(symm_entries[i]) );
    dlst_init( &(symm_vals[i]) );
  }

  ThisElement = (char *) malloc(Ptrwidth+1);
  if ( ThisElement == NULL )
    IOHBTerminate("Insufficient memory for ThisElement (1).");
  *(ThisElement+Ptrwidth) = (char) NULL;
  count = 0;
  for( i = 0; i < Ptrcrd; i++ ) {
    fgets( line, BUFSIZ, in_file );
    if ( sscanf(line, "%*s") < 0 ) 
      IOHBTerminate("--- Null (or blank) line in ptr data region ---\n");
    col = 0;
    for( ind = 0; ind < Ptrperline; ind++ ) {

      if( count > Ncol || count > row_f+1 )
        break;

      /* copy and convert index */
      strncpy( ThisElement, line+col, Ptrwidth );
      temp_elem = atoi(ThisElement) - offset;

      if( count >= row_i ) {
        /* only save elements in the proper range for this processor */
        rowptr[ count - row_i ] = temp_elem;
      }

      all_rowptr[ count ] = temp_elem;

      count++;
      col += Ptrwidth;
    }
  }
  free(ThisElement);

#ifndef NDEBUG_IO
fprintf( stderr, "printing rowptr...\n" );
for( i = 0; i <= nr; i++ )
  fprintf( stderr, "rowptr[%d]==%d\n", i, rowptr[i] );
fprintf( stderr, "printing all_rowptr...\n" );
for( i = 0; i <= row_f+1; i++ )
  fprintf( stderr, "all_rowptr[%d]==%d\n", i, all_rowptr[i] );
#endif


  /* alloc space for column indices and values */

  ThisElement = (char *) malloc(Indwidth+1);
  if ( ThisElement == NULL )
    IOHBTerminate("Insufficient memory for ThisElement (2).");
  *(ThisElement+Indwidth) = (char) NULL;
  val_ThisElement = (char *) malloc(Valwidth+2);
  if ( val_ThisElement == NULL )
    IOHBTerminate("Insufficient memory for val_ThisElement (2).");
  *(val_ThisElement+Valwidth) = (char) NULL;
  *(val_ThisElement+Valwidth+1) = (char) NULL;

  len_extra_symm = 0;
  fgetpos( in_file, &save_pos );
  rownum = 0;

  /* position at analogous place in file for values */
  val_in_file = fopen( filename, "r" );
  assert( val_in_file != NULL );
  val_skip_lines = 4 + (Rhscrd > 0) + Ptrcrd + Indcrd;

#ifndef NDEBUG_IO
fprintf( stderr, "header lines: %d (%d), ptr lines: %d, ind lines: %d\n",
         4 + (Rhscrd>0), Rhscrd, Ptrcrd, Indcrd );
fprintf( stderr, "skipping %d lines to get to vals...\n", val_skip_lines );
#endif

  for( i = 0; i < val_skip_lines; i++ ) {
    fgets( line, BUFSIZ, val_in_file );
  }
  fgetpos( val_in_file, &val_save_pos );

  count = 0;
  /*  for( i = 0; i < Indcrd; i++ ) {*/
  i = 0;       /* line number */
  col = 0;     /* column number on a given line */
  ind = 0;     /* item number on a given line */
  val_col = 0; /* analogous */
  val_ind = 0;
  val_i = 0;
  while( i <= Indcrd ) {

    /* read new lines, if necessary */
    if( (ind % Indperline) == 0 ) {
      fgets( line, BUFSIZ, in_file );
      if ( sscanf(line,"%*s") < 0 )
        IOHBTerminate("--- Null (or blank) line in index data region ---\n");
      i++;

      col = 0;
    }

    if( (val_ind % Valperline) == 0 ) {
      fgets( val_line, BUFSIZ, val_in_file );
      if( sscanf(val_line, "%*s") < 0 )
        IOHBTerminate("--- Null (or blank) line in value region ---\n");
      val_i++;

      val_col = 0;

      if( Valflag == 'D' ) {
        while( strchr(val_line, 'D') ) *strchr(val_line,'D') = 'E';
      }
    }

    if (count == Nnzero) break;

    /* read an entry from this line */
    strncpy( ThisElement, line+col, Indwidth );
    col += Indwidth;
    ind++;

    strncpy( val_ThisElement, val_line + val_col, Valwidth );
    *(val_ThisElement+Valwidth) = (char) NULL;
    val_col += Valwidth;
    val_ind++;
    if ( Valflag != 'F' && strchr(val_ThisElement,'E') == NULL ) {
      /* insert a char prefix for exp */
      last = strlen(val_ThisElement);
      for (j=last+1;j>=0;j--) {
        val_ThisElement[j] = val_ThisElement[j-1];
        if ( val_ThisElement[j] == '+' || val_ThisElement[j] == '-' ) {
          val_ThisElement[j-1] = Valflag;
          break;
        }
      }
    }

    /* done */
    if( count >= rowptr[nr] )
      break;

    temp_elem = atoi( ThisElement ) - offset;
    val_temp_elem = atof( val_ThisElement );

#ifndef NDEBUG_IO
    fprintf( stderr, "found: %d (%f)\n", temp_elem, val_temp_elem );
#endif

    if( temp_elem >= row_i && temp_elem <= row_f ) {
      if( temp_elem != rownum ) { /* ignore diagonal entry */

#ifndef NDEBUG_IO
        fprintf( stderr, "new entry: (%d, %d) == %f\n",
                 temp_elem, rownum, val_temp_elem );
#endif

        len_extra_symm++;
        lst_insert( &(symm_entries[temp_elem]), rownum );
        dlst_insert( &(symm_vals[temp_elem]), val_temp_elem );
      }
    }

    count++;
    if( count >= all_rowptr[rownum+1] )
      rownum++;
  }


#ifndef NDEBUG_IO
fprintf( stderr, "extra entries due to symmetry: %d\n", len_extra_symm );
#endif

  len_colind = rowptr[nr] - rowptr[0] + len_extra_symm;
  *p_nnz = len_colind;
  colind = (int *)malloc( sizeof(int)*len_colind );
  *p_colind = colind;

#ifndef NDEBUG_IO
fprintf( stderr, "nnz == %d\n", len_colind );
#endif

  val = (double *)malloc( sizeof(double)*len_colind );
  *p_val = val;

  assert( colind != NULL && val != NULL );

  /*  Read column index array:  */
  fsetpos( in_file, &save_pos );
  i = 0;
  col = 0;
  ind = 0;

  fsetpos( val_in_file, &val_save_pos );
  val_i = 0;
  val_col = 0;
  val_ind = 0;

  count = 0;
  rownum = 0;
  running_offset = 0;

  while( i <= Indcrd ) {

    /* read new lines, if necessary */
    if( (ind % Indperline) == 0 ) {
      fgets( line, BUFSIZ, in_file );
      if ( sscanf(line,"%*s") < 0 )
        IOHBTerminate("--- Null (or blank) line in index data region ---\n");
      i++;

      col = 0;
    }

    if( (val_ind % Valperline) == 0 ) {
      fgets( val_line, BUFSIZ, val_in_file );
      if( sscanf(val_line, "%*s") < 0 )
        IOHBTerminate("--- Null (or blank) line in value region ---\n");
      val_i++;

      val_col = 0;

      if( Valflag == 'D' ) {
        while( strchr(val_line, 'D') ) *strchr(val_line,'D') = 'E';
      }
    }


    if (count == Nnzero) break;


    /* read an entry from this line */
    strncpy( ThisElement, line+col, Indwidth );
    col += Indwidth;
    ind++;

    strncpy( val_ThisElement, val_line + val_col, Valwidth );
    *(val_ThisElement+Valwidth) = (char) NULL;
    val_col += Valwidth;
    val_ind++;
    if ( Valflag != 'F' && strchr(val_ThisElement,'E') == NULL ) {
      /* insert a char prefix for exp */
      last = strlen(val_ThisElement);
      for (j=last+1;j>=0;j--) {
        val_ThisElement[j] = val_ThisElement[j-1];
        if ( val_ThisElement[j] == '+' || val_ThisElement[j] == '-' ) {
          val_ThisElement[j-1] = Valflag;
          break;
        }
      }
    }

    /* done */
    if( count >= all_rowptr[nr + row_i] )
      break;

    temp_elem = atoi( ThisElement ) - offset;
    val_temp_elem = atof( val_ThisElement );

#ifndef NDEBUG_IO
    fprintf( stderr, "entry: (%d, %d) == %f\n", rownum, temp_elem, val_temp_elem );
#endif

    if( count >= all_rowptr[ row_i ] ) {
      new_insert_pos = count - all_rowptr[row_i] + running_offset;

#ifndef NDEBUG_IO
      fprintf( stderr, "inserting into colind[%d]: %d\n",
               new_insert_pos, temp_elem );
#endif
      colind[ new_insert_pos ] = temp_elem;
      val[ new_insert_pos ] = val_temp_elem;
    }

    count++;
    if( count >= all_rowptr[rownum+1] ) {
      rownum++;

      if( rownum >= row_i && rownum <= row_f+1 ) {
#ifndef NDEBUG_IO
        fprintf( stderr, "rowptr[%d] (== %d) += %d\n", rownum - row_i, rowptr[ rownum - row_i ], running_offset );
#endif
        rowptr[ rownum - row_i ] += running_offset;
      }

      if( rownum >= row_i && rownum <= row_f ) {
        /* insert symmetric entries, if any */
        int new_additions = 0;
        list_node_t* trace = symm_entries[rownum].head;
        dlist_node_t* dtrace = symm_vals[rownum].head;

#ifndef NDEBUG_IO
        fprintf( stderr, "symm_entry[%d].length == %d\n", rownum, symm_entries[rownum].length );
#endif

        new_insert_pos = count - all_rowptr[row_i] + running_offset;
        while( trace != NULL ) {
          assert( dtrace != NULL );

#ifndef NDEBUG_IO
          fprintf( stderr, "inserting symmetric entry: colind[%d] = %d\n",
                   new_insert_pos + new_additions, trace->value );
          fprintf( stderr, "inserting symmetric value: val[%d] = %f\n",
                   new_insert_pos + new_additions, dtrace->value );
#endif
          colind[ new_insert_pos + new_additions ] = trace->value;
          val[ new_insert_pos + new_additions ] = dtrace->value;
          trace = trace->next;
          dtrace = dtrace->next;
          new_additions++;
        } /* while */
        assert( new_additions == symm_entries[rownum].length );
        assert( new_additions == symm_vals[rownum].length );
        running_offset += new_additions;
      } /* rownum >= row_i ... */
    } /* count >= ... */
  }

  free(ThisElement);
  free(val_ThisElement);


  for( i = 0; i < row_f+1; i++ ) {
    lst_destroy( &(symm_entries[i]) );
  }
  for( i = 0; i < row_f+1; i++ ) {
    dlst_destroy( &(symm_vals[i]) );
  }
  free( symm_entries );
  free( symm_vals );
  free( all_rowptr );

  fclose( in_file );
  fclose( val_in_file );
  return 1;
}
コード例 #4
0
void Trilinos_Util_ReadHb2Epetra(char *data_file,
				 const Epetra_Comm  &comm, 
				 Epetra_Map *& map, 
				 Epetra_CrsMatrix *& A, 
				 Epetra_Vector *& x, 
				 Epetra_Vector *& b,
				 Epetra_Vector *&xexact) {
  FILE *in_file ;
  int numGlobalEquations=0, N_columns=0, n_entries=0, Nrhs=0;
  char Title[73], Key[9], Rhstype[4];
  char Type[4] = "XXX";
  char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
  int Ptrcrd, Indcrd, Valcrd, Rhscrd;
  
  for(int ii=0; ii<73; ++ii) Title[ii] = '\0';

  int * bindx, * pntr, * indx1, * pntr1;
  double * val, * val1, * hbx, * hbxexact, * hbb;

  hbx = 0; hbb = 0; hbxexact = 0; hbb = 0;

  if(comm.MyPID() == 0)  { 
      in_file = fopen( data_file, "r");
      if (in_file == NULL)
	{
	  printf("Error: Cannot open file: %s\n",data_file);
	  exit(1);
	}

      /* Get information about the array stored in the file specified in the  */
      /* argument list:                                                       */

      printf("Reading matrix info from %s...\n",data_file);
      
      in_file = fopen( data_file, "r");
      if (in_file == NULL)
	{
	  printf("Error: Cannot open file: %s\n",data_file);
	  exit(1);
	}
      
      readHB_header(in_file, Title, Key, Type, &numGlobalEquations, &N_columns, 
		    &n_entries, &Nrhs,
		    Ptrfmt, Indfmt, Valfmt, Rhsfmt,
		    &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
      fclose(in_file);

      if (Nrhs < 0 ) Nrhs = 0;

      printf("%s", "***************************************************************\n");
      printf("Matrix in file %s is %d x %d, \n",data_file, numGlobalEquations, N_columns);
      printf("with %d nonzeros with type %3s;\n", n_entries, Type);
      printf("%s", "***************************************************************\n");
      printf("Title: %72s\n",Title);
      printf("%s", "***************************************************************\n");
      /*Nrhs = 0; */
      printf("%d right-hand-side(s) available.\n",Nrhs);

      if (Type[0] != 'R') perror("Can only handle real valued matrices");
      int isym = 0;
      if (Type[1] == 'S') 
	{
	  printf("%s", "Converting symmetric matrix to nonsymmetric storage\n");
	  n_entries = 2*n_entries - N_columns;
	  isym = 1;
	}
      if (Type[2] != 'A') perror("Can only handle assembled matrices");
      if (N_columns != numGlobalEquations) perror("Matrix dimensions must be the same");
      
      /* Read the matrix information, generating the associated storage arrays  */
      printf("Reading the matrix from %s...\n",data_file);

      /* Allocate space.  Note that we add extra storage in case of zero
	 diagonals.  This is necessary for conversion to MSR format. */

      pntr   = (int    *) calloc(N_columns+1,sizeof(int)) ;
      bindx = (int    *) calloc(n_entries+N_columns+1,sizeof(int)) ;
      val   = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ;
      
      readHB_mat_double(data_file, pntr, bindx, val);

      /* Translate integer arrays to zero base */
      for (int i = 0; i <= numGlobalEquations; i++) pntr[i]--;
      {for (int i = 0; i <= n_entries; i++) bindx[i]--;}

      /* If a rhs is specified in the file, read one, 
	 generating the associate storage */
      if (Nrhs > 0 && Rhstype[2] =='X')
	{
	  printf("Reading right-hand-side vector(s) from %s...\n",data_file);
	  hbb = (double *) calloc(N_columns,sizeof(double));
	  readHB_aux_double(data_file, 'F', hbb);
	  printf("Reading exact solution  vector(s) from %s...\n",data_file);
	  hbxexact = (double *) calloc(N_columns,sizeof(double));
	      readHB_aux_double(data_file, 'X', hbxexact);

	}
      else
	{
	  
	  /* Set Xexact to a random vector */

	  printf("%s", "Setting  random exact solution  vector\n");
	  hbxexact = (double *) calloc(N_columns,sizeof(double));
	  
	  for (int i=0;i<numGlobalEquations;i++)	 hbxexact[i] = 
                                              ((double)
                                               rand())/((double) RAND_MAX);
	  
	  /* Compute b to match xexact */
	  
	 hbb = (double   *) calloc(N_columns,sizeof(double)) ;
	  if (hbb == NULL) perror("Error: Not enough space to create rhs");
 

      Trilinos_Util_scscmv (isym, N_columns, N_columns, val, bindx, pntr, hbxexact, hbb);
	}

      /* Compute residual using CSC format */

      double res = Trilinos_Util_scscres(isym, numGlobalEquations, numGlobalEquations, val, bindx, pntr, 
		    hbxexact, hbb);
      printf(
	      "The residual using CSC format and exact solution is %12.4g\n",
	      res);

      
      /* Set initial guess to zero */
      
      hbx = (double   *) calloc(numGlobalEquations,sizeof(double)) ;
      
      if (hbx == NULL) 
	perror("Error: Not enough space to create guess");
      
      
      /* Set RHS to a random vector, initial guess to zero */
      {for (int i=0;i<numGlobalEquations;i++) hbx[i] = 0.0;}
      
      
      /* Allocate temporary space */
      
      pntr1 = (int   *) calloc(N_columns+1,sizeof(int)) ;
      indx1 = (int   *) calloc(n_entries+N_columns+1,sizeof(int)) ;
      val1 = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ;
      
      
      /* Convert in the following way:
	 - CSC to CSR 
	 - CSR to MSR
      */
      Trilinos_Util_csrcsc(numGlobalEquations, numGlobalEquations, 0, 0, val, bindx, pntr, val1, indx1, pntr1);
      
      if (Type[1] == 'S') 
	{
	  int *indu, *iwk;
	  int ierr;
	  indu = new int[N_columns];
	  iwk = new int[N_columns+1];
	  ierr = Trilinos_Util_ssrcsr(3, 1, N_columns, val1, indx1, pntr1, n_entries,
	  		  val1, indx1, pntr1, indu, iwk);
	  delete [] indu;
	  delete [] iwk;
	  if (ierr !=0 ) 
	    {
	    printf(" Error in converting from symmetric form\n  IERR = %d\n",ierr);
	    abort();
	    }
	}
  }
  comm.Broadcast(&numGlobalEquations, 1, 0);
  int nlocal = 0;
  if (comm.MyPID()==0) nlocal = numGlobalEquations;
  map = new Epetra_Map(numGlobalEquations, nlocal, 0, comm); // Create map with all elements on PE 0
  
  A = new Epetra_CrsMatrix(Copy, *map, 0); // Construct matrix on PE 0
  if (comm.MyPID()==0)
    for (int i=0; i<numGlobalEquations; i++)
      A->InsertGlobalValues(i, pntr1[i+1]-pntr1[i], val1+pntr1[i], indx1+pntr1[i]);
  A->FillComplete();
  
  x = new Epetra_Vector(Copy, *map, hbx);
  b = new Epetra_Vector(Copy, *map, hbb);
  xexact = new Epetra_Vector(Copy, *map, hbxexact);

  Epetra_Vector bcomp(*map);

  A->Multiply(false, *xexact, bcomp);
  double residual;
  bcomp.Norm2(&residual);
  if (comm.MyPID()==0) cout << "Norm of computed b = " << residual << endl;
  b->Norm2(&residual);
  if (comm.MyPID()==0) cout << "Norm of given b    = " << residual << endl;
  bcomp.Update(-1.0, *b, 1.0);
  bcomp.Norm2(&residual);
  if (comm.MyPID()==0) cout << "Norm of difference between computed b and given b for xexact = " << residual << endl;
  
  /* Release unneeded space */
  if (comm.MyPID()==0) {
    if (hbb!=0) free((void *) hbb);
    if (hbx!=0) free((void *) hbx);
    if (hbxexact!=0) free((void *) hbxexact);
    free((void *) val);
    free((void *) bindx);
    free((void *) val1);
    free((void *) indx1);
    free((void *) pntr1);
    free((void *) pntr);
  }
  return;
}
コード例 #5
0
ファイル: hb2mtxstrm.c プロジェクト: 10376920/pacs
void main(int argc, char *argv[])
{
    FILE *in_file;
    char Title[73], Key[9], Rhstype[4];
    char Type[4];
    char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
    int Ptrcrd, Indcrd, Valcrd, Rhscrd;
    int Indperline, Indwidth;
    int Valperline, Valwidth, Valprec;
    int Valflag;           /* Indicates 'E','D', or 'F' float format */
    int Nrow, Ncol, Nnzero;
    int Nrhs;
    char* ThisElement;
    char format[30];
    char rformat[30];
    int *colptr, *rowind;
    int *colcount;
    int i,j, repeat, count, col, ind, items, last;
    char line[BUFSIZ];
    MM_typecode matcode;

    if (argc != 2) {
      printf("Usage: %s HBfile\n\n", argv[0]);
      printf("   Sends Matrix Market formatted output to stdout\n");
      exit(-1);
    } 

    in_file = fopen( argv[1], "r");
    if (in_file == NULL)
    {
       fprintf(stderr,"Error: Cannot open file: %s\n",argv[1]);
       exit(1);
    }

    readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
                  Ptrfmt, Indfmt, Valfmt, Rhsfmt,
                  &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
    fclose(in_file);

    if (Type[0] == 'P' ) {
      fprintf(stderr,"This is a streaming translator for LARGE files with ");
      fprintf(stderr,"REAL or COMPLEX data.  Use 'hbmat2mtx' for PATTERN matrices.\n");
      exit(1);
    }
    in_file = readHB_newind(argv[1], &Nrow, &Ncol, &Nnzero, &colptr, &rowind);
    ParseIfmt(Indfmt,&Indperline,&Indwidth);
    sprintf(format,"%%%dd %%%dd ",Indwidth,Indwidth);
    ParseRfmt(Valfmt,&Valperline,&Valwidth,&Valprec,&Valflag);
    sprintf(rformat,"%%%ds ",Valwidth);
    ThisElement = (char *) malloc(Valwidth+1);


/*  Skip to values in hb file: */

   mm_set_matrix(&matcode);
   mm_set_coordinate(&matcode);
   if ( Type[0] == 'R' )
    mm_set_real(&matcode);
   else if ( Type[0] == 'C' )
    mm_set_complex(&matcode);
   else if ( Type[0] == 'P' )
    mm_set_pattern(&matcode);
   else {
    fprintf(stderr,"Unrecognized field in HB Type: %1s",Type);
    exit(1);
   }
   if ( Type[1] == 'U' || Type[1] == 'R' )
    mm_set_general(&matcode);
   else if ( Type[1] == 'S' )
    mm_set_symmetric(&matcode);
   else if ( Type[1] == 'Z' )
    mm_set_skew(&matcode);
   else if ( Type[1] == 'H' )
    mm_set_hermitian(&matcode);
   else {
    fprintf(stderr,"Unrecognized field in HB Type: %1s",&Type[1]);
    exit(1);
   }
   if ( Type[2] != 'A' ){
    fprintf(stderr,"Unrecognized format in HB Type: %1s",&Type[2]);
    exit(1);
   }
    mm_write_banner(stdout, matcode);
    fprintf(stdout,"%% RBTitle: %s\n",Title);
    fprintf(stdout,"%% RBKey:   %s\n",Key);
    mm_write_mtx_crd_size(stdout, Nrow, Ncol, Nnzero);

    if ( ThisElement == NULL ) IOHBTerminate("Insufficient memory for ThisElement.\nhb2mtxstrm.c: Line 117 approx.");
    repeat=0;
    if ( Type[0] == 'C') repeat=1;
    count = 0;
    colcount = &colptr[1];
    items = 0; 
    for (i=0;i<Valcrd;i++)
    {
       fgets(line, BUFSIZ, in_file);
       if ( sscanf(line,"%*s") < 0 ) {
         fprintf(stderr,"iohb.c: Null (or blank) line in value data region of HB file.\n");
         exit(1);
       }
       if (Valflag == 'D') {
          while( strchr(line,'D') ) *strchr(line,'D') = 'E';
       }
       col =  0;
       for (ind = 0;ind<Valperline;ind++)
       {
          if (count == Nnzero) break;
          if (count == *colcount-1) colcount++;
          strncpy(ThisElement,line+col,Valwidth);
          *(ThisElement+Valwidth) = (char) NULL;
          if ( Valflag != 'F' && strchr(ThisElement,'E') == NULL ) {
             /* insert a char prefix for exp */
             last = strlen(ThisElement);
             for (j=last+1;j>=0;j--) {
                ThisElement[j] = ThisElement[j-1];
                if ( ThisElement[j] == '+' || ThisElement[j] == '-' ) {
                   ThisElement[j-1] = Valflag;
                   break;
                }
             }
          }
         items++;
         if (items==1) fprintf(stdout,format,rowind[count],colcount-colptr);
         if (items > repeat) { 
            fprintf(stdout,rformat,ThisElement);
            fprintf(stdout,"\n");
            count++; 
            items=0;
         } else {
            fprintf(stdout,rformat,ThisElement);
         }
         col += Valwidth;
       }
    }
       
}
コード例 #6
0
ファイル: hb2mtxstrm.c プロジェクト: 10376920/pacs
FILE * readHB_ind(const char* filename, int colptr[], int rowind[])
{
/****************************************************************************/
/*  This function opens and reads the specified file, interpreting its      */
/*  contents as a sparse matrix stored in the Harwell/Boeing standard       */
/*  format and creating compressed column storage scheme vectors to hold    */
/*  the index information.                                                  */
/*                                                                          */
/*    ----------                                                            */
/*    **CAVEAT**                                                            */
/*    ----------                                                            */
/*  Parsing real formats from Fortran is tricky, and this file reader       */
/*  does not claim to be foolproof.   It has been tested for cases when     */
/*  the real values are printed consistently and evenly spaced on each      */
/*  line, with Fixed (F), and Exponential (E or D) formats.                 */
/*                                                                          */
/*  **  If the input file does not adhere to the H/B format, the  **        */
/*  **             results will be unpredictable.                 **        */
/*                                                                          */
/****************************************************************************/
    FILE *in_file;
    int i,ind,col,offset,count;
    int Nrow,Ncol,Nnzero,Nrhs;
    int Ptrcrd, Indcrd, Valcrd, Rhscrd;
    int Ptrperline, Ptrwidth, Indperline, Indwidth;
    int Valperline, Valwidth, Valprec;
    int Valflag;           /* Indicates 'E','D', or 'F' float format */
    char* ThisElement;
    char line[BUFSIZ];
    char Title[73], Key[8], Type[4], Rhstype[4];
    char Ptrfmt[17], Indfmt[17], Rhsfmt[21], Valfmt[21];

    if ( (in_file = fopen( filename, "r")) == NULL ) {
       fprintf(stderr,"Error: Cannot open file: %s\n",filename);
       return 0;
    }

    readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
                  Ptrfmt, Indfmt, Valfmt, Rhsfmt,
                  &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);

/*  Parse the array input formats from Line 3 of HB file  */
    ParseIfmt(Ptrfmt,&Ptrperline,&Ptrwidth);
    ParseIfmt(Indfmt,&Indperline,&Indwidth);
    ParseRfmt(Valfmt,&Valperline,&Valwidth,&Valprec,&Valflag);
    if (Valflag == 'D') {
          *strchr(Valfmt,'D') = 'E';
    }

/*  Read column pointer array:   */

    offset = 1-_SP_base;  /* if base 0 storage is declared (via macro definition), */
                          /* then storage entries are offset by 1                  */

    ThisElement = (char *) malloc(Ptrwidth+1);
    if ( ThisElement == NULL ) IOHBTerminate("Insufficient memory for ThisElement.\nhb2mtxstrm.c: Line 216 approx.");
    count=0;
    for (i=0;i<Ptrcrd;i++)
    {
       fgets(line, BUFSIZ, in_file);
       if ( sscanf(line,"%*s") < 0 ) 
         IOHBTerminate("iohb.c: Null (or blank) line in pointer data region of HB file.\n");
       col =  0;
       for (ind = 0;ind<Ptrperline;ind++)
       {
          if (count > Ncol) break;
          strncpy(ThisElement,line+col,Ptrwidth);
          *(ThisElement+Ptrwidth) = (char) NULL;
/*          ThisElement = substr(line,col,Ptrwidth); */
          colptr[count] = atoi(ThisElement)-offset;
          count++; col += Ptrwidth;
       }
    }
    free(ThisElement);

/*  Read row index array:  */

    ThisElement = (char *) malloc(Ptrwidth+1);
    if ( ThisElement == NULL ) IOHBTerminate("Insufficient memory for ThisElement.\nhb2mtxstrm.c: Line 238 approx.");
    count = 0;
    for (i=0;i<Indcrd;i++)
    {
       fgets(line, BUFSIZ, in_file);
       if ( sscanf(line,"%*s") < 0 ) 
         IOHBTerminate("iohb.c: Null (or blank) line in index data region of HB file.\n");
       col =  0;
       for (ind = 0;ind<Indperline;ind++)
       {
          if (count == Nnzero) break;
          strncpy(ThisElement,line+col,Indwidth);
          *(ThisElement+Indwidth) = (char) NULL;
          /* ThisElement = substr(line,col,Indwidth);*/
          rowind[count] = atoi(ThisElement)-offset;
          count++; col += Indwidth;
       }
    }
    free(ThisElement);
    return in_file;
}
コード例 #7
0
ファイル: hbmat2mtx.c プロジェクト: nschloe/hbio
int main(int argc, char *argv[])
{
  FILE *in_file;
  char Title[73], Key[9], Rhstype[4];
  char Type[4];
  char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
  int Ptrcrd, Indcrd, Valcrd;
  int Rhscrd = 0;
  int Indperline, Indwidth;
  int Valperline, Valwidth, Valprec;
  int Valflag;           /* Indicates 'E','D', or 'F' float format */
  int Nrow, Ncol, Nnzero;
  int Nrhs;
  char *valc = NULL;
  char *Valfmtc;
  char *tmp1;
  char *tmp2;
  char format[30];
  char rformat[30];
  char cformat[30];
  int *colptr, *rowind;
  int i,j, indxval, rowp1, colp1;
  MM_typecode matcode;

  if (argc != 2) {
    printf("Usage: %s HBfile \n", argv[0]);
    exit(-1);
  }

  in_file = fopen( argv[1], "r");
  if (in_file == NULL)
  {
    fprintf(stderr,"Error: Cannot open file: %s\n",argv[1]);
    exit(1);
  }

  readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
      Ptrfmt, Indfmt, Valfmt, Rhsfmt,
      &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
  fclose(in_file);

  readHB_newmat_char(argv[1], &Nrow, &Ncol, &Nnzero, &colptr, &rowind, &valc,
      &Valfmtc);
  ParseIfmt(Indfmt,&Indperline,&Indwidth);
  ParseRfmt(Valfmt,&Valperline,&Valwidth,&Valprec,&Valflag);
  sprintf(format,"%%%dd %%%dd \n",Indwidth,Indwidth);
  sprintf(rformat,"%%%dd %%%dd %%%ds\n",Indwidth,Indwidth,Valwidth);
  sprintf(cformat,"%%%dd %%%dd %%%ds %%%ds\n",Indwidth,Indwidth,Valwidth,Valwidth);


  mm_set_matrix(&matcode);
  mm_set_coordinate(&matcode);
  if ( Type[0] == 'R' )
    mm_set_real(&matcode);
  else if ( Type[0] == 'C' )
    mm_set_complex(&matcode);
  else if ( Type[0] == 'P' )
    mm_set_pattern(&matcode);
  else {
    fprintf(stderr,"Unrecognized field in HB Type: %1s",Type);
    exit(1);
  }
  if ( Type[1] == 'U' || Type[1] == 'R' )
    mm_set_general(&matcode);
  else if ( Type[1] == 'S' )
    mm_set_symmetric(&matcode);
  else if ( Type[1] == 'Z' )
    mm_set_skew(&matcode);
  else if ( Type[1] == 'H' )
    mm_set_hermitian(&matcode);
  else {
    fprintf(stderr,"Unrecognized field in HB Type: %1s",&Type[1]);
    exit(1);
  }
  if ( Type[2] != 'A' ){
    fprintf(stderr,"Unrecognized format in HB Type: %1s",&Type[2]);
    exit(1);
  }
  mm_write_banner(stdout, matcode);
  fprintf(stdout,"%% RBTitle: %s\n",Title);
  fprintf(stdout,"%% RBKey:   %s\n",Key);
  mm_write_mtx_crd_size(stdout, Nrow, Ncol, Nnzero);

  if ( Type[0] == 'C' ) {
    /*  Loop through columns */
    for (j = 0; j < Ncol ; j++)
      for (i=colptr[j];i<colptr[j+1];i++)
      {
        indxval = 2*(i-1);
        rowp1 = rowind[i-1]+1-1;
        colp1 = j + 1;
        tmp1 = substr(valc,indxval*Valwidth,Valwidth);
        tmp2 = substr(valc,(indxval+1)*Valwidth,Valwidth);
        fprintf(stdout,cformat,rowp1,colp1,tmp1,tmp2);
      }
  } else if ( Type[0] == 'R' ) {
    /*  Loop through columns */
    for (j = 0; j < Ncol ; j++)
      for (i=colptr[j];i<colptr[j+1];i++)
      {
        rowp1 = rowind[i-1];
        colp1 = j + 1;
        tmp1 = substr(valc,(i-1)*Valwidth,Valwidth);
        fprintf(stdout,rformat,rowp1,colp1,tmp1);
      }
  } else {
    /*  Loop through columns */
    for (j = 0; j < Ncol ; j++)
      for (i=colptr[j];i<colptr[j+1];i++)
      {
        rowp1 = rowind[i-1];
        colp1 = j + 1;
        fprintf(stdout,format,rowp1,colp1);
      }
  }
  return 0;
}
コード例 #8
0
void read_hb(char *data_file,
	      int *N_global, int *n_nonzeros, 
	      double **val, int **bindx,
	      double **x, double **b, double **bt, double **xexact)
#undef DEBUG 

{
  FILE *in_file ;
  char Title[73], Key[9], Rhstype[4];
  char Type[4] = "XXX\0";
  char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
  int Ptrcrd, Indcrd, Valcrd, Rhscrd;

  int i, n_entries, N_columns, Nrhs;
  int ii, jj ;
  int kk = 0;
  int isym;
  int ione = 1;
  double value, res;
  double *cnt;
  int *pntr, *indx1, *pntr1;
  double *val1;

  
      in_file = fopen( data_file, "r");
      if (in_file == NULL)
	{
	  printf("Error: Cannot open file: %s\n",data_file);
	  exit(1);
	}

      /* Get information about the array stored in the file specified in the  */
      /* argument list:                                                       */

      printf("Reading matrix info from %s...\n",data_file);
      
      in_file = fopen( data_file, "r");
      if (in_file == NULL)
	{
	  printf("Error: Cannot open file: %s\n",data_file);
	  exit(1);
	}

      readHB_header(in_file, Title, Key, Type, N_global, &N_columns, 
		    &n_entries, &Nrhs,
		    Ptrfmt, Indfmt, Valfmt, Rhsfmt,
		    &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
      fclose(in_file);

      if (Nrhs < 0 ) Nrhs = 0;

      printf("***************************************************************\n");
      printf("Matrix in file %s is %d x %d, \n",data_file, *N_global, N_columns);
      printf("with %d nonzeros with type %3s;\n", n_entries, Type);
      printf("***************************************************************\n");
      printf("Title: %72s\n",Title);
      printf("***************************************************************\n");
      /*Nrhs = 0; */
      printf("%d right-hand-side(s) available.\n",Nrhs);

      if (Type[0] != 'R') perror("Can only handle real valued matrices");
      isym = 0;
      if (Type[1] == 'S') 
	{
	  printf("Converting symmetric matrix to nonsymmetric storage\n");
	  n_entries = 2*n_entries - N_columns;
	  isym = 1;
	}
      if (Type[2] != 'A') perror("Can only handle assembled matrices");
      if (N_columns != *N_global) perror("Matrix dimensions must be the same");
      *n_nonzeros = n_entries;
      
      /* Read the matrix information, generating the associated storage arrays  */
      printf("Reading the matrix from %s...\n",data_file);

      /* Allocate space.  Note that we add extra storage in case of zero
	 diagonals.  This is necessary for conversion to MSR format. */

      pntr   = (int    *) calloc(N_columns+1,sizeof(int)) ;
      *bindx = (int    *) calloc(n_entries+N_columns+1,sizeof(int)) ;
      *val   = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ;
      
      readHB_mat_double(data_file, pntr, *bindx, *val);

      /* If a rhs is specified in the file, read one, 
	 generating the associate storage */
      if (Nrhs > 0 && Rhstype[2] =='X')
	{
	  printf("Reading right-hand-side vector(s) from %s...\n",data_file);
	  *b = (double *) calloc(N_columns,sizeof(double));
	  readHB_aux_double(data_file, 'F', (*b));
	  printf("Reading exact solution  vector(s) from %s...\n",data_file);
	  *xexact = (double *) calloc(N_columns,sizeof(double));
	      readHB_aux_double(data_file, 'X', (*xexact));

	}
      else
	{
	  
	  /* Set Xexact to a random vector */

	  printf("Setting  random exact solution  vector\n");
	  *xexact = (double *) calloc(N_columns,sizeof(double));
	  
	  for (i=0;i<*N_global;i++)	 (*xexact)[i] = drand48();
	  
	  /* Compute b to match xexact */
	  
	  *b = (double   *) calloc(N_columns,sizeof(double)) ;
	  if ((*b) == NULL) perror("Error: Not enough space to create rhs");
 
	  scscmv (isym, 1, N_columns, N_columns, (*val), (*bindx), pntr, (*xexact), (*b));

	}

      /* Compute residual using CSC format */

      for (i = 0; i <= *N_global; i++) pntr[i]--;
      for (i = 0; i <= n_entries; i++) (*bindx)[i]--;
      res = scscres(isym, *N_global, *N_global, (*val), (*bindx), pntr, 
		    (*xexact), (*b));
      printf(
	      "The residual using CSC format and exact solution is %12.4g\n",
	      res);
      for (i = 0; i <= *N_global; i++) pntr[i]++;
      for (i = 0; i <= n_entries; i++) (*bindx)[i]++;

      
      /* Set initial guess to zero */
      
      *x = (double   *) calloc((*N_global),sizeof(double)) ;
      
      if ((*x) == NULL) 
	perror("Error: Not enough space to create guess");
      
      
      /* Set RHS to a random vector, initial guess to zero */
      for (i=0;i<*N_global;i++) (*x)[i] = 0.0;
      
      
      /* Allocate temporary space */
      
      pntr1 = (int   *) calloc(N_columns+1,sizeof(int)) ;
      indx1 = (int   *) calloc(n_entries+N_columns+1,sizeof(int)) ;
      val1 = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ;
      
      
      /* Convert in the following way:
	 - CSC to CSR 
	 - CSR to MSR
      */
      csrcsc_(N_global,&ione,&ione,
	      *val,*bindx,pntr,
	      val1,indx1,pntr1);

      /* Compute bt = A(trans)*xexact */

      *bt = (double   *) calloc(N_columns,sizeof(double)) ;
      
      scscmv (isym, 1, N_columns, N_columns, val1, indx1, pntr1, (*xexact), (*bt));

      if (Type[1] == 'S') 
	{
	  int *indu;
	  int ierr;
	  indu = indx1+n_entries; /* Use end of bindx for workspace */
	  ssrcsr_(&N_columns, val1, indx1, pntr1, &n_entries,
				  val1, indx1, pntr1, indu, &ierr);
	  if (ierr !=0 ) 
	    {
	    printf(" Error in converting from symmetric form\n  IERR = %d\n",ierr);
	    abort();
	    }
	}

      csrmsr_(N_global,val1,indx1,pntr1,
	      *val,*bindx,
	      *val,*bindx);
      
      /* Recompute number of nonzeros in case there were zero diagonals */
      
      *n_nonzeros = (*bindx)[*N_global] - 2; /* Still in Fortran mode so -2 */
      
      /* Finally, convert bindx vectors to zero base */
      
      for (i=0;i<*n_nonzeros+1;i++) (*bindx)[i] -= 1;
      

      printf("The residual using MSR format and exact solution is %12.4g\n",
	      smsrres (*N_global, *N_global, (*val), (*bindx), 
		       (*xexact), (*xexact), (*b)));

      /* Release unneeded space */

      free((void *) val1);
      free((void *) indx1);
      free((void *) pntr1);
      free((void *) pntr);
  
  /* end read_hb */
}