<div dir="ltr"><div dir="ltr">
You could use VecPermulte and MatPermute from the PETSc API to permute the vectors/matrices. However, MatPermute creates a new matrix and even though VecPermute permutes the vector (locally) in-place, it allocates a temporary array and frees the original array.<br><br></div><div>Since you are working on dense matrices and vectors and desire to avoid temporary allocation, you could use BLAS level 1 swap function (used by VecSwap to swap two vectors) which will probably be the most optimized version for the hardware you're using (since it's implemented by platform specific intrinsics and assembly). <br></div><div dir="ltr"><br><br>

</div><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Tue, 18 May 2021 11:44:36 -0500<br>
From: Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank">bsmith@petsc.dev</a>><br>
To: Roland Richter <<a href="mailto:roland.richter@ntnu.no" target="_blank">roland.richter@ntnu.no</a>><br>
Cc: PETSc <<a href="mailto:petsc-users@mcs.anl.gov" target="_blank">petsc-users@mcs.anl.gov</a>><br>
Subject: Re: [petsc-users] Efficient FFTShift-implementation for<br>
        vectors/matrices<br>
Message-ID: <<a href="mailto:83012843-A364-4CE1-A92B-1768EB11591E@petsc.dev" target="_blank">83012843-A364-4CE1-A92B-1768EB11591E@petsc.dev</a>><br>
Content-Type: text/plain; charset="us-ascii"<br>
<br>
<br>
  I found a variety of things on the web, below. I don't understand this but for the even case it seems one simply modifies the input matrix before the FFT <a href="http://www.fftw.org/faq/section3.html#centerorigin" rel="noreferrer" target="_blank">http://www.fftw.org/faq/section3.html#centerorigin</a><br>
<br>
  <a href="https://stackoverflow.com/questions/5915125/fftshift-ifftshift-c-c-source-code" rel="noreferrer" target="_blank">https://stackoverflow.com/questions/5915125/fftshift-ifftshift-c-c-source-code</a> <<a href="https://stackoverflow.com/questions/5915125/fftshift-ifftshift-c-c-source-code" rel="noreferrer" target="_blank">https://stackoverflow.com/questions/5915125/fftshift-ifftshift-c-c-source-code</a>><br>
<br>
  <a href="https://www.dsprelated.com/showthread/comp.dsp/20790-1.php" rel="noreferrer" target="_blank">https://www.dsprelated.com/showthread/comp.dsp/20790-1.php</a> <<a href="https://www.dsprelated.com/showthread/comp.dsp/20790-1.php" rel="noreferrer" target="_blank">https://www.dsprelated.com/showthread/comp.dsp/20790-1.php</a>><br>
<br>
<br>
<br>
> On May 18, 2021, at 9:48 AM, Roland Richter <<a href="mailto:roland.richter@ntnu.no" target="_blank">roland.richter@ntnu.no</a>> wrote:<br>
> <br>
> Dear all,<br>
> <br>
> I tried to implement the function fftshift from numpy (i.e. swap the<br>
> half-spaces of all axis) for row vectors in a matrix by using the<br>
> following code<br>
> <br>
> void fft_shift(Mat &fft_matrix) {<br>
>         PetscScalar *mat_ptr;<br>
>         MatDenseGetArray (fft_matrix, &mat_ptr);<br>
>         PetscInt r_0, r_1;<br>
>         MatGetOwnershipRange(fft_matrix, &r_0, &r_1);<br>
>         PetscInt local_row_num = r_1 - r_0;<br>
>         arma::cx_mat temp_mat(local_row_num, Ntime, arma::fill::zeros);<br>
>         for(int i = 0; i < Ntime; ++i) {<br>
>             const PetscInt row_shift = i * local_row_num;<br>
>             for(int j = 0; j < local_row_num; ++j) {<br>
>                 const PetscInt cur_pos = j + row_shift;<br>
>                 if(i < (int)(Ntime / 2))<br>
>                     temp_mat(j, i + int(Ntime / 2)) = *(mat_ptr + cur_pos);<br>
>                 else<br>
>                     temp_mat(j, i - int(Ntime / 2)) = *(mat_ptr + cur_pos);<br>
>             }<br>
>         }<br>
>         for(int i = 0; i < Ntime; ++i) {<br>
>             const PetscInt row_shift = i * local_row_num;<br>
>             for(int j = 0; j < local_row_num; ++j) {<br>
>                 const PetscInt cur_pos = j + row_shift;<br>
>                 *(mat_ptr + cur_pos) = temp_mat(j, i);<br>
>             }<br>
>         }<br>
>         MatDenseRestoreArray (fft_matrix, &mat_ptr);<br>
> }<br>
> <br>
> but I do not like the approach of having a second matrix as temporary<br>
> storage space. Are there more efficient approaches possible using<br>
> PETSc-functions?<br>
> <br>
> Thanks!<br>
> <br>
> Regards,<br>
> <br>
> Roland Richter<br>
> <br>
<br>
-------------- next part --------------<br>
An HTML attachment was scrubbed...<br>
URL: <<a href="http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20210518/b8710455/attachment-0001.html" rel="noreferrer" target="_blank">http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20210518/b8710455/attachment-0001.html</a>><br>
<br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="font-size:12.8px">Sajid Ali (he/him) | PhD Candidate<br></div><div style="font-size:12.8px">Applied Physics<br></div><div style="font-size:12.8px">Northwestern University</div><div style="font-size:12.8px"><a href="http://s-sajid-ali.github.io" target="_blank">s-sajid-ali.github.io</a></div></div></div></div></div></div></div></div>