Exemplo n.º 1
0
static void taucs_ccs_randomperm(int n, int **perm, int **invperm)
{
	int i;

	*perm = (int *) taucs_malloc(n * sizeof(int));
	*invperm = (int *) taucs_malloc(n * sizeof(int));
	if (!(*perm) || !(*invperm)) {
		taucs_free(*perm);
		taucs_free(*invperm);
		*perm = *invperm = NULL;
		taucs_printf("taucs_ccs_randomperm: out of memory for permutation\n");
		return;
	}

	for (i = 0; i < n; i++)
		(*perm)[i] = i;

	for (i = 0; i < n; i++) {
		int i1, i2;
		int t;

		i1 = rand() % (n - i);
		i2 = n - i - 1;

		t = (*perm)[i1];
		(*perm)[i1] = (*perm)[i2];
		(*perm)[i2] = t;
	}

	for (i = 0; i < n; i++)
		(*invperm)[(*perm)[i]] = i;
	return;
}
Exemplo n.º 2
0
void taucs_dtl(ccs_free) (taucs_ccs_matrix * matrix) {
	if (!matrix)
		return;

	taucs_free(matrix->rowind);
	taucs_free(matrix->colptr);
	taucs_free(matrix->taucs_values);
	taucs_free(matrix);
}
double taucs_available_memory_size() 
{
  double m_sys;
  double m,m_low,m_high,m_tol;
  char*  p;

  m_sys = taucs_system_memory_size();
  
  /* malloc test */

  m = 1048576.0;

  while ( (p=(char*) taucs_malloc( (size_t) (m*2.0) )) != NULL ) {
    taucs_free(p);
    m = m*2.0;
  }

  m_low  = m;
  m_high = 2.0*m;
  m_tol  = m / 128.0;

  while ( m_high - m_low > m_tol ) {
    m = m_low + ( (m_high-m_low)/2.0 );
    taucs_printf("taucs_avail_memory_size: [%.0lf %.0lf %.0lf]\n",
	       m_low  / 1048576.0,
	       m      / 1048576.0,
	       m_high / 1048576.0);
    if ( (p=(char*) taucs_malloc( (size_t) m )) != NULL ) 
      m_low = m;
    else 
      m_high = m;
    taucs_free(p);
  }

  m = m_low;

  taucs_printf("taucs_avail_memory_size: malloc test=%.0lf MB sys test=%.0lf MB\n",
	     m / 1048576.0,
	     m_sys / 1048576.0
	     );

  /* if m_sys is meaningful, then we limit m by 0.75*m_sys */

  if (m_sys > 0) {
    m_sys = floor(0.75 * m_sys); 
    if (m_sys < m) m = m_sys;
  }

  return m;
}
Exemplo n.º 4
0
taucs_ccs_matrix *taucs_dtl(ccs_create) (int m, int n, int nnz) {
	taucs_ccs_matrix *matrix;

	matrix = (taucs_ccs_matrix *) taucs_malloc(sizeof(taucs_ccs_matrix));
	if (!matrix) {
		taucs_printf("taucs_ccs_create: out of memory\n");
		return NULL;
	}
#ifdef TAUCS_CORE_DOUBLE
	matrix->flags = TAUCS_DOUBLE;
#endif

#ifdef TAUCS_CORE_SINGLE
	matrix->flags = TAUCS_SINGLE;
#endif

#ifdef TAUCS_CORE_DCOMPLEX
	matrix->flags = TAUCS_DCOMPLEX;
#endif

#ifdef TAUCS_CORE_SINGLE
	matrix->flags = TAUCS_SINGLE;
#endif

	matrix->n = n;
	matrix->m = m;
	matrix->colptr = (int *) taucs_malloc((n + 1) * sizeof(int));
	matrix->rowind = (int *) taucs_malloc(nnz * sizeof(int));
	matrix->taucs_values = (taucs_datatype *) taucs_malloc(nnz * sizeof(taucs_datatype));
	if (!(matrix->colptr) || !(matrix->rowind) || !(matrix->taucs_values)) {
		taucs_printf("taucs_ccs_create: out of memory (n=%d, nnz=%d)\n", n, nnz);
		taucs_free(matrix->colptr);
		taucs_free(matrix->rowind);
		taucs_free(matrix->taucs_values);
		taucs_free(matrix);
		return NULL;
	}

	return matrix;
}
void 
taucs_ccs_order(taucs_ccs_matrix* m, 
		int** perm, int** invperm,
		char* which)
{
  if (!strcmp(which,"mmd") || !strcmp(which,"amd") || !strcmp(which,"md")) 
    taucs_ccs_amd(m,perm,invperm,which);
  else if (!strcmp(which,"metis"))
    taucs_ccs_metis(m,perm,invperm,which);
  else if (!strcmp(which,"genmmd"))
    taucs_ccs_genmmd(m,perm,invperm,which);
  else if (!strcmp(which,"colamd"))
    taucs_ccs_colamd(m,perm,invperm,which);
  else if (!strcmp(which,"random"))
    taucs_ccs_randomperm(m->n,perm,invperm);
  else if (!strcmp(which,"tree")) {
    taucs_ccs_treeorder(m,perm,invperm);
    if (*perm == NULL) /* perhaps the graph of the matrix is not a tree */
      taucs_ccs_metis(m,perm,invperm,"metis");
  }
  else if (!strcmp(which,"identity")) {
    int i;
    *perm    = (int*) taucs_malloc((m->n) * sizeof(int));
    *invperm = (int*) taucs_malloc((m->n) * sizeof(int));
    if (!(*perm) || !(*invperm)) {
      taucs_free(*perm); taucs_free(*invperm);
      *perm = *invperm = NULL;
      taucs_printf("taucs_ccs_order: out of memory for identity permutation\n");
      return;
    }
    for (i=0; i<m->n; i++) (*perm)[i] = (*invperm)[i] = i;
    return;
  }
  else {
    taucs_printf("taucs_ccs_order: invalid ordering requested (%s)\n",which);
    *perm = *invperm = NULL;
  }
}
Exemplo n.º 6
0
void taucs_sccs_times_vec_dacc(taucs_ccs_matrix * m, taucs_single * X, taucs_single * B)
{
	int i, ip, j, n;
	taucs_single Aij;
	taucs_double *Bd;

	assert(m->flags & TAUCS_SYMMETRIC);
	assert(m->flags & TAUCS_LOWER);
	assert(m->flags & TAUCS_SINGLE);

	n = m->n;

	Bd = (taucs_double *) taucs_malloc(n * sizeof(taucs_double));
	if (Bd == NULL) {
		taucs_sccs_times_vec(m, X, B);
		return;
	}

	for (i = 0; i < n; i++)
		Bd[i] = 0.0;

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr[j + 1]); ip++) {
			i = (m->rowind)[ip];
			Aij = (m->taucs_values)[ip];

			Bd[i] += X[j] * Aij;
			if (i != j)
				Bd[j] += X[i] * Aij;
		}
	}

	for (i = 0; i < n; i++)
		B[i] = (taucs_single) Bd[i];
	taucs_free(Bd);
}
Exemplo n.º 7
0
taucs_ccs_matrix* 
taucs_dtl(ccs_read_ijv)(char* ijvfilename,int flags,int base)
{
	/* omer - base is 0 when the ijv file is 1-based and 1 when the ijv file
	is 0-based. we add base to the i's and j's found.*/
  FILE* f;
  taucs_ccs_matrix*  m;
  int*    clen; 
  int*    is; 
  int*    js;
  taucs_datatype* vs;
  int ncols, nrows, nnz;
  int i,j,k,n;
  double         di,dj;
  taucs_datatype dv;

  f = fopen (ijvfilename , "r");

  if (f == NULL) {
    taucs_printf("taucs_ccs_read_ijv: could not open ijv file %s\n",ijvfilename);
    return NULL;
  }

  n = 10000;
  is = (int*)    taucs_malloc(n*sizeof(int));
  js = (int*)    taucs_malloc(n*sizeof(int));
  vs = (taucs_datatype*) taucs_malloc(n*sizeof(taucs_datatype));
  if (!is || !js || !vs) {
    taucs_printf("symccs_read_ijv: out of memory\n");
    taucs_free(is); taucs_free(js); taucs_free(vs); 
    return NULL; 
  }

  nnz = 0;
  nrows = ncols = 0;
  while (!feof(f)) {
    if (nnz == n) {
      n = (int) ( 1.25 * (double) n);
      taucs_printf("taucs_ccs_read_ijv: allocating %d ijv's\n",n);
      is = (int*)    taucs_realloc(is,n*sizeof(int));
      js = (int*)    taucs_realloc(js,n*sizeof(int));
      vs = (taucs_datatype*) taucs_realloc(vs,n*sizeof(taucs_datatype));
      if (!is || !js || !vs) { 
	taucs_printf("taucs_ccs_read_ijv: out of memory\n");
	taucs_free(is); taucs_free(js); taucs_free(vs); 
	return NULL; 
      }
    }

#ifdef TAUCS_CORE_DOUBLE
    if (fscanf(f, "%lg %lg %lg", &di, &dj, &dv) != 3) break;
#endif

#ifdef TAUCS_CORE_SINGLE
    if (fscanf(f, "%lg %lg %g", &di, &dj, &dv) != 3) break;
#endif

#ifdef TAUCS_CORE_COMPLEX
    {
      taucs_real_datatype dv_i;
      taucs_real_datatype dv_r;

#ifdef TAUCS_CORE_DCOMPLEX
      if (fscanf(f, "%lg %lg %lg+%lgi", &di, &dj, &dv_r,&dv_i) != 4) break;
#endif
#ifdef TAUCS_CORE_SCOMPLEX
      if (fscanf(f, "%lg %lg %g+%gi", &di, &dj, &dv_r, &dv_i) != 4) break;
#endif
      dv = taucs_complex_create(dv_r,dv_i);
    }
#endif

    is[nnz] = (int)di+base; js[nnz] = (int)dj+base; vs[nnz] = dv;/*omer*/
    /* we read the lower part */
    if ((flags & TAUCS_SYMMETRIC) && is[nnz] < js[nnz]) continue; 
    if ((flags & TAUCS_HERMITIAN) && is[nnz] < js[nnz]) continue; 
    nrows = max(is[nnz],nrows);
    ncols = max(js[nnz],ncols);
    nnz++;
   }

  fclose ( f );

  m = (taucs_ccs_matrix*) taucs_malloc(sizeof(taucs_ccs_matrix));
  if (!m) { 
    taucs_printf("taucs_ccs_read_ijv: out of memory\n");
    taucs_free(is); taucs_free(js); taucs_free(vs); 
    return NULL; 
  }
  m->n      = ncols;
  m->m      = nrows;
  m->flags  = 0;
  if (flags & TAUCS_SYMMETRIC) 
    m->flags  = TAUCS_SYMMETRIC | TAUCS_LOWER;
  if (flags & TAUCS_HERMITIAN) 
    m->flags  = TAUCS_HERMITIAN | TAUCS_LOWER;

#ifdef TAUCS_CORE_DOUBLE
  m->flags |= TAUCS_DOUBLE;
#endif

#ifdef TAUCS_CORE_SINGLE
  m->flags |= TAUCS_SINGLE;
#endif

#ifdef TAUCS_CORE_DCOMPLEX
  m->flags |= TAUCS_DCOMPLEX;
#endif

#ifdef TAUCS_CORE_SCOMPLEX
  m->flags |= TAUCS_SCOMPLEX;
#endif

  clen      = (int*)    taucs_malloc((ncols+1) * sizeof(int));
  m->colptr = (int*)    taucs_malloc((ncols+1) * sizeof(int));
  m->rowind = (int*)    taucs_malloc(nnz       * sizeof(int));
  m->taucs_values = (taucs_datatype*) taucs_malloc(nnz * sizeof(taucs_datatype));
  if (!clen || !(m->colptr) || !(m->rowind) || !(m->rowind)) {
    taucs_printf("taucs_ccs_read_ijv: out of memory: ncols=%d nnz=%d\n",ncols,nnz);
    taucs_free(clen); taucs_free(m->colptr); taucs_free(m->rowind); 
    taucs_free(m->taucs_values);
    taucs_free (m); taucs_free(is); taucs_free(js); taucs_free(vs); 
    return NULL; 
  }

  for (j=0; j<ncols; j++) clen[j] = 0;
  for (k=0; k<nnz; k++) {
    i = is[k] - 1; /* make it 1-based */
    j = js[k] - 1; /* make it 1-based */
		if ( j<0 || j>ncols ) taucs_printf("j=%d k=%d\n",j,k);
    ( clen[j] )++;
  }
  /* just check */
  k = 0;
  for (j=0; j<ncols; j++) 
    k += clen[j];
	if (k!=nnz) taucs_printf("k=%d, nnz=%d\n",k,nnz);
  assert(k == nnz);

  /* now compute column pointers */
  
  k = 0;
  for (j=0; j<ncols; j++) {
    int tmp;
    tmp =  clen[j];
    clen[j] = (m->colptr[j]) = k;
    k += tmp;
  }
  clen[ncols] = (m->colptr[ncols]) = k;
  assert(clen[ncols] == nnz);
  
  /* now read matrix into data structure */

  for (k=0; k<nnz; k++) {
    i = is[k] - 1; /* make it 1-based */
    j = js[k] - 1; /* make it 1-based */
    assert(i < nrows);
    assert(j < ncols);
    (m->taucs_values)[ clen[j] ] = vs[k];
    (m->rowind)[ clen[j] ] = i;
    clen[j] ++;
  }
  
  taucs_free(clen);
  taucs_free(vs);
  taucs_free(js);
  taucs_free(is);
  
  taucs_printf("taucs_ccs_read_ijv: read %s, n=%d\n",ijvfilename,m->n);

  return m;
} 
Exemplo n.º 8
0
static void taucs_ccs_metis(taucs_ccs_matrix * m, int **perm, int **invperm, char *which)
{
#ifndef TAUCS_CONFIG_METIS
	taucs_printf("taucs_ccs_metis: METIS routines not linked.\n");
	*perm = NULL;
	*invperm = NULL;
	return;
#else
	int n, nnz, i, j, ip;
	int *xadj;
	int *adj;
	int num_flag = 0;
	int options_flag[8];
	int *len;
	int *ptr;

	/*
	 * taucs_printf("taucs_ccs_metis: starting (%s)\n",which); 
	 */

	if (!(m->flags & TAUCS_SYMMETRIC) && !(m->flags & TAUCS_HERMITIAN)) {
		taucs_printf("taucs_ccs_treeorder: METIS ordering only works on symmetric matrices.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}
	/*
	 * this routine may actually work on UPPER as well 
	 */
	if (!(m->flags & TAUCS_LOWER)) {
		taucs_printf("taucs_ccs_metis: the lower part of the matrix must be represented.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}

	n = m->n;
	nnz = (m->colptr)[n];

	*perm = (int *) taucs_malloc(n * sizeof(int));
	*invperm = (int *) taucs_malloc(n * sizeof(int));

	xadj = (int *) taucs_malloc((n + 1) * sizeof(int));
	adj = (int *) taucs_malloc(2 * nnz * sizeof(int));

	if (!(*perm) || !(*invperm) || !xadj || !adj) {
		taucs_free(*perm);
		taucs_free(*invperm);
		taucs_free(xadj);
		taucs_free(adj);
		*perm = *invperm = NULL;
		return;
	}

	ptr = len = *perm;
	for (i = 0; i < n; i++)
		len[i] = 0;

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			/*
			 * i = (m->rowind)[ip] - (m->indshift);
			 */
			i = (m->rowind)[ip];
			if (i != j) {
				len[i]++;
				len[j]++;
			}
		}
	}

	xadj[0] = 0;
	for (i = 1; i <= n; i++)
		xadj[i] = xadj[i - 1] + len[i - 1];

	for (i = 0; i < n; i++)
		ptr[i] = xadj[i];

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			/*
			 * i = (m->rowind)[ip] - (m->indshift);
			 */
			i = (m->rowind)[ip];
			if (i != j) {
				adj[ptr[i]] = j;
				adj[ptr[j]] = i;
				ptr[i]++;
				ptr[j]++;
			}
		}
	}

	options_flag[0] = 1;				       /* use these options */
	options_flag[1] = 3;				       /* default */
	options_flag[2] = 1;				       /* default */
	options_flag[3] = 1;				       /* two-side refinement */
	options_flag[4] = 0;				       /* no debug */
	options_flag[5] = 1;				       /* default */
	options_flag[6] = 0; 				       /* THIS IS SLOW if non-zero. global nodes */
	options_flag[7] = 3;				       /* number of separators */

	METIS_NodeND(&n, xadj, adj, &num_flag, options_flag, *perm, *invperm);

	taucs_free(xadj);
	taucs_free(adj);
#endif
}
Exemplo n.º 9
0
static void taucs_ccs_treeorder(taucs_ccs_matrix * m, int **perm, int **invperm)
{
	int n, nnz, i, j, ip, k, p, nleaves;
	int *adjptr;
	int *adj;
	int *len;
	int *ptr;
	int *degree;
	int *leaves;

	if (!(m->flags & TAUCS_SYMMETRIC) && !(m->flags & TAUCS_HERMITIAN)) {
		taucs_printf("taucs_ccs_treeorder: tree ordering only works on symmetric matrices.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}
	/*
	 * this routine may actually work on UPPER as well 
	 */
	if (!(m->flags & TAUCS_LOWER)) {
		taucs_printf("taucs_ccs_treeorder: the lower part of the matrix must be represented.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}

	n = m->n;
	nnz = (m->colptr)[n];

	taucs_printf("taucs_ccs_treeorder: starting, matrix is %dx%d, # edges=%d\n", n, n, nnz - n);

	*perm = (int *) taucs_malloc(n * sizeof(int));
	*invperm = (int *) taucs_malloc(n * sizeof(int));

	/*
	 * we can reuse buffers: don't need invperm until the end 
	 */
	/*
	 * also, we can reuse perm for leaves but it's messy.  
	 */
	len = (int *) taucs_malloc(n * sizeof(int));
	degree = (int *) taucs_malloc(n * sizeof(int));
	leaves = (int *) taucs_malloc(n * sizeof(int));

	adjptr = (int *) taucs_malloc(n * sizeof(int));
	adj = (int *) taucs_malloc(2 * (nnz - n) * sizeof(int));

	if (!(*perm) || !(*invperm) || !adjptr || !adj || !len || !degree || !leaves) {
		taucs_free(adj);
		taucs_free(adjptr);
		taucs_free(len);
		taucs_free(leaves);
		taucs_free(degree);
		taucs_free(*perm);
		taucs_free(*invperm);
		*perm = *invperm = NULL;
	}

	for (i = 0; i < n; i++)
		len[i] = 0;

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			/*
			 * i = (m->rowind)[ip] - (m->indshift);
			 */
			i = (m->rowind)[ip];
			if (i != j) {
				len[i]++;
				len[j]++;
			}
		}
	}

	nleaves = 0;
	for (i = 0; i < n; i++) {
		degree[i] = len[i];
		if (degree[i] <= 1) {
			leaves[nleaves] = i;
			nleaves++;
		}
	}

	adjptr[0] = 0;
	for (i = 1; i < n; i++)
		adjptr[i] = adjptr[i - 1] + len[i - 1];

	ptr = *perm;
	for (i = 0; i < n; i++)
		ptr[i] = adjptr[i];

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			/*
			 * i = (m->rowind)[ip] - (m->indshift);
			 */
			i = (m->rowind)[ip];
			if (i != j) {
				adj[ptr[i]] = j;
				adj[ptr[j]] = i;
				ptr[i]++;
				ptr[j]++;
			}
		}
	}

	/*
	 * taucs_printf("taucs_ccs_treeorder: %d initial leaves: ",nleaves); for (i=0; i<nleaves; i++) taucs_printf("%d
	 * ",leaves[i]); taucs_printf("\n"); 
	 */

	for (i = 0; i < n; i++) {
		nleaves--;
		if (nleaves <= 0) {
			/*
			 * not a tree 
			 */
			taucs_free(adj);
			taucs_free(adjptr);
			taucs_free(len);
			taucs_free(leaves);
			taucs_free(degree);
			taucs_free(*perm);
			taucs_free(*invperm);
			*perm = *invperm = NULL;
		}
		j = leaves[nleaves];

		/*
		 * taucs_printf("taucs_ccs_treeorder: next leaf is %d, degree=%d\n",j,len[j]);
		 */

		(*perm)[i] = j;
		(*invperm)[j] = i;

		if (len[j] > 0) {
			if (len[j] != 1) {
				/*
				 * not a tree 
				 */
				taucs_free(adj);
				taucs_free(adjptr);
				taucs_free(len);
				taucs_free(leaves);
				taucs_free(degree);
				taucs_free(*perm);
				taucs_free(*invperm);
				*perm = *invperm = NULL;
			}
			p = adj[adjptr[j]];

			/*
			 * taucs_printf("taucs_ccs_treeorder: parent of %d is %d\n",j,p);
			 */

			for (k = 0; k < len[p]; k++)
				if (adj[adjptr[p] + k] == j)
					break;

			if (k >= len[p]) {		       /* otherwise j does not show up in p's adjacency list */
				/*
				 * not a tree 
				 */
				taucs_free(adj);
				taucs_free(adjptr);
				taucs_free(len);
				taucs_free(leaves);
				taucs_free(degree);
				taucs_free(*perm);
				taucs_free(*invperm);
				*perm = *invperm = NULL;
			}

			/*
			 * now delete j from p's adjacency list and compress 
			 */
			len[p]--;
			for (; k < len[p]; k++)
				adj[adjptr[p] + k] = adj[adjptr[p] + k + 1];

			if (len[p] == 1) {		       /* degree was higher and now is 1 */
				leaves[nleaves] = p;
				nleaves++;
			}
		}
	}

	taucs_free(adj);
	taucs_free(adjptr);
	taucs_free(len);
	taucs_free(leaves);
	taucs_free(degree);

	/*
	 * taucs_printf("taucs_ccs_treeorder: ordering: "); for (i=0; i<n; i++) taucs_printf("%d ",(*perm)[i]);
	 * taucs_printf("\n"); 
	 */

	taucs_printf("taucs_ccs_treeorder: done\n");
}
Exemplo n.º 10
0
static void taucs_ccs_colamd(taucs_ccs_matrix * m, int **perm, int **invperm, char *which)
{
#ifndef TAUCS_CONFIG_COLAMD
	taucs_printf("taucs_ccs_colamd: COLAMD routines not linked.\n");
	*perm = NULL;
	*invperm = NULL;
	return;
#else
	double knobs[COLAMD_KNOBS];
	int Alen;
	int *A;
	int *p;
	int *ip;
	int k, nnz;
	int i;

	if (m->flags & TAUCS_SYMMETRIC || m->flags & TAUCS_HERMITIAN) {
		taucs_printf("taucs_ccs_colamd: not applicable for symmetric or hermitian matrices\n");
		return;
	}

	taucs_printf("taucs_ccs_colamd: starting\n");

	*perm = NULL;
	*invperm = NULL;

	nnz = (m->colptr)[m->n];

	p = (int *) taucs_malloc((m->n + 1) * sizeof(int));
	ip = (int *) taucs_malloc((m->n + 1) * sizeof(int));
	assert(p && ip);

	Alen = colamd_recommended(nnz, m->m, m->n);
	A = taucs_malloc(Alen * sizeof(int));
	assert(A);
	assert(A);
	colamd_set_defaults(knobs);

	for (i = 0; i <= m->n; i++)
		p[i] = (m->colptr)[i];
	for (k = 0; k < nnz; k++)
		A[k] = (m->rowind)[k];

	taucs_printf("oocsp_ccs_colamd: calling colamd matrix is %dx%d, nnz=%d\n", m->m, m->n, nnz);
	if (!colamd(m->m, m->n, Alen, A, p, knobs)) {
		taucs_printf("oocsp_ccs_colamd: colamd failed\n");
		taucs_free(A);
		taucs_free(p);
		return;
	}
	taucs_printf("oocsp_ccs_colamd: colamd returned\n");

	taucs_free(A);

	*perm = p;
	*invperm = ip;

	for (i = 0; i < m->n; i++)
		(*invperm)[(*perm)[i]] = i;
#endif
}
Exemplo n.º 11
0
static void taucs_ccs_genmmd(taucs_ccs_matrix * m, int **perm, int **invperm, char *which)
{
#ifndef TAUCS_CONFIG_GENMMD
	taucs_printf("taucs_ccs_genmmd: GENMMD routines not linked.\n");
	*perm = NULL;
	*invperm = NULL;
	return;
#else
	int n, maxint, delta, nofsub;
	int *xadj;
	int *adjncy;
	int *invp;
	int *prm;
	int *dhead;
	int *qsize;
	int *llist;
	int *marker;

	int *len;
	int *next;

	int nnz, i, j, ip;

	/*
	 * taucs_printf("taucs_ccs_genmmd: starting (%s)\n",which);
	 */

	if (!(m->flags & TAUCS_SYMMETRIC) && !(m->flags & TAUCS_HERMITIAN)) {
		taucs_printf("taucs_ccs_genmmd: GENMMD ordering only works on symmetric matrices.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}
	/*
	 * this routine may actually work on UPPER as well 
	 */
	if (!(m->flags & TAUCS_LOWER)) {
		taucs_printf("taucs_ccs_genmmd: the lower part of the matrix must be represented.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}

	*perm = NULL;
	*invperm = NULL;

	n = m->n;
	nnz = (m->colptr)[n];

	/*
	 * I copied the value of delta and the size of 
	 */
	/*
	 * from SuperLU. Sivan 
	 */

	delta = 1;					       /* DELTA is a parameter to allow the choice of nodes whose degree <= 
							        * min-degree + DELTA. */
	delta = 1;					       /* DELTA is a parameter to allow the choice of nodes whose degree <= 
							        * min-degree + DELTA. */
	/*
	 * maxint = 2147483648;
	 *//*
	 * 2**31-1, for 32-bit only! 
	 */
	maxint = 32000;

	assert(sizeof(int) == 4);
	maxint = 2147483647;				       /* 2**31-1, for 32-bit only! */

	xadj = (int *) taucs_malloc((n + 1) * sizeof(int));
	adjncy = (int *) taucs_malloc((2 * nnz - n) * sizeof(int));
	invp = (int *) taucs_malloc((n + 1) * sizeof(int));
	prm = (int *) taucs_malloc(n * sizeof(int));
	dhead = (int *) taucs_malloc((n + 1) * sizeof(int));
	qsize = (int *) taucs_malloc((n + 1) * sizeof(int));
	llist = (int *) taucs_malloc(n * sizeof(int));
	marker = (int *) taucs_malloc(n * sizeof(int));

	if (!xadj || !adjncy || !invp || !prm || !dhead || !qsize || !llist || !marker) {
		taucs_free(xadj);
		taucs_free(adjncy);
		taucs_free(invp);
		taucs_free(prm);
		taucs_free(dhead);
		taucs_free(qsize);
		taucs_free(llist);
		taucs_free(marker);
		return;
	}

	len = dhead;					       /* we reuse space */
	next = qsize;					       /* we reuse space */

	for (i = 0; i < n; i++)
		len[i] = 0;

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			/*
			 * i = (m->rowind)[ip] - (m->indshift);
			 */
			i = (m->rowind)[ip];
			if (i != j) {
				len[i]++;
				len[j]++;
			} else {
				/*
				 * len[i] ++;
				 */
			}
		}
	}

	xadj[0] = 1;
	for (i = 1; i <= n; i++)
		xadj[i] = xadj[i - 1] + len[i - 1];

	/*
	 * for (i=0; i<=n; i++) printf("xadj[%d]=%d\n",i,xadj[i]);
	 */

	/*
	 * use degree as a temporary 
	 */

	for (i = 0; i < n; i++)
		next[i] = xadj[i] - 1;

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			/*
			 * i = (m->rowind)[ip] - (m->indshift);
			 */
			i = (m->rowind)[ip];
			assert(next[i] < 2 * nnz - n);
			assert(next[j] < 2 * nnz - n);
			if (i != j) {
				adjncy[next[i]] = j + 1;
				adjncy[next[j]] = i + 1;
				next[i]++;
				next[j]++;
			} else {
				/*
				 * adjncy[ next[i] ] = j+1; next[i] ++; 
				 */
			}
		}
	}

	/*
	 * for (j=0; j<n; j++) { qsort(adjncy + (xadj[j] - 1), xadj[j+1] - xadj[j], sizeof(int), compare_ints); printf("+++ %d:
	 * ",j+1); for (ip=xadj[j]-1; ip<xadj[j+1]-1;ip++) printf("%d ",adjncy[ip]); printf("\n"); } 
	 */

	/*
	 * taucs_printf("taucs_ccs_genmmd: calling genmmd, matrix is %dx%d, nnz=%d\n", n,n,nnz); 
	 */

	genmmd_(&n, xadj, adjncy, invp, prm, &delta, dhead, qsize, llist, marker, &maxint, &nofsub);

	/*
	 * taucs_printf("taucs_ccs_genmmd: genmmd returned.\n");
	 */

	/*
	 * { FILE* f; f=fopen("p.ijv","w"); for (i=0; i<n; i++) fprintf(f,"%d %d\n",prm[i],invp[i]); fclose(f); } 
	 */

	taucs_free(marker);
	taucs_free(llist);
	taucs_free(qsize);
	taucs_free(dhead);
	taucs_free(xadj);
	taucs_free(adjncy);

	for (i = 0; i < n; i++)
		prm[i]--;
	for (i = 0; i < n; i++)
		invp[prm[i]] = i;

	*perm = prm;
	*invperm = invp;
#endif
}
Exemplo n.º 12
0
static void taucs_ccs_amd(taucs_ccs_matrix * m, int **perm, int **invperm, char *which)
{
#ifndef TAUCS_CONFIG_AMD
	taucs_printf("taucs_ccs_amd: AMD routines not linked.\n");
	*perm = NULL;
	*invperm = NULL;
	return;
#else
	int n, iwlen, pfree, ncmpa, iovflo;
	int *iw;
	int *pe;
	int *degree;
	int *nv;
	int *next;
	int *last;
	int *head;
	int *elen;
	int *w;
	int *len;

	int nnz, i, j, ip;

	taucs_printf("taucs_ccs_amd: starting (%s)\n", which);

	if (!(m->flags & TAUCS_SYMMETRIC) && !(m->flags & TAUCS_HERMITIAN)) {
		taucs_printf("taucs_ccs_amd: AMD ordering only works on symmetric matrices.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}
	/*
	 * this routine may actually work on UPPER as well 
	 */
	if (!(m->flags & TAUCS_LOWER)) {
		taucs_printf("taucs_ccs_amd: the lower part of the matrix must be represented.\n");
		*perm = NULL;
		*invperm = NULL;
		return;
	}

	*perm = NULL;
	*invperm = NULL;

	n = m->n;
	nnz = (m->colptr)[n];

	pe = (int *) taucs_malloc((n+1) * sizeof(int));
	degree = (int *) taucs_malloc(n * sizeof(int));
	nv = (int *) taucs_malloc(n * sizeof(int));
	next = (int *) taucs_malloc(n * sizeof(int));
	last = (int *) taucs_malloc(n * sizeof(int));
	head = (int *) taucs_malloc(n * sizeof(int));
	elen = (int *) taucs_malloc(n * sizeof(int));
	w = (int *) taucs_malloc(n * sizeof(int));
	len = (int *) taucs_malloc(n * sizeof(int));

	/*
	 * AMD docs recommend iwlen >= 1.2 nnz, but this leads to compressions 
	 */
	iwlen = n + (int) (10.0 * (nnz - n));

	taucs_printf("taucs_ccs_amd: allocating %d ints for iw\n", iwlen);

	iw = (int *) taucs_malloc(iwlen * sizeof(int));

	if (!pe || !degree || !nv || !next || !last || !head || !elen || !w || !len || !iw) {
		taucs_printf("taucs_ccs_amd: out of memory\n");
		taucs_free(pe);
		taucs_free(degree);
		taucs_free(nv);
		taucs_free(next);
		taucs_free(last);
		taucs_free(head);
		taucs_free(elen);
		taucs_free(w);
		taucs_free(len);
		taucs_free(iw);
		return;
	}

	/*
	 * assert(iw && pe && degree && nv && next && last && head && elen && w && len); 
	 */

	int offset;

	if (!strcmp(which, "amdc") || !strcmp(which, "amdbarc")){
		offset = 0;				       /* C */
	} else {
		offset = 1;				       /* Fortran */
	}

	iovflo = INT_MAX;				       /* for 32-bit only! */

	for (i = 0; i < n; i++)
		len[i] = 0;

	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			i = (m->rowind)[ip];
			if (i != j) {
				len[i]++;
				len[j]++;
			}
		}
	}

	pe[0] = offset;
	for (i = 1; i < n; i++)
		pe[i] = pe[i - 1] + len[i - 1];

	pfree = pe[n - 1] + len[n - 1];

	if (offset == 0) {
		pe[n] = pfree;
	}

	/*
	 * use degree as a temporary 
	 */
	for (i = 0; i < n; i++)
		degree[i] = pe[i] - offset;

	
	for (j = 0; j < n; j++) {
		for (ip = (m->colptr)[j]; ip < (m->colptr)[j + 1]; ip++) {
			i = (m->rowind)[ip];
			if (i != j) {
				iw[degree[i]] = j + offset;
				iw[degree[j]] = i + offset;
				degree[i]++;
				degree[j]++;
			}
		}
	}

	taucs_printf("taucs_ccs_amd: calling amd matrix is %dx%d, nnz=%d\n", n, n, nnz);

	if (!strcmp(which, "mmd"))
		amdexa_(&n, pe, iw, len, &iwlen, &pfree, nv, next, last, head, elen, degree, &ncmpa, w, &iovflo);
	else if (!strcmp(which, "md"))
		amdtru_(&n, pe, iw, len, &iwlen, &pfree, nv, next, last, head, elen, degree, &ncmpa, w, &iovflo);
	else if (!strcmp(which, "amdbar"))
		amdbarnew_(&n, pe, iw, len, &iwlen, &pfree, nv, next, last, head, elen, degree, &ncmpa, w);
	else if (!strcmp(which, "amd"))
		amdnew_(&n, pe, iw, len, &iwlen, &pfree, nv, next, last, head, elen, degree, &ncmpa, w);
	else if (!strcmp(which, "amdc"))
		GMRFLib_amdc(n, pe, iw, len, iwlen, pfree, nv, next, last, head, elen, degree, ncmpa, w);
	else if (!strcmp(which, "amdbarc"))
		GMRFLib_amdbarc(n, pe, iw, len, iwlen, pfree, nv, next, last, head, elen, degree, ncmpa, w);
	else {
		taucs_printf("taucs_ccs_amd: WARNING - invalid ordering requested (%s)\n", which);
		return;
	}

	taucs_printf("taucs_ccs_amd: amd returned. optimal iwlen=%d (in this run was %d), %d compressions\n", pfree, iwlen, ncmpa);
	/*
	 * { FILE* f; f=fopen("p.ijv","w"); for (i=0; i<n; i++) fprintf(f,"%d\n",last[i]); fclose(f); } 
	 */

	taucs_free(pe);
	taucs_free(degree);
	taucs_free(nv);
	taucs_free(next);
	/*
	 * free(last ); 
	 */
	taucs_free(head);
	taucs_free(elen);
	taucs_free(w);
	/*
	 * free(len ); 
	 */
	taucs_free(iw);

	for (i = 0; i < n; i++)
		last[i]--;
	for (i = 0; i < n; i++)
		len[last[i]] = i;

	*perm = last;
	*invperm = len;
#endif
}
Exemplo n.º 13
0
taucs_ccs_matrix* 
taucs_dtl(ccs_read_ccs)(char* filename,int flags)
{
  FILE* f;
  taucs_ccs_matrix*  m;

  /*
  int*    clen; 
  int*    is; 
  int*    js;
  taucs_datatype* vs;
  int ncols, nrows, nnz;
  int i,ip,j,k,n;
  */
  /* taucs_datatype dv;*/
  /* double         di,dj;*/

  int i,ip,j,N,*pointers;

  f = fopen(filename ,"r");

  if (f == NULL) {
    taucs_printf("taucs_ccs_read_ccs: could not open ccs file %s\n",filename);
    return NULL;
  }

  fscanf(f,"%d",&N);

  pointers = (int*) taucs_malloc((N+1)*sizeof(int));
  for(i=0; i<N+1; ++i) {
    fscanf(f,"%d",&pointers[i]);
  }

  m = taucs_dtl(ccs_create)(N, N, pointers[N]);
  for (i=0; i<=N; i++) (m->colptr)[i] = pointers[i];

  for(i=0; i<pointers[N]; ++i)
    fscanf(f,"%d",(m->rowind)+i);

#ifdef TAUCS_CORE_DOUBLE  
  for(i=0; i<pointers[N]; ++i)
    fscanf(f,"%lg",(m->taucs_values)+i);
#endif
  
#ifdef TAUCS_CORE_SINGLE  
  for(i=0; i<pointers[N]; ++i)
    fscanf(f,"%g",(m->taucs_values)+i);
#endif
  
#ifdef TAUCS_CORE_DCOMPLEX  
  for(i=0; i<pointers[N]; ++i) {
    taucs_real_datatype dv_r;
    taucs_real_datatype dv_i;
    fscanf(f,"%lg+%lgi",&dv_r,&dv_i);
    (m->taucs_values)[i] = taucs_complex_create(dv_r,dv_i);
  }
#endif
  
#ifdef TAUCS_CORE_SCOMPLEX
  for(i=0; i<pointers[N]; ++i) {
    taucs_real_datatype dv_r;
    taucs_real_datatype dv_i;
    fscanf(f,"%g+%gi",&dv_r,&dv_i);
    (m->taucs_values)[i] = taucs_complex_create(dv_r,dv_i);
  }
#endif
  
  if (flags & TAUCS_SYMMETRIC) {
    m->flags  = TAUCS_SYMMETRIC | TAUCS_LOWER;
    for (j=0; j<N; j++) {
      for (ip=(m->colptr)[j]; ip<(m->colptr)[j+1]; ip++) {
	i = (m->rowind)[ip];
	assert(i >= j);
      }
    }
  } else
    m->flags  = 0;

#ifdef TAUCS_CORE_DOUBLE
  m->flags |= TAUCS_DOUBLE;
#endif

#ifdef TAUCS_CORE_SINGLE
  m->flags |= TAUCS_SINGLE;
#endif

#ifdef TAUCS_CORE_DCOMPLEX
  m->flags |= TAUCS_DCOMPLEX;
#endif

#ifdef TAUCS_CORE_SCOMPLEX
  m->flags |= TAUCS_SCOMPLEX;
#endif

  taucs_free(pointers);
  
  taucs_printf("taucs_ccs_read_ccs: read %s, n=%d\n",filename,m->n);

  return m;
} 
Exemplo n.º 14
0
taucs_ccs_matrix *taucs_dtl(ccs_permute_symmetrically) (taucs_ccs_matrix * A, int *perm, int *invperm) {
	taucs_ccs_matrix *PAPT;
	int n;
	int nnz;

	/*
	 * int* colptr;
	 */
	int *len;
	int i, j, ip, I, J;
	taucs_datatype AIJ;

	assert(A->flags & TAUCS_SYMMETRIC || A->flags & TAUCS_HERMITIAN);
	assert(A->flags & TAUCS_LOWER);

	n = A->n;
	nnz = (A->colptr)[n];

	PAPT = taucs_dtl(ccs_create) (n, n, nnz);
	if (!PAPT)
		return NULL;

	/*
	 * PAPT->flags = TAUCS_SYMMETRIC | TAUCS_LOWER;
	 */
	PAPT->flags = A->flags;

	len = (int *) taucs_malloc(n * sizeof(int));
	/*
	 * colptr = (int*) taucs_malloc(n * sizeof(int));
	 */
	if (!len) {
		taucs_printf("taucs_ccs_permute_symmetrically: out of memory\n");
		taucs_ccs_free(PAPT);
		return NULL;
	}

	for (j = 0; j < n; j++)
		len[j] = 0;

	for (j = 0; j < n; j++) {
		for (ip = (A->colptr)[j]; ip < (A->colptr)[j + 1]; ip++) {
			/*
			 * i = (A->rowind)[ip] - (A->indshift);
			 */
			i = (A->rowind)[ip];

			I = invperm[i];
			J = invperm[j];

			if (I < J) {
				int T = I;

				I = J;
				J = T;
			}

			len[J]++;

		}
	}

	(PAPT->colptr)[0] = 0;
	for (j = 1; j <= n; j++)
		(PAPT->colptr)[j] = (PAPT->colptr)[j - 1] + len[j - 1];

	for (j = 0; j < n; j++)
		len[j] = (PAPT->colptr)[j];

	for (j = 0; j < n; j++) {
		for (ip = (A->colptr)[j]; ip < (A->colptr)[j + 1]; ip++) {
			/*
			 * i = (A->rowind)[ip] - (A->indshift);
			 */
			i = (A->rowind)[ip];
			AIJ = (A->taucs_values)[ip];

			I = invperm[i];
			J = invperm[j];

			if (I < J) {
				int T = I;

				I = J;
				J = T;
				if (A->flags & TAUCS_HERMITIAN)
					AIJ = taucs_conj(AIJ);
			}

			/*
			 * (PAPT->rowind)[ len[J] ] = I + (PAPT->indshift);
			 */
			(PAPT->rowind)[len[J]] = I;
			(PAPT->taucs_values)[len[J]] = AIJ;

			len[J]++;
		}
	}

	taucs_free(len);
	return PAPT;
}
Exemplo n.º 15
0
taucs_ccs_matrix* 
taucs_ccs_read_binary(char* filename)
{
  taucs_ccs_matrix* A = NULL; /* warning*/
  int  nrows,ncols,flags,j;/*nnz, omer*/
  int     f;
  ssize_t bytes_read;
  int*    colptr;

  taucs_printf("taucs_ccs_binary: reading binary matrix %s\n",filename);
  
#ifdef OSTYPE_win32
  f = open(filename,_O_RDONLY |_O_BINARY);
#else
  f = open(filename,O_RDONLY);
#endif
  /*f = open(filename,O_RDONLY);*/

  bytes_read = read(f,&nrows,sizeof(int));
  bytes_read = read(f,&ncols,sizeof(int));
  bytes_read = read(f,&flags,sizeof(int));

  taucs_printf("\t%d-by-%d, flags = %08x\n",nrows,ncols,flags);
  taucs_printf("\t%d-by-%d, flags = %d  \n",nrows,ncols,flags);

  colptr = (int*) taucs_malloc((ncols+1) * sizeof(int));
  assert(colptr);
  
  bytes_read = read(f,colptr,(ncols+1)*sizeof(int));

  taucs_printf("colptr = [");
  for(j=0; j<min(ncols-1,10); j++)
    taucs_printf("%d,",colptr[j]);
  taucs_printf("...,%d]\n",colptr[ncols]);

	if ( 0 ) /* we need this so that we have 'else if' in each type */
	{}
#ifdef TAUCS_DOUBLE_IN_BUILD
  else if (flags & TAUCS_DOUBLE) {
    A = taucs_dccs_create(nrows,ncols,colptr[ncols]);
    if (!A) return NULL;
    bytes_read = read(f,A->rowind,colptr[ncols]*sizeof(int));
    bytes_read = read(f,A->values.d,colptr[ncols]*sizeof(taucs_double));
  }
#endif

#ifdef TAUCS_SINGLE_IN_BUILD
  else if (flags & TAUCS_SINGLE) {
    A = taucs_sccs_create(nrows,ncols,colptr[ncols]);
    if (!A) return NULL;
    bytes_read = read(f,A->rowind,colptr[ncols]*sizeof(int));
    bytes_read = read(f,A->values.s,colptr[ncols]*sizeof(taucs_single));
  }
#endif

#ifdef TAUCS_DCOMPLEX_IN_BUILD
  else if (flags & TAUCS_DCOMPLEX) {
    A = taucs_zccs_create(nrows,ncols,colptr[ncols]);
    if (!A) return NULL;
    bytes_read = read(f,A->rowind,colptr[ncols]*sizeof(int));
    bytes_read = read(f,A->values.z,colptr[ncols]*sizeof(taucs_dcomplex));
  }
#endif

#ifdef TAUCS_SCOMPLEX_IN_BUILD
  else if (flags & TAUCS_SCOMPLEX) {
    A = taucs_cccs_create(nrows,ncols,colptr[ncols]);
    if (!A) return NULL;
    bytes_read = read(f,A->rowind,colptr[ncols]*sizeof(int));
    bytes_read = read(f,A->values.c,colptr[ncols]*sizeof(taucs_scomplex));
  }
#endif
	else {
    assert(0);
  }

  A->flags = flags;
  
  for (j=0; j<=ncols; j++) (A->colptr)[j] = colptr[j];

  taucs_free(colptr);

  close(f);

  taucs_printf("taucs_ccs_read_binary: done reading\n");

  return A;
}
Exemplo n.º 16
0
/* split into left p columns, right p columns */
void taucs_dtl(ccs_split) (taucs_ccs_matrix * A, taucs_ccs_matrix ** L, taucs_ccs_matrix ** R, int p) {
	int i, n;
	int Lnnz, Rnnz;

	assert((A->flags & TAUCS_SYMMETRIC) || (A->flags & TAUCS_TRIANGULAR));
	assert(A->flags & TAUCS_LOWER);

	n = A->n;

	*L = (taucs_ccs_matrix *) taucs_malloc(sizeof(taucs_ccs_matrix));
	*R = (taucs_ccs_matrix *) taucs_malloc(sizeof(taucs_ccs_matrix));
	if (!(*L) || !(*R)) {
		taucs_printf("taucs_ccs_split: out of memory\n");
		taucs_free(*L);
		taucs_free(*R);
		*L = *R = NULL;
		return;
	}

	Lnnz = 0;
	for (i = 0; i < p; i++)
		Lnnz += ((A->colptr)[i + 1] - (A->colptr)[i]);

	(*L)->flags |= TAUCS_SYMMETRIC | TAUCS_LOWER;
	(*L)->n = n;
	(*L)->m = n;
	(*L)->colptr = (int *) taucs_malloc((n + 1) * sizeof(int));
	(*L)->rowind = (int *) taucs_malloc(Lnnz * sizeof(int));
	(*L)->taucs_values = (void *) taucs_malloc(Lnnz * sizeof(taucs_datatype));
	if (!((*L)->colptr) || !((*L)->rowind) || !((*L)->rowind)) {
		taucs_printf("taucs_ccs_split: out of memory: n=%d nnz=%d\n", n, Lnnz);
		taucs_free((*L)->colptr);
		taucs_free((*L)->rowind);
		taucs_free((*L)->taucs_values);
		taucs_free((*L));
		return;
	}

	for (i = 0; i <= p; i++)
		((*L)->colptr)[i] = (A->colptr)[i];
	for (i = p + 1; i < n + 1; i++)
		((*L)->colptr)[i] = ((*L)->colptr)[p];	       /* other columns are empty */

	for (i = 0; i < Lnnz; i++) {
		((*L)->rowind)[i] = (A->rowind)[i];
		((*L)->taucs_values)[i] = (A->taucs_values)[i];
	}

	/*
	 * now copy right part of matrix into a p-by-p matrix 
	 */

	Rnnz = 0;
	for (i = p; i < n; i++)
		Rnnz += ((A->colptr)[i + 1] - (A->colptr)[i]);

	(*R)->flags = TAUCS_SYMMETRIC | TAUCS_LOWER;
	(*R)->n = n - p;
	(*R)->m = n - p;
	(*R)->colptr = (int *) taucs_malloc((n - p + 1) * sizeof(int));
	(*R)->rowind = (int *) taucs_malloc(Rnnz * sizeof(int));
	(*R)->taucs_values = (void *) taucs_malloc(Rnnz * sizeof(taucs_datatype));
	if (!((*R)->colptr) || !((*R)->rowind) || !((*R)->rowind)) {
		taucs_printf("taucs_ccs_split: out of memory (3): p=%d nnz=%d\n", p, Rnnz);
		taucs_free((*R)->colptr);
		taucs_free((*R)->rowind);
		taucs_free((*R)->taucs_values);
		taucs_free((*L)->colptr);
		taucs_free((*L)->rowind);
		taucs_free((*L)->taucs_values);
		taucs_free((*R));
		taucs_free((*L));
		return;
	}

	for (i = 0; i <= (n - p); i++)
		((*R)->colptr)[i] = (A->colptr)[i + p] - Lnnz;

	for (i = 0; i < Rnnz; i++) {
		((*R)->rowind)[i] = (A->rowind)[i + Lnnz] - p;
		((*R)->taucs_values)[i] = (A->taucs_values)[i + Lnnz];
	}
}
Exemplo n.º 17
0
taucs_ccs_matrix *taucs_dtl(ccs_augment_nonpositive_offdiagonals) (taucs_ccs_matrix * A) {
#ifdef TAUCS_CORE_COMPLEX
	assert(0);
#else
	int n, i, j;
	int *tmp;
	taucs_ccs_matrix *A_tmp;

	if (!(A->flags & TAUCS_SYMMETRIC) || !(A->flags & TAUCS_LOWER)) {
		taucs_printf("taucs_ccs_augment_nonpositive_offdiagonal: matrix not symmetric or not lower\n");
		return NULL;
	}

	n = A->n;

	tmp = (int *) taucs_calloc((2 * n + 1), sizeof(int));
	if (!tmp) {
		taucs_printf("taucs_ccs_augment_nonpositive_offdiagonal: out of memory\n");
		return NULL;
	}

	A_tmp = taucs_dtl(ccs_create) (2 * n, 2 * n, 2 * (A->colptr[n]));
	if (A_tmp == NULL) {
		taucs_free(tmp);
		return NULL;
	}
	A_tmp->flags |= TAUCS_SYMMETRIC | TAUCS_LOWER;

	for (i = 0; i < n; i++) {
		for (j = A->colptr[i]; j < A->colptr[i + 1]; j++) {
			if ((i == A->rowind[j]) || (A->taucs_values[j] < 0)) {
				tmp[i]++;
				tmp[i + n]++;
			} else {
				tmp[i]++;
				tmp[A->rowind[j]]++;
			}
		}
	}

	A_tmp->colptr[0] = 0;
	for (i = 0; i < 2 * n; i++)
		A_tmp->colptr[i + 1] = A_tmp->colptr[i] + tmp[i];
	for (i = 0; i < 2 * n; i++)
		tmp[i] = A_tmp->colptr[i];

	for (i = 0; i < n; i++) {
		for (j = A->colptr[i]; j < A->colptr[i + 1]; j++) {
			if ((i == A->rowind[j]) || (A->taucs_values[j] < 0)) {
				A_tmp->rowind[tmp[i]] = A->rowind[j];
				A_tmp->taucs_values[tmp[i]++] = A->taucs_values[j];
				A_tmp->rowind[tmp[i + n]] = A->rowind[j] + n;
				A_tmp->taucs_values[tmp[i + n]++] = A->taucs_values[j];
			} else {
				A_tmp->rowind[tmp[i]] = A->rowind[j] + n;
				A_tmp->taucs_values[tmp[i]++] = -A->taucs_values[j];
				A_tmp->rowind[tmp[A->rowind[j]]] = i + n;
				A_tmp->taucs_values[tmp[A->rowind[j]]++] = -A->taucs_values[j];
			}
		}
	}
	taucs_free(tmp);

	return A_tmp;
#endif
	/*
	 * added omer
	 */
	return NULL;
}
Exemplo n.º 18
0
taucs_ccs_matrix* 
taucs_dtl(ccs_read_mtx)(char* filename,int flags)
{
  FILE* f;
  taucs_ccs_matrix*  m;
  int*    clen; 
  int*    is; 
  int*    js;
  taucs_datatype* vs;
  int ncols, nrows, nnz;
  int i,j,k,n;
  double di,dj;
  taucs_datatype dv;

  f = fopen (filename , "r");

  if (f == NULL) {
    taucs_printf("taucs_ccs_read_mtx: could not open mtx file %s\n",filename);
    return NULL;
  }

  if (fscanf(f, "%d %d %d", &nrows, &ncols, &nnz) != 3) {
    taucs_printf("taucs_ccs_read_mtx: wrong header\n");
    return NULL;
  }

  n = 10000;
  is = (int*)    taucs_malloc(n*sizeof(int));
  js = (int*)    taucs_malloc(n*sizeof(int));
  vs = (taucs_datatype*) taucs_malloc(n*sizeof(taucs_datatype));
  if (!is || !js || !vs) {
    taucs_printf("taucs_ccs_read_mtx: out of memory\n");
    taucs_free(is); taucs_free(js); taucs_free(vs); 
    return NULL; 
  }

  nnz = 0;
  nrows = ncols = 0;
  while (!feof(f)) {
    if (nnz == n) {
      n = (int) ( 1.25 * (double) n);
      taucs_printf("taucs_ccs_read_mtx: allocating %d ijv's\n",n);
      is = (int*)    taucs_realloc(is,n*sizeof(int));
      js = (int*)    taucs_realloc(js,n*sizeof(int));
      vs = (taucs_datatype*) taucs_realloc(vs,n*sizeof(taucs_datatype));
      if (!is || !js || !vs) { 
	taucs_printf("taucs_ccs_read_mtx: out of memory\n");
	taucs_free(is); taucs_free(js); taucs_free(vs); 
	return NULL; 
      }
    }

#ifdef TAUCS_CORE_DOUBLE
    if (fscanf(f, "%lg %lg %lg", &di, &dj, &dv) != 3) break;
#endif

#ifdef TAUCS_CORE_SINGLE
    if (fscanf(f, "%lg %lg %g", &di, &dj, &dv) != 3) break;
#endif

#ifdef TAUCS_CORE_COMPLEX
    {
      taucs_real_datatype dv_i;
      taucs_real_datatype dv_r;
#ifdef TAUCS_CORE_DCOMPLEX
      if (fscanf(f, "%lg %lg %lg+%lgi", &di, &dj, &dv_r,&dv_i) != 4) break;
#endif
#ifdef TAUCS_CORE_SCOMPLEX
      if (fscanf(f, "%lg %lg %g+%gi", &di, &dj, &dv_r,&dv_i) != 4) break;
#endif
      dv = taucs_complex_create(dv_r,dv_i);
    }
#endif

    is[nnz] = (int)di; js[nnz] = (int)dj; vs[nnz] = dv;/*omer*/
    /* upper or lower might be stored, we use lower */
    if ((flags & TAUCS_SYMMETRIC) && is[nnz] < js[nnz]) {
      int t = is[nnz];
      is[nnz] = js[nnz];
      js[nnz] = t;
    }

    if (flags & TAUCS_PATTERN) {
#ifdef TAUCS_CORE_DOUBLE
      if (is[nnz] == js[nnz]) vs[nnz] = (double) (nrows+1);
      else                    vs[nnz] = -1.0;
#endif

#ifdef TAUCS_CORE_SINGLE
      if (is[nnz] == js[nnz]) vs[nnz] = (float) (nrows+1);
      else                    vs[nnz] = -1.0;
#endif

#ifdef TAUCS_CORE_DCOMPEX
      assert(0);
#endif

#ifdef TAUCS_CORE_SCOMPLEX
      assert(0);
#endif
    }
    nrows = max(is[nnz],nrows);
    ncols = max(js[nnz],ncols);
    nnz++;
   }

  fclose ( f );

  m = (taucs_ccs_matrix*) taucs_malloc(sizeof(taucs_ccs_matrix));
  if (!m) { 
    taucs_printf("taucs_ccs_read_mtx: out of memory\n");
    taucs_free(is); taucs_free(js); taucs_free(vs); 
    return NULL; 
  }
  m->n      = nrows;
  m->m      = ncols;
  if (flags & TAUCS_SYMMETRIC) 
    m->flags  = TAUCS_SYMMETRIC | TAUCS_LOWER;
  else
    m->flags  = 0;

#ifdef TAUCS_CORE_DOUBLE
  m->flags |= TAUCS_DOUBLE;
#endif

#ifdef TAUCS_CORE_SINGLE
  m->flags |= TAUCS_SINGLE;
#endif

#ifdef TAUCS_CORE_DCOMPLEX
  m->flags |= TAUCS_DCOMPLEX;
#endif

#ifdef TAUCS_CORE_SCOMPLEX
  m->flags |= TAUCS_SCOMPLEX;
#endif

  clen      = (int*)    taucs_malloc((ncols+1) * sizeof(int));
  m->colptr = (int*)    taucs_malloc((ncols+1) * sizeof(int));
  m->rowind = (int*)    taucs_malloc(nnz       * sizeof(int));
  m->taucs_values = (taucs_datatype*) taucs_malloc(nnz * sizeof(taucs_datatype));
  if (!clen || !(m->colptr) || !(m->rowind) || !(m->rowind)) {
    taucs_printf("taucs_ccs_read_mtx: out of memory: ncols=%d nnz=%d\n",ncols,nnz);
    taucs_free(clen); taucs_free(m->colptr); taucs_free(m->rowind); 
    taucs_free(m->taucs_values);
    taucs_free (m); taucs_free(is); taucs_free(js); taucs_free(vs); 
    return NULL; 
  }

  for (j=0; j<ncols; j++) clen[j] = 0;
  for (k=0; k<nnz; k++) {
    i = is[k] - 1; /* make it 1-based */
    j = js[k] - 1; /* make it 1-based */
    ( clen[j] )++;
  }
  /* just check */
  k = 0;
  for (j=0; j<ncols; j++) 
    k += clen[j];
  assert(k == nnz);

  /* now compute column pointers */
  
  k = 0;
  for (j=0; j<ncols; j++) {
    int tmp;
    tmp =  clen[j];
    clen[j] = (m->colptr[j]) = k;
    k += tmp;
  }
  clen[ncols] = (m->colptr[ncols]) = k;
  assert(clen[ncols] == nnz);
  
  /* now read matrix into data structure */

  for (k=0; k<nnz; k++) {
    i = is[k] - 1; /* make it 1-based */
    j = js[k] - 1; /* make it 1-based */
    assert(i < nrows);
    assert(j < ncols);
    (m->taucs_values)[ clen[j] ] = vs[k];
    (m->rowind)[ clen[j] ] = i;
    clen[j] ++;
  }
  
  taucs_free(clen);
  taucs_free(vs);
  taucs_free(js);
  taucs_free(is);
  
  taucs_printf("taucs_ccs_read_mtx: read %s, n=%d\n",filename,m->n);

  return m;
} 
static void 
taucs_ccs_metis(taucs_ccs_matrix* m, 
		int** perm, int** invperm,
		char* which)
{
#ifndef TAUCS_CONFIG_METIS
  taucs_printf("taucs_ccs_metis: METIS routines not linked.\n");
  *perm    = NULL;
  *invperm = NULL;
  return;
#else
  int  n,nnz,i,j,ip;
  int* xadj;
  int* adj;
  int  num_flag     = 0;
  int  options_flag = 0;
  int* len;
  int* ptr;

  /* taucs_printf("taucs_ccs_metis: starting (%s)\n",which); */

  if (!(m->flags & TAUCS_SYMMETRIC) && !(m->flags & TAUCS_HERMITIAN)) {
    taucs_printf("taucs_ccs_treeorder: METIS ordering only works on symmetric matrices.\n");
    *perm    = NULL;
    *invperm = NULL;
    return;
  }
  /* this routine may actually work on UPPER as well */
  if (!(m->flags & TAUCS_LOWER)) {
    taucs_printf("taucs_ccs_metis: the lower part of the matrix must be represented.\n");
    *perm    = NULL;
    *invperm = NULL;
    return;
  }

  n   = m->n;
  nnz = (m->colptr)[n];
  
  *perm    = (int*) taucs_malloc(n * sizeof(int));
  *invperm = (int*) taucs_malloc(n * sizeof(int));

  xadj = (int*) taucs_malloc((n+1) * sizeof(int));
  /* Change suggested by Yifan Hu for diagonal matrices */
  /* and for matrices with no diagonal */
  /* adj  = (int*) taucs_malloc(2*(nnz-n) * sizeof(int));*/
  adj  = (int*) taucs_malloc(2* nnz * sizeof(int));

  if (!(*perm) || !(*invperm) || !xadj || !adj) {
    taucs_free(*perm);
    taucs_free(*invperm);
    taucs_free(xadj);
    taucs_free(adj);
    *perm = *invperm = NULL;
    return;
  }

  /* assert(*perm && *invperm && xadj && adj);*/

  ptr = len = *perm;

  for (i=0; i<n; i++) len[i] = 0;

  for (j=0; j<n; j++) {
    for (ip = (m->colptr)[j]; ip < (m->colptr)[j+1]; ip++) {
      /*i = (m->rowind)[ip] - (m->indshift);*/
      i = (m->rowind)[ip];
      if (i != j) {
	len[i] ++;
	len[j] ++;
      }
    }
  }

  xadj[0] = 0;
  for (i=1; i<=n; i++) xadj[i] = xadj[i-1] + len[i-1];
  
  for (i=0; i<n; i++) ptr[i] = xadj[i];

  for (j=0; j<n; j++) {
    for (ip = (m->colptr)[j]; ip < (m->colptr)[j+1]; ip++) {
      /*i = (m->rowind)[ip] - (m->indshift);*/
      i = (m->rowind)[ip];
      if (i != j) {
	adj[ ptr[i] ] = j;
	adj[ ptr[j] ] = i;
	ptr[i] ++;
	ptr[j] ++;
      }
    }
  }

  /* taucs_printf("taucs_ccs_metis: calling metis matrix is %dx%d, nnz=%d\n", */
	     /* n,n,nnz); */

  METIS_NodeND(&n,
	       xadj,adj,
	       &num_flag, &options_flag,
	       *perm,*invperm);

  /* taucs_printf("taucs_ccs_metis: metis returned\n"); */

  /*
  {
    FILE* f;
    f=fopen("p.ijv","w");
    for (i=0; i<n; i++) fprintf(f,"%d\n",last[i]);
    fclose(f);
  }
  */

  taucs_free(xadj);
  taucs_free(adj);
#endif
}