[Trilinos-Users] Re: multiply two Epetra_CrsMatrix and get
back the diagonal
Kurt Stokbro
kurt.stokbro at gmail.com
Tue Oct 30 12:23:55 MDT 2007
Hi Michael,
One of the matrixes is symmetric, so I have implemented the attached
routine, that works in seriel. I was wondering if there is a routine
that works in parallel and that is more optimal.
Regards,
Kurt
On 10/30/07, Michael A Heroux <maherou at sandia.gov> wrote:
> Kurt,
>
> Given the row bias of Epetra_CrsMatrix, going down the columns of b is a bit
> tricky. There are two basic approaches:
>
> - Transpose b all at once. This would be most time-efficient, but take
> extra memory at least temporarily.
> - Grab a column of b at a time. This would be most space efficient, but
> take more time.
>
> Do you have a sense of which is most acceptable?
>
> Mike
>
>
> On 10/29/07 2:19 PM, "Kurt Stokbro" <kurt.stokbro at gmail.com> wrote:
>
> > I need a subroutine that can
> > Epetra_Vector multiplyDiag(Epetra_CrsMatrix& a, Epetra_CrsMatrix& b)
> > {
> > for(int j=0;j<a.numRows;j++)
> > {
> > v(j)=0.0
> > for(int i=0;i<a.numCols;i++)
> > v(j)+=a(j,i)*b(i,j)
> > }
> > return v
> > }
> >
> > Does anybody have an efficient routine for this?
> > Thanks,
> > Kurt Stokbro
> >
> > _______________________________________________
> > Trilinos-Users mailing list
> > Trilinos-Users at software.sandia.gov
> > http://software.sandia.gov/mailman/listinfo/trilinos-users
>
>
>
-------------- next part --------------
typedef Teuchos::SerialDenseVector<int,double> TVector;
TVector multiplyDiag( Epetra_CrsMatrix & G, Epetra_CrsMatrix & S)
{
int numOrb= G.NumGlobalRows();
int MaxNumIndicesG = G.MaxNumEntries();
int extractedNumEntriesG;
int * extractedIndicesG = new int[MaxNumIndicesG];
double * extractedValuesG = new double[MaxNumIndicesG];
int MaxNumIndicesS = S.MaxNumEntries();
int extractedNumEntriesS;
int * extractedIndicesS = new int[MaxNumIndicesS];
double * extractedValuesS = new double[MaxNumIndicesS];
TVector diag(numOrb) ;
if(G.NumGlobalNonzeros()==S.NumGlobalNonzeros())
{
for(int i=0;i<numOrb;i++)
{
int err = G.ExtractGlobalRowCopy(
i, // input
MaxNumIndicesG, //
extractedNumEntriesG, // output
extractedValuesG, // output
extractedIndicesG); // output
assert(err == 0);
err = S.ExtractGlobalRowCopy(
i, // input
MaxNumIndicesS, //
extractedNumEntriesS, // output
extractedValuesS, // output
extractedIndicesS); // output
assert(err == 0);
for(int j= 0; j < extractedNumEntriesG; j++)
diag(i)+=extractedValuesG[j]*extractedValuesS[j];
}
}
else
{
for(int i=0;i<numOrb;i++)
{
int err = G.ExtractGlobalRowCopy(
i, // input
MaxNumIndicesG, //
extractedNumEntriesG, // output
extractedValuesG, // output
extractedIndicesG); // output
assert(err == 0);
err = S.ExtractGlobalRowCopy(
i, // input
MaxNumIndicesS, //
extractedNumEntriesS, // output
extractedValuesS, // output
extractedIndicesS); // output
assert(err == 0);
int jS=0;
for(int jG = 0; jG < extractedNumEntriesG; jG++)
{
int jiG = extractedIndicesG[jG];
while(extractedIndicesS[jS]<jiG && jS<extractedNumEntriesS-1)
jS++;
if (extractedIndicesS[jS]==jiG )
diag(i)+=extractedValuesG[jG]*extractedValuesS[jS];
}
}
}
delete [] extractedIndicesG;
delete [] extractedValuesG;
delete [] extractedIndicesS;
delete [] extractedValuesS;
return diag;
}
More information about the Trilinos-Users
mailing list