Actual source code: aijsbaij.c

  1: /*$Id: aijsbaij.c,v 1.9 2001/08/07 03:02:55 balay Exp $*/

 3:  #include src/mat/impls/aij/seq/aij.h
 4:  #include src/mat/impls/baij/seq/baij.h
 5:  #include src/mat/impls/sbaij/seq/sbaij.h

  7: EXTERN_C_BEGIN
 10: int MatConvert_SeqSBAIJ_SeqAIJ(Mat A,const MatType newtype,Mat *newmat)
 11: {
 12:   Mat          B;
 13:   Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data;
 14:   Mat_SeqAIJ   *b;
 15:   int          ierr,*ai=a->i,*aj=a->j,m=A->m,n=A->n,i,j,k,*bi,*bj,
 16:                *rowlengths,nz,*rowstart,itmp;
 17:   int          bs=a->bs,bs2=bs*bs,mbs=A->m/bs;
 18:   PetscScalar  *av,*bv;


 22:   /* compute rowlengths of newmat */
 23:   PetscMalloc((2*m+1)*sizeof(int),&rowlengths);
 24:   rowstart = rowlengths + m;
 25: 
 26:   for (i=0; i<mbs; i++) rowlengths[i*bs] = 0;
 27:   aj = a->j;
 28:   k = 0;
 29:   for (i=0; i<mbs; i++) {
 30:     nz = ai[i+1] - ai[i];
 31:     aj++; /* skip diagonal */
 32:     for (j=1; j<nz; j++) { /* no. of lower triangular blocks */
 33:       rowlengths[(*aj)*bs]++; aj++;
 34:     }
 35:     rowlengths[k] += nz;   /* no. of upper triangular blocks */
 36:     rowlengths[k] *= bs;
 37:     for (j=1; j<bs; j++) {
 38:       rowlengths[k+j] = rowlengths[k];
 39:     }
 40:     k += bs;
 41:     /* printf(" rowlengths[%d]: %d\n",i, rowlengths[i]); */
 42:   }
 43: 
 44:   MatCreate(A->comm,m,n,m,n,&B);
 45:   MatSetType(B,newtype);
 46:   MatSeqAIJSetPreallocation(B,0,rowlengths);
 47:   MatSetOption(B,MAT_COLUMN_ORIENTED);
 48:   MatSetOption(B,MAT_ROWS_SORTED);
 49:   MatSetOption(B,MAT_COLUMNS_SORTED);
 50: 
 51:   b  = (Mat_SeqAIJ*)(B->data);
 52:   bi = b->i;
 53:   bj = b->j;
 54:   bv = b->a;

 56:   /* set b->i */
 57:   bi[0] = 0; rowstart[0] = 0;
 58:   for (i=0; i<mbs; i++){
 59:     for (j=0; j<bs; j++){
 60:       b->ilen[i*bs+j]  = rowlengths[i*bs];
 61:       rowstart[i*bs+j+1] = rowstart[i*bs+j] + rowlengths[i*bs];
 62:     }
 63:     bi[i+1]     = bi[i] + rowlengths[i*bs]/bs;
 64:   }
 65:   if (bi[mbs] != 2*a->nz - mbs) SETERRQ2(1,"bi[mbs]: %d != 2*a->nz-mbs: %d\n",bi[mbs],2*a->nz - mbs);

 67:   /* set b->j and b->a */
 68:   aj = a->j; av = a->a;
 69:   for (i=0; i<mbs; i++) {
 70:     /* diagonal block */
 71:     for (j=0; j<bs; j++){   /* row i*bs+j */
 72:       itmp = i*bs+j;
 73:       for (k=0; k<bs; k++){ /* col i*bs+k */
 74:         *(bj + rowstart[itmp]) = (*aj)*bs+k;
 75:         *(bv + rowstart[itmp]) = *(av+k*bs+j);
 76:         rowstart[itmp]++;
 77:       }
 78:     }
 79:     aj++; av += bs2;
 80: 
 81:     nz = ai[i+1] - ai[i] -1;
 82:     while (nz--){
 83:       /* lower triangular blocks */
 84:       for (j=0; j<bs; j++){   /* row (*aj)*bs+j */
 85:         itmp = (*aj)*bs+j;
 86:         for (k=0; k<bs; k++){ /* col i*bs+k */
 87:           *(bj + rowstart[itmp]) = i*bs+k;
 88:           *(bv + rowstart[itmp]) = *(av+k*bs+j);
 89:           rowstart[itmp]++;
 90:         }
 91:       }
 92:       /* upper triangular blocks */
 93:       for (j=0; j<bs; j++){   /* row i*bs+j */
 94:         itmp = i*bs+j;
 95:         for (k=0; k<bs; k++){ /* col (*aj)*bs+k */
 96:           *(bj + rowstart[itmp]) = (*aj)*bs+k;
 97:           *(bv + rowstart[itmp]) = *(av+k*bs+j);
 98:           rowstart[itmp]++;
 99:         }
100:       }
101:       aj++; av += bs2;
102:     }
103:   }
104:   PetscFree(rowlengths);
105:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
106:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

108:   /* Fake support for "inplace" convert. */
109:   if (*newmat == A) {
110:     MatDestroy(A);
111:   }
112:   *newmat = B;
113:   return(0);
114: }
117: int MatConvert_SeqAIJ_SeqSBAIJ(Mat A,const MatType newtype,Mat *newmat) {
118:   Mat          B;
119:   Mat_SeqAIJ   *a = (Mat_SeqAIJ*)A->data;
120:   Mat_SeqSBAIJ *b;
121:   int          ierr,*ai=a->i,*aj,m=A->M,n=A->N,i,j,
122:                *bi,*bj,*rowlengths;
123:   PetscScalar  *av,*bv;

126:   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
127:   MatMissingDiagonal_SeqAIJ(A); /* check for missing diagonals, then mark diag */

129:   PetscMalloc(m*sizeof(int),&rowlengths);
130:   for (i=0; i<m; i++) {
131:     rowlengths[i] = ai[i+1] - a->diag[i];
132:   }
133:   MatCreate(A->comm,m,n,m,n,&B);
134:   MatSetType(B,newtype);
135:   MatSeqSBAIJSetPreallocation(B,1,0,rowlengths);

137:   MatSetOption(B,MAT_ROW_ORIENTED);
138:   MatSetOption(B,MAT_ROWS_SORTED);
139:   MatSetOption(B,MAT_COLUMNS_SORTED);
140: 
141:   b  = (Mat_SeqSBAIJ*)(B->data);
142:   bi = b->i;
143:   bj = b->j;
144:   bv = b->a;

146:   bi[0] = 0;
147:   for (i=0; i<m; i++) {
148:     aj = a->j + a->diag[i];
149:     av = a->a + a->diag[i];
150:     for (j=0; j<rowlengths[i]; j++){
151:       *bj = *aj; bj++; aj++;
152:       *bv = *av; bv++; av++;
153:     }
154:     bi[i+1]    = bi[i] + rowlengths[i];
155:     b->ilen[i] = rowlengths[i];
156:   }
157: 
158:   PetscFree(rowlengths);
159:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
160:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

162:   /* Fake support for "inplace" convert. */
163:   if (*newmat == A) {
164:     MatDestroy(A);
165:   }
166:   *newmat = B;

168:   return(0);
169: }
170: EXTERN_C_END

172: EXTERN_C_BEGIN
175: int MatConvert_SeqSBAIJ_SeqBAIJ(Mat A,const MatType newtype,Mat *newmat)
176: {
177:   Mat          B;
178:   Mat_SeqSBAIJ *a = (Mat_SeqSBAIJ*)A->data;
179:   Mat_SeqBAIJ  *b;
180:   int          ierr,*ai=a->i,*aj=a->j,m=A->m,n=A->n,i,k,*bi,*bj,
181:                *browlengths,nz,*browstart,itmp;
182:   int          bs=a->bs,bs2=bs*bs,mbs=m/bs;
183:   PetscScalar  *av,*bv;

186:   /* compute browlengths of newmat */
187:   PetscMalloc(2*mbs*sizeof(int),&browlengths);
188:   browstart = browlengths + mbs;
189:   for (i=0; i<mbs; i++) browlengths[i] = 0;
190:   aj = a->j;
191:   for (i=0; i<mbs; i++) {
192:     nz = ai[i+1] - ai[i];
193:     aj++; /* skip diagonal */
194:     for (k=1; k<nz; k++) { /* no. of lower triangular blocks */
195:       browlengths[*aj]++; aj++;
196:     }
197:     browlengths[i] += nz;   /* no. of upper triangular blocks */
198:   }
199: 
200:   MatCreate(A->comm,m,n,m,n,&B);
201:   MatSetType(B,newtype);
202:   MatSeqBAIJSetPreallocation(B,bs,0,browlengths);
203:   MatSetOption(B,MAT_ROW_ORIENTED);
204:   MatSetOption(B,MAT_ROWS_SORTED);
205:   MatSetOption(B,MAT_COLUMNS_SORTED);
206: 
207:   b  = (Mat_SeqBAIJ*)(B->data);
208:   bi = b->i;
209:   bj = b->j;
210:   bv = b->a;

212:   /* set b->i */
213:   bi[0] = 0;
214:   for (i=0; i<mbs; i++){
215:     b->ilen[i]    = browlengths[i];
216:     bi[i+1]       = bi[i] + browlengths[i];
217:     browstart[i]  = bi[i];
218:   }
219:   if (bi[mbs] != 2*a->nz - mbs) SETERRQ2(1,"bi[mbs]: %d != 2*a->nz - mbs: %d\n",bi[mbs],2*a->nz - mbs);
220: 
221:   /* set b->j and b->a */
222:   aj = a->j; av = a->a;
223:   for (i=0; i<mbs; i++) {
224:     /* diagonal block */
225:     *(bj + browstart[i]) = *aj; aj++;
226:     itmp = bs2*browstart[i];
227:     for (k=0; k<bs2; k++){
228:       *(bv + itmp + k) = *av; av++;
229:     }
230:     browstart[i]++;
231: 
232:     nz = ai[i+1] - ai[i] -1;
233:     while (nz--){
234:       /* lower triangular blocks */
235:       *(bj + browstart[*aj]) = i;
236:       itmp = bs2*browstart[*aj];
237:       for (k=0; k<bs2; k++){
238:         *(bv + itmp + k) = *(av + k);
239:       }
240:       browstart[*aj]++;

242:       /* upper triangular blocks */
243:       *(bj + browstart[i]) = *aj; aj++;
244:       itmp = bs2*browstart[i];
245:       for (k=0; k<bs2; k++){
246:         *(bv + itmp + k) = *av; av++;
247:       }
248:       browstart[i]++;
249:     }
250:   }
251:   PetscFree(browlengths);
252:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
253:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

255:   /* Fake support for "inplace" convert. */
256:   if (*newmat == A) {
257:     MatDestroy(A);
258:   }
259:   *newmat = B;
260:   return(0);
261: }
264: int MatConvert_SeqBAIJ_SeqSBAIJ(Mat A,const MatType newtype,Mat *newmat)
265: {
266:   Mat          B;
267:   Mat_SeqBAIJ  *a = (Mat_SeqBAIJ*)A->data;
268:   Mat_SeqSBAIJ *b;
269:   int          ierr,*ai=a->i,*aj,m=A->m,n=A->n,i,j,k,
270:                *bi,*bj,*browlengths;
271:   int          bs=a->bs,bs2=bs*bs,mbs=m/bs;
272:   PetscScalar  *av,*bv;

275:   if (n != m) SETERRQ(PETSC_ERR_ARG_WRONG,"Matrix must be square");
276:   MatMissingDiagonal_SeqBAIJ(A); /* check for missing diagonals, then mark diag */
277: 
278:   PetscMalloc(mbs*sizeof(int),&browlengths);
279:   for (i=0; i<mbs; i++) {
280:     browlengths[i] = ai[i+1] - a->diag[i];
281:   }

283:   MatCreate(A->comm,m,n,m,n,&B);
284:   MatSetType(B,newtype);
285:   MatSeqSBAIJSetPreallocation(B,bs,0,browlengths);
286:   MatSetOption(B,MAT_ROW_ORIENTED);
287:   MatSetOption(B,MAT_ROWS_SORTED);
288:   MatSetOption(B,MAT_COLUMNS_SORTED);
289: 
290:   b  = (Mat_SeqSBAIJ*)(B->data);
291:   bi = b->i;
292:   bj = b->j;
293:   bv = b->a;

295:   bi[0] = 0;
296:   for (i=0; i<mbs; i++) {
297:     aj = a->j + a->diag[i];
298:     av = a->a + (a->diag[i])*bs2;
299:     for (j=0; j<browlengths[i]; j++){
300:       *bj = *aj; bj++; aj++;
301:       for (k=0; k<bs2; k++){
302:         *bv = *av; bv++; av++;
303:       }
304:     }
305:     bi[i+1]    = bi[i] + browlengths[i];
306:     b->ilen[i] = browlengths[i];
307:   }
308:   PetscFree(browlengths);
309:   MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
310:   MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);

312:   /* Fake support for "inplace" convert. */
313:   if (*newmat == A) {
314:     MatDestroy(A);
315:   }
316:   *newmat = B;

318:   return(0);
319: }
320: EXTERN_C_END