% corr2p   dechirp rechirp                 Steve Mann, 1992
% convert correspondences to pchirp parameters, using the linearized
% form (should work most practical cases)
%
% the coordinates are normalized on [0,1);   X down, Y to right
%
% user supplies [x,y,u,v]; function returns [a,b,c,d,e,f,g,h]
%                x=[x1;x2;x3;x4], etc...
%                                                                Y axis
% Example of dechirp:                              -------------->
% x = [0.1; .03; .95; .94];                        |
% y = [.04, .98, .04, .96];                        |
% u = [0;0;1;1];                                   v
% v = [0;1;0;1];                                X axis 
% [a b c d e f g h]=corr2p(x,y,u,v)                
% or
% p = corr2p(x,y,u,v);  % one parameter vector of length 8
%
% Example of rechirp: u=[0.1; .03; .95; .94]; v=[.04, .98, .04, .96];
%                     x=[0;0;1;1]; y=[0;1;0;1];
% p=corr2p(x,y,u,v);
%
% See also: corners2r.c (help in .m file), corners2d.c, pcompose.m, pchirp.c

function [a,b,c,d,e,f,g,h] = pchirplikexdrmapping(x,y,u,v);

input_ismatrix = 0;
if nargin == 1
  input_ismatrix = 1;
  [M,N] = size(x);
  if N ~= 4
     disp('corr2p: you must have 1 (matrix) or 4 (vectors) input parameters')
    error('        exiting')
  end%if
  y=x(:,2); % leave x to last
  u=x(:,3);
  v=x(:,4);
  x=x(:,1); % destroy vector x now
end%if
if nargin==2
  error('corr2p: have not decided how to handle case of 2 input arguments')
end%if
if nargin==3
  error('corr2p: have not decided how to handle case of 3 input arguments')
end%if
if nargin==4
  N=length(x);
  if (length(y)~=N)|(length(u)~=N)|(length(v)~=N)
    error('corr2p: input correspondence vectors must be same length')
  end%if
  if max([min(size(x)),min(size(x)),min(size(x)),min(size(x))]) > 1
    error('corr2p: you gave 4 inputs; all 4 must be vectors not matrices');
  end%if
end%if nargin

if N<4
  disp('corr2r: warning, system underdetermined; will give lstsqr but beware');
end%if

one=ones(size(x));
zero=zeros(size(x));
p=pinv([x(:)  y(:)  one(:)  zero(:) zero(:) zero(:) -u(:).*x(:) -u(:).*y(:); ...
        zero(:) zero(:) zero(:) x(:)  y(:)  one(:)  -v(:).*x(:) -v(:).*y(:)])...
  *[u(:);v(:)];        

p=p.'  % convert to row vector as is the convention

if (nargout~=1)&(nargout~=8)
  error('corr2p: wrong number of output arguments')
end%if

if nargout==8
  a=p(1); b=p(2); c=p(3); d=p(4); e=p(5); f=p(6); g=p(7); h=p(8);
else%ifnargout=1
  a=p; % all of them in vector to first and only output
end%if

