Pierre,
Our MatProductReplaceMats() is not well tested, which might be buggy. I 
simplified your code without calling MatProductReplaceMats() and got correct 
results in the cases
./ex1111 -product_view ::ascii_matlab -convert false/true -correct false
and
./ex1111 -product_view ::ascii_matlab -convert false/true -correct true

My code is attached. I'll investigate MatProductReplaceMats().
Hong




________________________________
From: petsc-dev <petsc-dev-boun...@mcs.anl.gov> on behalf of Barry Smith 
<bsm...@petsc.dev>
Sent: Thursday, July 14, 2022 4:38 PM
To: Pierre Jolivet <pie...@joliv.et>
Cc: For users of the development version of PETSc <petsc-dev@mcs.anl.gov>
Subject: Re: [petsc-dev] MatProduct_AtB --with-scalar-type=complex


  Can you confirm if MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ() ends up being 
called for you and what path it takes inside that routine (depends) on the 
algorithm it is using.



> On Jul 14, 2022, at 4:30 PM, Pierre Jolivet <pie...@joliv.et> wrote:
>
> Hello,
> In the following example, the SeqAIJ implementation of MatProduct_AtB produce 
> a different (and wrong) result, compared to the SeqDense implementation or 
> MATLAB.
> I want to compute B = A^H A (where ^H is the Hermitian transpose).
> So I create a MatProduct with A and A.
> Duplicate A into another Mat which I conjugate.
> And I replace the first Mat of the product with this conjugate.
> I expect to get the proper result, which I don’t.
> Is the MatProduct_AtB implementation in the complex case not computing A^T B 
> (where ^T is the transpose)?
> For reference, here is how to properly compute A^H A with current main: 
> conj(A^H conj(A)) — so it requires an extra MatConjugate I’d like to avoid.
>
> Thanks,
> Pierre
>
> <ex1111.c>
>
> $ ./ex1111 -product_view ::ascii_matlab -A_view ::ascii_matlab -convert false
> %Mat Object: 1 MPI process
> %  type: seqdense
> % Size = 2 2
> Mat_0xc4000001_0 = zeros(2,2);
> Mat_0xc4000001_0 = [
> 7.2003197397953400e-01 + 6.1793966542126100e-02i 3.9777780919128602e-01 + 
> 7.3036588248200474e-02i
> 1.0022337819588500e-02 + 1.4463931936456476e-01i 1.0386628927366459e-01 + 
> 2.5078039364333193e-01i
> ];
> %Mat Object: 1 MPI process
> %  type: seqdense
> % Size = 2 2
> Mat_0xc4000001_1 = zeros(2,2);
> Mat_0xc4000001_1 = [
> 5.4328551781548817e-01 + 0.0000000000000000e+00i 3.2823965013353340e-01 + 
> 1.5498666614872689e-02i
> 3.2823965013353340e-01 + -1.5498666614872689e-02i 2.3724054059134142e-01 + 
> 0.0000000000000000e+00i
> ];
>
> $ ./ex1111 -product_view ::ascii_matlab -convert true
> %Mat Object: 1 MPI process
> %  type: seqaij
> % Size = 2 2
> % Nonzeros = 4
> zzz = zeros(4,4);
> zzz = [
> 1 1  4.9380746380098023e-01 9.1886511660038694e-02
> 1 2  2.4666779825931440e-01 9.4705502650537468e-02
> 2 1  2.4666779825931440e-01 9.4705502650537468e-02
> 2 2  1.0079024247365802e-01 1.1019992594899400e-01
> ];
> Mat_0xc4000001_0 = spconvert(zzz);
>
> $ ./ex1111 -product_view ::ascii_matlab -convert true -correct true
> %Mat Object: 1 MPI process
> %  type: seqaij
> % Size = 2 2
> % Nonzeros = 4
> zzz = zeros(4,4);
> zzz = [
> 1 1  5.4328551781548828e-01 -0.0000000000000000e+00
> 1 2  3.2823965013353340e-01 1.5498666614872696e-02
> 2 1  3.2823965013353340e-01 -1.5498666614872696e-02
> 2 2  2.3724054059134142e-01 -0.0000000000000000e+00
> ];
> Mat_0xc4000001_0 = spconvert(zzz);
>
> <Screenshot 2022-07-14 at 10.12.53 PM.png>

#include <petsc.h>
static char help[] = "";

int main(int argc,char **args)
{
  PetscInt  n = 2;
  Mat       array[1],B,conjugate;
  PetscBool flg = PETSC_FALSE, correct = PETSC_FALSE;

  PetscCall(PetscInitialize(&argc,&args,NULL,help));
  PetscCall(MatCreateConstantDiagonal(PETSC_COMM_WORLD,n,n,n,n,-1.0,array));
  PetscCall(MatConvert(array[0],MATDENSE,MAT_INPLACE_MATRIX,array));
  PetscCall(MatSetRandom(array[0],NULL));
  PetscCall(MatViewFromOptions(array[0],NULL,"-A_view"));
  PetscCall(PetscOptionsGetBool(NULL,NULL,"-convert",&flg,NULL));
  PetscCall(PetscOptionsGetBool(NULL,NULL,"-correct",&correct,NULL));
  if (flg) {
    PetscCall(MatConvert(array[0],MATAIJ,MAT_INPLACE_MATRIX,array));
    //PetscCall(PetscOptionsGetBool(NULL,NULL,"-correct",&correct,NULL));
  }

  PetscCall(MatDuplicate(array[0], MAT_COPY_VALUES, &conjugate));
  PetscCall(MatConjugate(conjugate));

  if (!correct) PetscCall(MatProductCreate(array[0],array[0],NULL,&B));
  else PetscCall(MatProductCreate(conjugate,array[0],NULL,&B));
  PetscCall(MatProductSetType(B,MATPRODUCT_AtB));
  PetscCall(MatProductSetFromOptions(B));
  PetscCall(MatProductSymbolic(B));
  PetscCall(MatProductNumeric(B));
  PetscCall(MatDestroy(&conjugate));

  PetscCall(MatViewFromOptions(B,NULL,"-product_view"));
  PetscCall(MatDestroy(&B));
  PetscCall(MatDestroy(array));
  PetscCall(PetscFinalize());
  return 0;
}

Reply via email to