# v_histndim

## PURPOSE

V_HISTNDIM - generates and/or plots an n-dimensional histogram

## SYNOPSIS

function [v,t]=v_histndim(x,b,mode)

## DESCRIPTION

    V_HISTNDIM - generates and/or plots an n-dimensional histogram

      Inputs:  X(m,d)   is the input data: each row is one d-dimensiona data point
               B(3,d)   specifies the histogram bins.
                             B(1,:) gives the number of bins in each dmension [default 10]
                             B(2,:) gives the minimum of the first bin in each dimension [default min(X)]
                             B(3,:) gives the maximum of the last bin in each dimension [default max(X)]
                        If B has only one column, the same values are use for al dimensions
                        If B(1,i)=0 then that dimension will be ignored (and excluded from V)
               MODE     is a character string containing a combination of the following:
                            'z' for zero base in the 2D plot [default base = min(V)]
                            'p' to scale V as probabilities [default actual counts]
                            'h' to plot a histogam even if output arguments are present

     Outputs:  V        d-dimensional array containing the histogram counts
               T        d-element cell array. d{i} contains the bin boundary values for
                        the i'th dimension. The length of d{i} is one more than the number of bins
                        in that dimension.

                        Note that if any of B(1,:) are zero then the number of dimensions in V and elements
                        of T will be correspondingly reduced.

     Example: v_histndim(randn(100000,2),[20 -3 3]','pz');

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

## SOURCE CODE

    0001 function [v,t]=v_histndim(x,b,mode)
    0002 %V_HISTNDIM - generates and/or plots an n-dimensional histogram
    0003 %
    0004 %  Inputs:  X(m,d)   is the input data: each row is one d-dimensiona data point
    0005 %           B(3,d)   specifies the histogram bins.
    0006 %                         B(1,:) gives the number of bins in each dmension [default 10]
    0007 %                         B(2,:) gives the minimum of the first bin in each dimension [default min(X)]
    0008 %                         B(3,:) gives the maximum of the last bin in each dimension [default max(X)]
    0009 %                    If B has only one column, the same values are use for al dimensions
    0010 %                    If B(1,i)=0 then that dimension will be ignored (and excluded from V)
    0011 %           MODE     is a character string containing a combination of the following:
    0012 %                        'z' for zero base in the 2D plot [default base = min(V)]
    0013 %                        'p' to scale V as probabilities [default actual counts]
    0014 %                        'h' to plot a histogam even if output arguments are present
    0015 %
    0016 % Outputs:  V        d-dimensional array containing the histogram counts
    0017 %           T        d-element cell array. d{i} contains the bin boundary values for
    0018 %                    the i'th dimension. The length of d{i} is one more than the number of bins
    0019 %                    in that dimension.
    0020 %
    0021 %                    Note that if any of B(1,:) are zero then the number of dimensions in V and elements
    0022 %                    of T will be correspondingly reduced.
    0023 %
    0024 % Example: v_histndim(randn(100000,2),[20 -3 3]','pz');
    0025
    0026 %       Copyright (C) Mike Brookes 2004
    0027 %      Version: $Id: v_histndim.m 10865 2018-09-21 17:22:45Z dmb $
    0028 %
    0029 %   VOICEBOX is a MATLAB toolbox for speech processing.
    0030 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
    0031 %
    0032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0033 %   This program is free software; you can redistribute it and/or modify
    0034 %   it under the terms of the GNU Lesser General Public License as published by
    0035 %   the Free Software Foundation; either version 3 of the License, or
    0036 %   (at your option) any later version.
    0037 %
    0038 %   This program is distributed in the hope that it will be useful,
    0039 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
    0040 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0041 %   GNU Lesser General Public License for more details.
    0042 %
    0043 %   You can obtain a copy of the GNU Lesser General Public License from
    0044 %   https://www.gnu.org/licenses/ .
    0045 %
    0046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0047
    0048 [n,d]=size(x);
    0049 if nargin<3
    0050     mode=' ';
    0051     if(nargin<2)
    0052         b=repmat(10,1,d);
    0053     end
    0054 end
    0055
    0056 if size(b,2)==1
    0057     b=repmat(b,1,d);
    0058 end
    0059 if size(b,1)<3
    0060     mi=min(x,[],1);
    0061     ma=max(x,[],1);
    0062     w=(ma-mi)./(b(1,:)-0.001);  % nudge slightly to make sure al points included
    0063     b(3,:)=ma+0.0005*w;
    0064     b(2,:)=mi-0.0005*w;
    0065 end
    0066
    0067 acd=find(b(1,:)>0);
    0068 sv=b(1,acd);
    0069 nbt=prod(sv);
    0070 t=cell(length(acd),1);
    0071
    0072 % loop through each dimension
    0073 k=1;        % indexing factor
    0074 ok=repmat(1>0,n,1);
    0075 ix=repmat(nbt-sum(cumprod(sv)),n,1);
    0076 for i=1:length(acd)
    0077     j=acd(i);
    0078     bw=b(1,j)/(b(3,j)-b(2,j));
    0079     bi=ceil((x(:,j)-b(2,j))*bw);
    0080     ok=ok & (bi>0) & (bi<=b(1,j));
    0081     ix(ok)=ix(ok)+k*bi(ok);
    0082     k=k*b(1,j);
    0083     t{i}=b(2,j)+(0:b(1,j))/bw;
    0084 end
    0085 v=full(sparse(ix(ok),1,1,nbt,1));
    0086 if length(sv)>1
    0087     v=reshape(v,sv);
    0088 end
    0089 if any(mode=='p')
    0090     v=v/n;
    0091 end
    0092
    0093 if ~nargout | any(mode=='h')
    0094     svg=find(sv>1);
    0095     if length(svg)==1
    0096         j=acd(svg);
    0097         bar(b(2,j)+(0.5:sv(svg)-0.5)*(b(3,j)-b(2,j))/b(1,j),v(:));
    0098     elseif length(svg)==2
    0099         j=acd(svg(1));
    0100         k=acd(svg(2));
    0101         bj=b(1,j);
    0102         bk=b(1,k);
    0103         %     imagesc(b(2:3,k),b(2:3,j),reshape(v,b(1,j),b(1,k)));
    0104         vda=kron(reshape(v,bj,bk),[1 1;1 1]);
    0105         if any(mode=='z')
    0106             ba=0;
    0107         else
    0108             ba=min(vda(:));
    0109         end
    0110         vda=[repmat(ba,1,2*bk+2);repmat(ba,2*bj,1) vda repmat(ba,2*bj,1);repmat(ba,1,2*bk+2)];
    0111         jda=kron(t{svg(1)},[1 1]);
    0112         jda=jda-(jda(3)-jda(2))*0.01*[-0.5 (-1).^(1:2*bj) 0.5]; % nudge slightly to avoid MATLAB plotting bug
    0113         kda=kron(t{svg(2)},[1 1]);
    0114         kda=kda-(kda(3)-kda(2))*0.01*[-0.5 (-1).^(1:2*bk) 0.5];
    0115         surf(jda,kda,vda');
    0116         ylabel(sprintf('Axis %d',k));
    0117         xlabel(sprintf('Axis %d',j));
    0118         colorbar;
    0119     else
    0120         fprintf(2,'Error in %s: Cannot plot 3-D histogram\n',mfilename);
    0121     end
    0122 end