55 Epetra_FastCrsMatrix::Epetra_FastCrsMatrix(
const Epetra_CrsMatrix & Matrix,
bool UseFloats)
58 NumMyRows_(Matrix.NumMyRows()),
59 NumMyNonzeros(Matrix.NumMyNonzeros()),
64 if (!CrsMatrix_.Filled())
throw CrsMatrix_.ReportError(
"Input matrix must have called FillComplete()", -1);
69 Epetra_FastCrsMatrix::~Epetra_FastCrsMatrix(){
71 if (Values_!=0 && ValuesAllocated_)
delete [] Values_;
72 if (FloatValues_!=0)
delete [] FloatValues_;
73 if (Indices_!=0)
delete [] Indices_;
74 if (ShortIndices_!=0)
delete [] ShortIndices_;
76 if (ImportVector_!=0)
delete ImportVector_;
78 if (ExportVector_!=0)
delete ExportVector_;
87 int Epetra_FastCrsMatrix::Allocate(
bool UseFloats) {
97 if (CrsMatrix.IndicesAreContiguous() && !UseFloats) {
98 ValuesAllocated_ =
false;
99 Values_ = CrsMatrix_[0];
101 else if (!UseFloats) {
103 Values_ =
new double[NumMyNonzeros_];
104 double * ptr = Values_;
105 for (i=0; i<NumMyRows_; i++) {
106 int NumEntries = CrsMatrix_.NumMyEntries(i);
107 double * rowi = CrsMatrix_[i];
108 for (j=0; j< NumEntries; j++) *ptr++ = *rowi++;
112 FloatValues_ =
new float[NumMyNonzeros_];
113 float * ptr = FloatValues_;
114 for (i=0; i<NumMyRows_; i++) {
115 int NumEntries = CrsMatrix_.NumMyEntries(i);
116 double * rowi = CrsMatrix_[i];
117 for (j=0; j< NumEntries; j++) *ptr++ = (
float) *rowi++;
126 if (CrsMatrix_.NumMyCols()>USHRT_MAX) {
128 Indices_ =
new int[NumMyNonzeros_+NumMyRows_];
129 int * ptr = Indices_;
130 for (i=0; i<NumMyRows_; i++) {
131 int NumEntries = CrsMatrix_.NumMyEntries(i);
132 int * rowi = CrsMatrix_.Graph()[i];
134 for (j=0; j< NumEntries; j++) *ptr++ = *rowi++;
138 ShortIndices_ =
new unsigned short[NumMyNonzeros_+NumMyRows_];
139 unsigned short * ptr = ShortIndices_;
140 for (i=0; i<NumMyRows_; i++) {
141 int NumEntries = CrsMatrix_.NumMyEntries(i);
142 unsigned short * rowi = CrsMatrix_Graph()[i];
144 for (j=0; j< NumEntries; j++) *ptr++ = (
unsigned short) *rowi++;
157 double * xp = (
double*)x.
Values();
158 double *yp = (
double*)y.
Values();
159 int NumMyCols_ = NumMyCols();
166 if (ImportVector_!=0) {
167 if (ImportVector_->NumVectors()!=1) {
delete ImportVector_; ImportVector_= 0;}
170 ImportVector_->Import(x, *Importer(),
Insert);
171 xp = (
double*)ImportVector_->Values();
176 if (ExportVector_!=0) {
177 if (ExportVector_->NumVectors()!=1) {
delete ExportVector_; ExportVector_= 0;}
180 yp = (
double*)ExportVector_->Values();
185 for (i=0; i < NumMyRows_; i++) {
186 int NumEntries = *NumEntriesPerRow++;
187 int * RowIndices = *Indices++;
188 double * RowValues = *Values++;
190 for (j=0; j < NumEntries; j++) sum += RowValues[j] * xp[RowIndices[j]];
195 if (Exporter()!=0) y.
Export(*ExportVector_, *Exporter(),
Add);
204 if (ExportVector_!=0) {
205 if (ExportVector_->NumVectors()!=1) {
delete ExportVector_; ExportVector_= 0;}
208 ExportVector_->Import(x, *Exporter(),
Insert);
209 xp = (
double*)ExportVector_->Values();
214 if (ImportVector_!=0) {
215 if (ImportVector_->NumVectors()!=1) {
delete ImportVector_; ImportVector_= 0;}
218 yp = (
double*)ImportVector_->Values();
223 for (i=0; i < NumMyCols_; i++) yp[i] = 0.0;
225 for (i=0; i < NumMyRows_; i++) {
226 int NumEntries = *NumEntriesPerRow++;
227 int * RowIndices = *Indices++;
228 double * RowValues = *Values++;
229 for (j=0; j < NumEntries; j++) yp[RowIndices[j]] += RowValues[j] * xp[i];
231 if (Importer()!=0) y.
Export(*ImportVector_, *Importer(),
Add);
234 UpdateFlops(2*NumGlobalNonzeros64());
244 double * xp = (
double *) X[0];
245 double * yp = (
double *) Y[0];
248 return(Multiply(TransA, x, y));
253 int * NumEntriesPerRow = NumEntriesPerRow_;
254 int ** Indices = Indices_;
255 double ** Values = Values_;
257 double **Xp = (
double**)X.
Pointers();
258 double **Yp = (
double**)Y.
Pointers();
261 int NumMyCols_ = NumMyCols();
273 if (ImportVector_!=0) {
274 if (ImportVector_->NumVectors()!=NumVectors) {
delete ImportVector_; ImportVector_= 0;}
277 ImportVector_->Import(X, *Importer(),
Insert);
278 Xp = (
double**)ImportVector_->Pointers();
283 if (ExportVector_!=0) {
284 if (ExportVector_->NumVectors()!=NumVectors) {
delete ExportVector_; ExportVector_= 0;}
287 Yp = (
double**)ExportVector_->Pointers();
292 for (i=0; i < NumMyRows_; i++) {
293 int NumEntries = *NumEntriesPerRow++;
294 int * RowIndices = *Indices++;
295 double * RowValues = *Values++;
296 for (k=0; k<NumVectors; k++) {
298 for (j=0; j < NumEntries; j++) sum += RowValues[j] * Xp[k][RowIndices[j]];
302 if (Exporter()!=0) Y.
Export(*ExportVector_, *Exporter(),
Add);
310 if (ExportVector_!=0) {
311 if (ExportVector_->NumVectors()!=NumVectors) {
delete ExportVector_; ExportVector_= 0;}
314 ExportVector_->Import(X, *Exporter(),
Insert);
315 Xp = (
double**)ExportVector_->Pointers();
320 if (ImportVector_!=0) {
321 if (ImportVector_->NumVectors()!=NumVectors) {
delete ImportVector_; ImportVector_= 0;}
324 Yp = (
double**)ImportVector_->Pointers();
331 for (k=0; k<NumVectors; k++)
332 for (i=0; i < NumMyCols_; i++) Yp[k][i] = 0.0;
334 for (i=0; i < NumMyRows_; i++) {
335 int NumEntries = *NumEntriesPerRow++;
336 int * RowIndices = *Indices++;
337 double * RowValues = *Values++;
338 for (k=0; k<NumVectors; k++) {
339 for (j=0; j < NumEntries; j++) Yp[k][RowIndices[j]] += RowValues[j] * Xp[k][i];
342 if (Importer()!=0) Y.
Export(*ImportVector_, *Importer(),
Add);
345 UpdateFlops(2*NumVectors*NumGlobalNonzeros64());
360 if ((!UnitDiagonal) && (NumMyDiagonals()<NumMyRows_))
EPETRA_CHK_ERR(-5);
364 int * NumEntriesPerRow = NumEntriesPerRow_;
365 int ** Indices = Indices_;
366 double ** Values = Values_;
367 int NumMyCols_ = NumMyCols();
370 if ((Upper && !Trans) || (!Upper && Trans)) {
371 NumEntriesPerRow += NumMyRows_-1;
372 Indices += NumMyRows_-1;
373 Values += NumMyRows_-1;
376 double *xp = (
double*)x.
Values();
377 double *yp = (
double*)y.
Values();
384 if (NoDiagonal()) j0--;
385 for (i=NumMyRows_-1; i >=0; i--) {
386 int NumEntries = *NumEntriesPerRow--;
387 int * RowIndices = *Indices--;
388 double * RowValues = *Values--;
390 for (j=j0; j < NumEntries; j++) sum += RowValues[j] * yp[RowIndices[j]];
392 if (UnitDiagonal) yp[i] = xp[i] - sum;
393 else yp[i] = (xp[i] - sum)/RowValues[0];
399 if (NoDiagonal()) j0--;
400 for (i=0; i < NumMyRows_; i++) {
401 int NumEntries = *NumEntriesPerRow++ - j0;
402 int * RowIndices = *Indices++;
403 double * RowValues = *Values++;
405 for (j=0; j < NumEntries; j++) sum += RowValues[j] * yp[RowIndices[j]];
407 if (UnitDiagonal) yp[i] = xp[i] - sum;
408 else yp[i] = (xp[i] - sum)/RowValues[NumEntries];
418 if (xp!=yp)
for (i=0; i < NumMyCols_; i++) yp[i] = xp[i];
423 if (NoDiagonal()) j0--;
425 for (i=0; i < NumMyRows_; i++) {
426 int NumEntries = *NumEntriesPerRow++;
427 int * RowIndices = *Indices++;
428 double * RowValues = *Values++;
429 if (!UnitDiagonal) yp[i] = yp[i]/RowValues[0];
430 for (j=j0; j < NumEntries; j++) yp[RowIndices[j]] -= RowValues[j] * yp[i];
436 if (NoDiagonal()) j0--;
438 for (i=NumMyRows_-1; i >= 0; i--) {
439 int NumEntries = *NumEntriesPerRow-- - j0;
440 int * RowIndices = *Indices--;
441 double * RowValues = *Values--;
442 if (!UnitDiagonal) yp[i] = yp[i]/RowValues[NumEntries];
443 for (j=0; j < NumEntries; j++) yp[RowIndices[j]] -= RowValues[j] * yp[i];
448 UpdateFlops(2*NumGlobalNonzeros64());
458 double * xp = (
double *) X[0];
459 double * yp = (
double *) Y[0];
462 return(
Solve(Upper, Trans, UnitDiagonal, x, y));
469 if ((!UnitDiagonal) && (NumMyDiagonals()<NumMyRows_))
EPETRA_CHK_ERR(-5);
472 int * NumEntriesPerRow = NumEntriesPerRow_;
473 int ** Indices = Indices_;
474 double ** Values = Values_;
478 if ((Upper && !Trans) || (!Upper && Trans)) {
479 NumEntriesPerRow += NumMyRows_-1;
480 Indices += NumMyRows_-1;
481 Values += NumMyRows_-1;
484 double **Xp = (
double**)X.
Pointers();
485 double **Yp = (
double**)Y.
Pointers();
495 if (NoDiagonal()) j0--;
496 for (i=NumMyRows_-1; i >=0; i--) {
497 int NumEntries = *NumEntriesPerRow--;
498 int * RowIndices = *Indices--;
499 double * RowValues = *Values--;
500 if (!UnitDiagonal) diag = 1.0/RowValues[0];
501 for (k=0; k<NumVectors; k++) {
503 for (j=j0; j < NumEntries; j++) sum += RowValues[j] * Yp[k][RowIndices[j]];
505 if (UnitDiagonal) Yp[k][i] = Xp[k][i] - sum;
506 else Yp[k][i] = (Xp[k][i] - sum)*diag;
512 if (NoDiagonal()) j0--;
513 for (i=0; i < NumMyRows_; i++) {
514 int NumEntries = *NumEntriesPerRow++ - j0;
515 int * RowIndices = *Indices++;
516 double * RowValues = *Values++;
517 if (!UnitDiagonal) diag = 1.0/RowValues[NumEntries];
518 for (k=0; k<NumVectors; k++) {
520 for (j=0; j < NumEntries; j++) sum += RowValues[j] * Yp[k][RowIndices[j]];
522 if (UnitDiagonal) Yp[k][i] = Xp[k][i] - sum;
523 else Yp[k][i] = (Xp[k][i] - sum)*diag;
532 for (k=0; k<NumVectors; k++)
533 if (Yp[k]!=Xp[k])
for (i=0; i < NumMyRows_; i++) Yp[k][i] = Xp[k][i];
538 if (NoDiagonal()) j0--;
540 for (i=0; i < NumMyRows_; i++) {
541 int NumEntries = *NumEntriesPerRow++;
542 int * RowIndices = *Indices++;
543 double * RowValues = *Values++;
544 if (!UnitDiagonal) diag = 1.0/RowValues[j0];
545 for (k=0; k<NumVectors; k++) {
546 if (!UnitDiagonal) Yp[k][i] = Yp[k][i]*diag;
547 for (j=j0; j < NumEntries; j++) Yp[k][RowIndices[j]] -= RowValues[j] * Yp[k][i];
554 if (NoDiagonal()) j0--;
556 for (i=NumMyRows_-1; i>=0; i--) {
557 int NumEntries = *NumEntriesPerRow-- - j0;
558 int * RowIndices = *Indices--;
559 double * RowValues = *Values--;
560 for (k=0; k<NumVectors; k++) {
561 if (!UnitDiagonal) Yp[k][i] = Yp[k][i]/Xp[k][i];
562 for (j=0; j < NumEntries; j++) Yp[k][RowIndices[j]] -= RowValues[j] * Yp[k][i];
568 UpdateFlops(2*NumVectors*NumGlobalNonzeros64());
Epetra_MultiVector: A class for constructing and using dense multi-vectors, vectors and matrices in p...
double ** Pointers() const
Get pointer to individual vector pointers.
#define EPETRA_CHK_ERR(a)
Epetra_Vector: A class for constructing and using dense vectors on a parallel computer.
int NumVectors() const
Returns the number of vectors in the multi-vector.
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
Exports an Epetra_DistObject using the Epetra_Import object.
double * Values() const
Get pointer to MultiVector values.
Epetra_CrsMatrix: A class for constructing and using real-valued double-precision sparse compressed r...
int Solve(int, TYPE *, TYPE *, TYPE *)
const Epetra_BlockMap & Map() const
Returns the address of the Epetra_BlockMap for this multi-vector.