function pca2d( x, y, pm, w, h )
% computes covariance matrix from the pairs x, y
% diagonalizes covariance matrix, i.e. performs a PCA on [ x, y ]
% x and y are column vectors
% pm: 0 - scatter of data, 1 - histogram, 2 - multivariate gauss from
% covariance matrix, 1 and 2 require w and h
% w and h are the width and the height (in data units) for plotting
% histograms instead of scatter

    % covariance matrix:
    cv = cov( [ x y ] );

    % eigen values:
    [ v , d] = eig( cv )
    s = sign( v );
    s(1,:) = s(2,:);
    v = v .* s;

    % plots:
    subplot( 2, 2, 1 );
    hold on;

    if (pm > 0) & (nargin == 5)
        if pm == 1
            % histogram of data:
            xp = -w:0.5:w;
            yp = -h:0.5:h;
            [n,c] = hist3([x y], { xp, yp } );
            contourf( c{1}, c{2}, n' );
        else
            % bivariate Gaussian:
            xp = -w:0.1:w;
            yp = -h:0.1:h;
            [xg,yg] = meshgrid( xp, yp );
            xy = [ xg(:) yg(:) ];
            gauss = reshape( exp(-0.5*diag(xy*inv(cv)*xy'))/sqrt((2.0*pi)^2.0*det(cv)), size( xg ) );
            contourf( xp, yp, gauss )
        end
        colormap( 'gray' );
    else
        % scatter plot:
        scatter( x, y, 'b', 'filled', 'MarkerEdgeColor', 'white' );
    end

    % plot eigenvectors:
    quiver( ones( 1, 2 ).*mean( x ), ones( 1, 2 )*mean(y), v(1,:).*sqrt(diag(d))', v(2,:).*sqrt(diag(d))', 'r', 'LineWidth', 3, 'AutoScale', 'off', 'AutoScaleFactor', 1.0, 'MaxHeadSize', 0.7 )

    xlabel( 'x' );
    ylabel( 'y' );
    axis( 'equal' );
    hold off;

    % histogram of x values:
    subplot( 2, 2, 3 );
    hist( x, 50, 'b' );
    xlabel( 'x' );
    ylabel( 'count' );

    % sort the eigenvalues:
    [d,inx] = sort( diag(d), 'descend' );

    subplot( 2, 2, 2 );
    hold on;
    % subtract means:
    x = x - mean( x );
    y = y - mean( y );
    % project onto eigenvectors:
    nc = [ x y ] * v(:,inx);
    cv = cov( nc )
    [ v , d] = eig( cv )
    if (pm > 0) & (nargin == 5)
        if pm == 1
            % histogram of data:
            [n,c] = hist3( nc, { xp, yp } );
            contourf( c{1}, c{2}, n' );
        else
            % bivariate Gaussian:
            gauss = reshape( exp(-0.5*diag(xy*inv(cv)*xy'))/sqrt((2.0*pi)^2.0*det(cv)), size( xg ) );
            contourf( xp, yp, gauss )
        end
    else
        % scatter plot:
        scatter( nc(:,1), nc(:,2), 'b', 'filled', 'MarkerEdgeColor', 'white' );
    end
    xlabel( 'n_x' );
    ylabel( 'n_y' );
    axis( 'equal' );
    hold off;

    % histogram of new x values:
    subplot( 2, 2, 4 );
    hist( nc(:,1), 50, 'b' );
    xlabel( 'n_x' );
    ylabel( 'count' );
end
