% rotation matrix: matrix vector multiplication
%
% (c) by Hannes Nickisch, MPI for Biological Cybernetics, 2012 August 16

function y = mvm(A,x,ctransp)

  if strcmp(A.method,'shear')
    if A.di
      z = shear(x,A.imsz,2,A.d1,ctransp);            % deriv of first shear in x
      z = shear(z,A.imsz,1,A.w2,ctransp);                     % first shear in y
      z = shear(z,A.imsz,2,A.w1,ctransp);                    % second shear in x
      y = z;
      z = shear(x,A.imsz,2,A.w1,ctransp);                     % first shear in x
      z = shear(z,A.imsz,1,A.d2,ctransp);           %  deriv of first shear in y
      z = shear(z,A.imsz,2,A.w1,ctransp);                    % second shear in x
      y = y+z;
      z = shear(x,A.imsz,2,A.w1,ctransp);                     % first shear in x
      z = shear(z,A.imsz,1,A.w2,ctransp);                     % first shear in y
      z = shear(z,A.imsz,2,A.d1,ctransp);          % deriv of  second shear in x
      y = y+z;
    else
      y = shear(x,A.imsz,2,A.w1,ctransp);                     % first shear in x
      y = shear(y,A.imsz,1,A.w2,ctransp);                     % first shear in y
      y = shear(y,A.imsz,2,A.w1,ctransp);                    % second shear in x
    end
  else
    if A.di
      if ctransp, y = d(A.W,A.di)'*x(:); else y = d(A.W,A.di)*x(:); end
    else
      if ctransp, y = A.W'*x(:); else y = A.W *x(:); end
    end
  end
  
function y = shear(x,sz,d,w,t)                  % Fourier equivalent of shearing
  y = fftshift(fft(reshape(x,sz),[],d),d);
  if t, y = ifft(ifftshift(conj(w).*y,d),[],d);
  else  y = ifft(ifftshift(     w .*y,d),[],d); end
