Regarding the previous questions I noticed that GA on LCA groups is too general for my concerns and that the study of GA on finite abelian groups is enough.

In a certain paper HGFei published a result that for *p×q*-images where *p* and *q* are relatively prime there is an isomorphism to a vector of length *N=pq*. The theory considers the groups $url1%5CbbZ_p%5Ctimes%5CbbZ_q$url2\bbZ_p\times\bbZ_q$url3\bbZ_p\times\bbZ_q$url4 and $url1%5CbbZ_N$url2\bbZ_N$url3\bbZ_N$url4 where $url1%5CbbZ_k%3A%3D%5CbbZ%2Fk%5CbbZ$url2\bbZ_k:=\bbZ/k\bbZ$url3\bbZ_k:=\bbZ/k\bbZ$url4. One explicit mapping from the matrix indices $url1%5Cleft%28%5Cbegin%7Bsmallmatrix%7Dj%5C%5C%20k%5Cend%7Bsmallmatrix%7D%5Cright%29$url2\left(\begin{smallmatrix}j\\ k\end{smallmatrix}\right)$url3\left(\begin{smallmatrix}j\\ k\end{smallmatrix}\right)$url4 to the corresponding vector indices is given by

$url1%5Ciota%5Ccolon%20%5CbbZ_p%5Ctimes%5CbbZ_q%20%5Cto%20%5CbbZ_N%2C%20%5Cquad%20%5Cleft%28%5Cbegin%7Bmatrix%7Dj%5C%5C%20k%5Cend%7Bmatrix%7D%5Cright%29%20%5Cmapsto%20%5Cbeta%20qj%20%2B%20%5Calpha%20pk%20%5Cpmod%20N$url2\iota\colon \bbZ_p\times\bbZ_q \to \bbZ_N, \quad \left(\begin{matrix}j\\ k\end{matrix}\right) \mapsto \beta qj + \alpha pk \pmod N$url3\iota\colon \bbZ_p\times\bbZ_q \to \bbZ_N, \quad \left(\begin{matrix}j\\ k\end{matrix}\right) \mapsto \beta qj + \alpha pk \pmod N$url4

where

*α* and

*β* are integers chosen such that

$url1%5Calpha%20p%2B%5Cbeta%20q%20%5Cequiv%201%20%5Cpmod%20N$url2\alpha p+\beta q \equiv 1 \pmod N$url3\alpha p+\beta q \equiv 1 \pmod N$url4.

My 480×480

zebra-image doesn’t have a height and width that are relatively prime, so I simply drop one

pixel of height:

> im=img(2:480,:);
> size(im)
ans =
479 480
> gcd(479,480)
ans = 1

Just for a first test I set *α=p* and *β=q* and define a primitive mapping function. (I’ll have to find a quicker transform, as in my tests the switching takes too long. But this could be due to the actually large test image. In addition, I currently only manage to do the backward step by storing the indices in an index matrix.)

> function ii=ma2ve(j,k)
> p=479; q=480; a=p; b=q;
> ii = mod(b*q*j+a*p*k , p*q);
> if ii==0; ii=p*q; end
> endfunction
> ma2ve(1,1)
ans = 1
> ma2ve(1,2)
ans = 229442
> p*q
ans = 229920

I have to return *N* instead of 0 to have a correct index value. Although the mapping is actually an isomorphism I didn’t know how to go back to the tuple (*j*,*k*), so I store the indices in an index matrix while building the image vector:

> idx=zeros(p,q); imv=zeros(1,N);
> tic; for ii=1:p; for jj=1:q;
> idx(ii,jj) = ma2ve(ii,jj);
> imv(idx(ii,jj)) = im(ii,jj);
> end; end; toc
Elapsed time is 58.358711 seconds.

58 seconds!? However, the image looks like this as a vector:

> plot(imv)

I try another way of visualizing that vector: I compare a plot of the index matrix with a *p×q*-reshaped (line-by-line) version of the vector:

> imagesc(idx)
> imagesc(reshape(imv,q,p)’) %p is the height of the image

This gives one an idea about how the image values are scattered over the vector in this case: Seeing the vector as a sequence, it starts to walk through the image by going on a diagonal. It is important to notice that there is no way to have the reshaped version of the vector look like the original image, as there would be no possibility for “spanning” the complete image because this requires horizontal *and* vertical “jumps” during the index transform. Therefore this conversion can never be obtained by a simple reshape.

For testing the inverse of this isomorphism, I want to check whether the FFT of that vector corresponds to the FFT2 of the original image:

> tic; Fv=fft(imv); toc
Elapsed time is 1.120667 seconds.
> tic; Fim=fft2(im); toc %for comparing speed
Elapsed time is 0.141670 seconds.
> plot(fftshift(abs(Fv)))

I invert the index transform by the use of the index matrix and visualize the resulting image:

> Fvim=zeros(p,q);
> tic; for ii=1:p; for jj=1:q;
> Fvim(ii,jj)=Fv(idx(ii,jj));
> end; end; toc
Elapsed time is 8.330673 seconds.
> Fdisp=abs(Fvim)/abs(max(Fvim(:))); %scaled for display
> imagesc(fftshift(Fdisp), [0 0.01])

And this indeed looks similar to the plot of the FFT2 of the zebra we have already seen before—Unfortunately, it only looks similar by chance, and it’s not identical and even less identical for other parameters. However, I only did it for testing the matrix-to-vector transform.

One of my next tasks will be to try a Gabor transform and an inverse Gabor transform of an image and see if it reconstructs the image completely. Also I still have to create scripts for building non-separable 2D-window functions like a Gaussian which is stretched in an arbitrary direction, as the presented matrix-to-vector conversion allows the computation of a dual even for non-separable windows.

I found a quicker way to compute the index matrix I mentioned: > tic; [jj kk]=meshgrid(1:p,1:q); toc Elapsed time is 0.080879 seconds. > size(jj), size(kk) ans&#

Weblog:Logbook of Stephan PauknerTracked:Apr 04, 13:59Given an image im of size p×q with gcd(p,q)=1.Find a number s that is not divided by the divisors of N=pq.Index vector, method 1:idx = mod(1:s:N*s, N);nil = find(idx==0); idx(nil)=N;Index vector, method 2 (preferred):idx = mod((1:s:N*s)-1, N)+1;imv(idx) =

Weblog:Logbook of Stephan PauknerTracked:Apr 12, 21:39I always wondered why it didn’t work to compute the dual Gabor atom by using the image-to-vector methods I explained previously [1,2,3]. Dr. Kaiblinger showed me that the correct way was to use that special isomorphism that walks along the diagonal

Weblog:Logbook of Stephan PauknerTracked:May 18, 09:56