function x = bin2hex(BinStr)

% BIN2HEX (BinStr,...output)
%
% Converts binary strings of any length to hexadecimal pairs. Adds leading
% zeros if there is not an even number of hex bits.
%
% Now also supports cell array inputs.
%
%
% Author: Richard Medlock 2001

% Check to see what the input is:

if iscell(BinStr)

    NCells = length(BinStr)

    for C = 1:NCells

        Str = BinStr{C};

        x{C} = doconvert(Str);

    end

elseif ~ischar(BinStr)

    error('Input must be a string or character or cell array.')

else

    x = doconvert(BinStr);

end

%-----------------------------------------------
function out = doconvert(BinStr)

Bits = length(BinStr);
Words = Bits/4;
WholeWords = floor(Words);
PartWords = Words-WholeWords;

while PartWords > 0

    BinStr = ['0' BinStr];
    Bits = length(BinStr);
    Words = Bits/4;
    WholeWords = floor(Words);
    PartWords = Words-WholeWords;

end

% For each WORD (4-bits), convert it to HEX based on the following rules:

Words = length(BinStr)/4;

HEXi = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

HexStr = [];

for W = 1:Words

    %For each word, convert it first to decimal:

    P = (W*4)-3;

    Word = BinStr(P:P+3);
    DEC = bin2dec(Word);
    HEX = HEXi{DEC+1};

    HexStr = [HexStr HEX];

end

LHex = length(HexStr); %If the Hex String has an odd number of bits, add 0 to the front.

if isodd(LHex)

    HexStr = ['0' HexStr];

end

out = HexStr;


function [ b, info ] = cgtsl ( n, c, d, e, b )

%*****************************************************************************80
%
%% CGTSL solves a complex general tridiagonal system.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 April 2007
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart,
%    LINPACK User's Guide,
%    SIAM, (Society for Industrial and Applied Mathematics),
%    3600 University City Science Center,
%    Philadelphia, PA, 19104-2688.
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, complex C(N); the subdiagonal of the matrix in entries C(2:N).
%
%    Input, complex D(N); the diagonal of the tridiagonal matrix.
%
%    Input, complex E(N), the superdiagonal of the matrix in entries E(1:N-1).
%
%    Input, complex B(N), the right hand side.
%
%    Output, complex B(N).  the solution.
%
%    Output, integer INFO.
%    0, normal value.
%    K, if the K-th element of the diagonal becomes exactly zero.  The
%    subroutine returns when this is detected.
%
  info = 0;
  c(1) = d(1);

  if ( 1 <= n-1 )

    d(1) = e(1);
    e(1) = 0.0;
    e(n) = 0.0;

    for k = 1 : n-1

      if ( cabs1 ( c(k) ) <= cabs1 ( c(k+1) ) )

        t      = b(k);
        b(k)   = b(k+1);
        b(k+1) = t;

        t      = c(k);
        c(k)   = c(k+1);
        c(k+1) = t;

        t      = d(k);
        d(k)   = d(k+1);
        d(k+1) = t;

        t      = e(k);
        e(k)   = e(k+1);
        e(k+1) = t;

      end

      if ( cabs1 ( c(k) ) == 0.0 )
        info = k;
        return
      end

      t = -c(k+1) / c(k);
      c(k+1) = d(k+1) + t * d(k);
      d(k+1) = e(k+1) + t * e(k);
      e(k+1) = 0.0;
      b(k+1) = b(k+1) + t * b(k);

    end

  end

  if ( cabs1 ( c(n) ) == 0.0 )
    info = n;
    return
  end
%
%  Back solve.
%
  b(n) = b(n) / c(n);

  if ( 1 < n )

    b(n-1) = ( b(n-1) - d(n-1) * b(n) ) / c(n-1);

    for k = n-2 : -1 : 1
      b(k) = ( b(k) - d(k) * b(k+1) - e(k) * b(k+2) ) / c(k);
    end

  end

  return
end


function [dat] = ft_preproc_derivative(dat, order)

% FT_PREPROC_DERIVATIVE computes the temporal Nth order derivative of the
% data
%
% Use as
%   [dat] = ft_preproc_derivative(dat, order)
% where
%   dat        data matrix (Nchans X Ntime)
%   order      number representing the Nth derivative (default = 1)
%
% See also PREPROC

% Copyright (C) 2008, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

% set the defaults if options are not specified
if nargin<2 || isempty(order)
  order = 1;
end

% preprocessing fails on channels that contain NaN
if any(isnan(dat(:)))
  ft_warning('FieldTrip:dataContainsNaN', 'data contains NaN values');
end

% compute the derivative
for i=1:order
  dat = gradient(dat);
end


m = 100;
n = 1000;
k = 12;
A = spx.dict.simple.gaussian_dict(m, n);
gen = spx.data.synthetic.SparseSignalGenerator(n, k);
% create a sparse vector
x =  gen.biGaussian();
b = A*x;
A  = double(A);
result = spx.fast.omp(A, b, k, 1e-12);
cmpare = spx.commons.SparseSignalsComparison(x, result, k);
cmpare.summarize();

% we now run both algorithms 100 times
tic;
for i=1:1000
    result = spx.fast.omp(A, b, k, 1e-12);
end
elapsed_time1 = toc;
fprintf('Time taken %0.4f seconds\n', elapsed_time1);

tic;
for i=1:1000
    result = spx.pursuit.single.omp_chol(A, b, k, 1e-12);
end
elapsed_time2 = toc;
fprintf('Time taken %0.4f seconds\n', elapsed_time2);

improvement_factor = elapsed_time2 / elapsed_time1;
fprintf('improvement_factor: %0.2f \n', improvement_factor);


function [mGal] = cmps22mGal(cmps2)
% Convert acceleration from centimeters per square centimeter to milligalileos
% Chad A. Greene 2012
mGal = cmps2*1e+3;
end


 function [xs, ni] = tml_sps(x, Gt, yi, bi, ri, niter, pixmax, curv)
%function [xs, ni] = tml_sps(x, Gt, yi, bi, ri, niter, pixmax, curv)
%	One iteration of the ML-SPS algorithm for transmission Poisson problem
%	(separable paraboloidal surrogates)
%	model: Y_i ~ Poisson(b_i exp(-[G x]_i) + r_i)
%	Input
%		x	[np,1]	initial guess
%		Gt		transpose of system matrix
%		yi		transmission sinogram
%		bi		blank scan factors
%		ri		background (randoms, scatter, crosstalk, etc)
%		bi,ri:		optional (can use empty matrices)
%		yi,bi,ri	must have identical dimensions
%		pixmax		upper constraint for pixel values
%			can be scalar (e.g. 'inf') or an array the size of x
%		curv		'oc' for erdogan's optimal curvatures
%				'pc' for erdogan's fast precomputed curvatures,
%					which usually gives faster convergence,
%					but can be nonmonotone
%				'nr' newton curvatures, can be nonmonotone
%	Output
%		x [np,niter]	updated image vectors each iteration
%
%	fix: the really slick way to do this would be to use
%	the fast precomputed denominator and just backtrack to the monotone
%	version on those rare occasions when it goes downhill
%
%	Copyright 2000-3-01	Jeff Fessler	The University of Michigan

if nargin < 3, ir_usage, end

[nb, na] = size(yi);

if (nargin < 4 || isempty(bi))
	bi = ones(size(yi));
end
if (nargin < 5 || isempty(ri))
	ri = zeros(size(yi));
end
if (nargin < 6 || isempty(niter))
	niter = 2;
end
if (nargin < 7 || isempty(pixmax))
	pixmax = inf;
end
if (nargin < 8 || isempty(curv))
	curv = 'oc';
end

trl_check(yi, bi, ri);

	gi = sum(Gt)';	% g_i = sum_j g_ij

	if strcmp(curv, 'pc')
		ni = trl_curvature_pre(yi, bi, ri);	% precomputed
		denom = Gt * (gi .* ni(:));
	elseif strcmp(curv, 'nr')
		warning 'newton curvatures can be non-monotone'
	elseif ~strcmp(curv, 'oc')
		error 'curv not implemented'
	end

xs = zeros(length(x), niter);
x = max(x,0);
x = min(x,pixmax);
xs(:,1) = x;

%
%	loop over iterations
%
for ii=2:niter
	li = reshape(Gt' * x, size(yi));	% l=G*x "line integrals"
	bel = bi .* exp(-li);
	yb = bel + ri;			% predicted measurement means

	dothi = (1 - yi ./ yb) .* bel;

	if strcmp(curv, 'oc')
		%	optimal curvatures (for ensured monotone increase)
		ni = trl_curvature(yi, bi, ri, li, 'oc');
		denom = Gt * (gi .* ni(:));
	elseif strcmp(curv, 'nr')
		ni = (1 - ri.*yi./yb.^2) .* bel;
		denom = Gt * (gi .* ni(:));
	end

	x = x + (Gt * dothi(:)) ./ denom;	% there's the update!
	x = max(x,0);				% enforce nonnegativity
	x = min(x,pixmax);			% enforce upper bound constraint

	xs(:,ii) = x;
end


function value = zsign1 ( z1, z2 )

%*****************************************************************************80
%
%% ZSIGN1 is a complex transfer-of-sign function.
%
%  Discussion:
%
%    The L1 norm is used.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 May 2006
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Parameters:
%
%    Input, complex Z1, Z2, the arguments.
%
%    Output, complex VALUE,  a complex value, with the magnitude of
%    Z1, and the argument of Z2.
%
  if ( zabs1 ( z2 ) == 0.0 )
    value = 0.0;
  else
    value = zabs1 ( z1 ) * ( z2 / zabs1 ( z2 ) );
  end

  return
end


function ShowImage(data, height, width, nRow, nColumn, reverse)

[p, m] = size(data);
if width * height ~= p
    error('<EigFace>: incorrect width or height.\n');
end

if nColumn * nRow > m
    error('<EigFace>: incorrect column number or row number.\n');
end

lineW = 1;
horiW = lineW;
vertW = lineW;
% scaling data
data = data/max(data(:));
canvH = height*nRow+horiW*(nRow+1);
canvW = width*nColumn+vertW*(nColumn+1);

% construct canvas
canvColor = .5;
if reverse
    canvColor = 1-canvColor;
end
Y = canvColor*ones(canvH,canvW);

% draw the datas
vertProb = lineW;
for i=1:nRow
    horiProb = lineW;
    for j=1:nColumn
        if reverse
            Y(vertProb+(1:height),  horiProb+(1:width)) = 1-reshape(data(:,(i-1)*nColumn+j),[height,width]);
        else
            Y(vertProb+(1:height),  horiProb+(1:width)) = reshape(data(:,(i-1)*nColumn+j),[height,width]);
        end
        % draw dashed line
        if j~=nColumn
            Y(vertProb+(1:floor(height/3):height), horiProb+width+1) = ~canvColor;
        end
        if i~=nRow
            Y(vertProb+height+1, horiProb+(1:floor(width/3):width)) = ~canvColor;
        end
        % move horizontal probe
        horiProb = horiProb+width+vertW;
    end
    % move vertical probe
    vertProb = vertProb+height+horiW;
end

% rescaling
Y = Y*255;

% show the image
imagesc(Y);
colormap(gray);
axis image off;


%% Copyright (C) 2003 Willem J. Atsma
%% Copyright (C) 2014-2016, 2019 Colin B. Macdonald
%%
%% This program is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public
%% License as published by the Free Software Foundation;
%% either version 3, or (at your option) any later version.
%%
%% This software is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied
%% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
%% PURPOSE.  See the GNU General Public License for more
%% details.
%%
%% You should have received a copy of the GNU General Public
%% License along with this software; see the file COPYING.  If not,
%% see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @deftypemethod  @@sym {@var{doublec} =} sym2poly (@var{p})
%% @deftypemethodx @@sym {@var{c} =} sym2poly (@var{p}, @var{x})
%% Return vector of coefficients of a symbolic polynomial.
%%
%% In the two-input form, the second argument @var{x} specifies the free
%% variable; in this case this function returns a row vector @var{c} of
%% symbolic expressions. The coefficients correspond to decreasing exponent
%% of the free variable.  Example:
%% @example
%% @group
%% syms x y
%% sym2poly(2*x^2 + 3*x - pi, x)
%%    @result{} (sym) [2  3  -π]  (1×3 matrix)
%% sym2poly(x^2 + y*x, x)
%%    @result{} (sym) [1  y  0]  (1×3 matrix)
%% @end group
%% @end example
%%
%% @strong{Warning}: Using the single-argument form, the coefficient vector
%% @var{c} is a plain numeric vector (double).  This is for compatibility
%% with the Matlab Symbolic Math Toolbox.
%% We suggest making this clear in your code by explicitly casting to @code{double},
%% as in:
%% @example
%% @group
%% syms x
%% @c doctest: +SKIP_IF(compare_versions (OCTAVE_VERSION(), '6.0.0', '<'))
%% double(sym2poly(pi*x^3 + 3*x/2 + exp(sym(1))))
%%    @result{}     3.1416      0   1.5000   2.7183
%% @end group
%% @end example
%% You may prefer specifying @var{X} or using @code{coeffs}:
%% @example
%% @group
%% coeffs(pi*x^3 + 3*x/2 + exp(sym(1)), 'all')
%%    @result{} (sym) [π  0  3/2  ℯ]  (1×4 matrix)
%% @end group
%% @end example
%%
%% If @var{p} is not a polynomial the result has no warranty.  SymPy can
%% certainly deal with more general concepts of polynomial but we do not
%% yet expose all of that here.
%%
%% @seealso{poly2sym, @@sym/coeffs, polyval, roots}
%% @end deftypemethod

%% Created: 18 April 2003
%% Changed: 25 April 2003
%%    Removed the use of differentiate to get to coefficients - round-off
%%     errors cause problems. Now using newly created sumterms().
%% Changed: 6 May 2003
%%    Removed the attempt to use ldegree(), degree() and coeff() - results
%%     with these are inconsistent.
%% Changed: 16 April 2014
%%    Used the comment header and tests in OctSymPy, but rewrote
%%    the body (by Colin Macdonald).

function c = sym2poly(p, x)

  if ~(isscalar(p))
    error ('sym2poly: works for scalar input only');
  end

  if (nargin == 1)
    ss = findsymbols(p);
    if (length (ss) >= 2)
      error ('sym2poly: input has more than one symbol: not clear what you want me to do')
    elseif (length (ss) == 1)
      x = ss{1};
    else
      x = sym('x');
    end
    convert_to_double = true;
  elseif (nargin == 2)
    convert_to_double = false;
  else
    print_usage ();
  end

  cmd = { 'f = _ins[0]'
          'x = _ins[1]'
          'p = Poly.from_expr(f,x)'
          'return p.all_coeffs(),' };

  c2 = pycall_sympy__ (cmd, sym(p), sym(x));
  if (isempty(c2))
    error ('sym2poly: empty python output, can this happen?  A bug.')
  end

  % FIXME: should be able to convert c2 to array faster than array
  % expansion!  Particularly in the case where we just convert to
  % double anyway!
  c = sym([]);
  for j = 1:numel(c2)
    % Bug #17
    %c(j) = c2{j};
    idx.type = '()'; idx.subs = {j};
    c = subsasgn(c, idx, c2{j});
  end

  if (convert_to_double)
    c = double(c);
  end

end

%!shared x,y,a,b,c
%! syms x y a b c
%!assert (isequal (sym2poly (x^2 + 3*x - 4), [1 3 -4]))
%!assert (isequal (sym2poly (x^6 - x^3), [1 0 0 -1 0 0 0]))
%!assert (isequal (sym2poly (x^2 + 3*x - 4, x), [1 3 -4]))
%!assert (norm (sym2poly (pi*x^2 + exp(sym(1))) - [pi 0 exp(1)]) < 10*eps)
%% types
%!assert (isa (sym2poly (x^2 + 3*x - 4), 'double'))
%!assert (isa (sym2poly (x^2 + 3*x - 4, x), 'sym'))
%% tests with other vars
%!assert (isequal (sym2poly (x^2+y*x, x), [sym(1) y sym(0)]))
%!assert (isequal (sym2poly (x^2+y*x, y), [x x^2]))
%% inverse relationship
%!assert (isequal (sym2poly (poly2sym ([a b c], x), x), [a b c]))
%!assert (isequal (poly2sym (sym2poly(a*x^2 + c, x), x), a*x^2 + c))
%!assert (isequal (sym2poly (poly2sym ([1 2 3])), [1 2 3]))

%!error <more than one symbol>
%! % too many symbols for single-input
%! p = a*x^2 + 2;
%! c = sym2poly (p);

%!assert (isequal (sym2poly (sym(5)), sym(5)))


function n = ndims(t)
%NDIMS Number of dimensions of a sparse tensor.
%
%   NDIMS(T) returns the number of dimensions of sparse tensor T.
%
%   Examples:
%   T = sptenrand([3 2 2],5);
%   ndims(T) %<-- should return 3
%
%   See also SPTENSOR.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

n = size(t.size,2);


function pass = test_size(pref)
%TEST_SIZE     Test the SIZE method of the CHEBMATRIX class
%%
% Create some CHEBMATRIX objects and check their sizes:
x = chebfun(@(x) x);
D = operatorBlock.diff();
S = functionalBlock.sum();

ff = chebmatrix([x, x, x]);
A = [[D, D, D]; [S, S, S]];
B = [[D x]; [S 1]];

pass(1) = all(size(ff) == [1 3]);
pass(2) = all(size(ff') == [3 1]);
pass(3) = all(size(A) == [2 3]);
pass(4) = all(size(A') == [3 2]);
pass(5) = all(size(B) == [2 2]);
pass(6) = all(size(B) == [2 2]);
%%
end


function calc_prob

%%

nGames = 50; % number of games
bet = 100; % units: escudos

pwin = 0.8; % probability of winning
ploss = 1 - pwin; % loosing probability

rate = 0.25;  % paying bet (what the house pays). This will be the average of
% bet payment with multiple bets

earnings =  ( (rate * win) -  ploss) * bet * nGames


function [satp] = satposin(t,eph)
%  SATPOSIN   Calculation of X,Y,Z coordinates in an INERTIAL
%	      reference frame at time t for given ephemeris eph

% Written by Kai Borre
% November 15, 1996

   GM = 3.986008e14;		% earth's universal gravitational parameter
				% m^3/s^2

   %  Units are either seconds, meters, or radians
   %  Assigning the local variables to eph
   svprn   =   eph(1);
   af2	   =   eph(2);
   M0	   =   eph(3);
   roota   =   eph(4);
   deltan  =   eph(5);
   ecc	   =   eph(6);
   omega   =   eph(7);
   cuc	   =   eph(8);
   cus	   =   eph(9);
   crc	   =  eph(10);
   crs	   =  eph(11);
   i0	   =  eph(12);
   idot    =  eph(13);
   cic	   =  eph(14);
   cis	   =  eph(15);
   Omega0  =  eph(16);
   Omegadot=  eph(17);
   toe	   =  eph(18);
   af0	   =  eph(19);
   af1	   =  eph(20);
   t0c	   =  eph(21);

   % Procedure for coordinate calculation
   A = roota*roota;
   t = check_t(t-t0c);
   n0 = sqrt(GM/A^3);
   n = n0+deltan;
   M = M0+n*t;
   M = rem(M,2*pi);
   E = M;
   E_old = E+.001;
   while abs(E-E_old) >= 1.e-12
      E_old = E;
      E = M+ecc*sin(E);
   end
   v = atan2(sqrt(1-ecc^2)*sin(E), cos(E)-ecc);
   phi = v+omega;
   phi = rem(phi,2*pi);
   u = phi		      + cuc*cos(2*phi)+cus*sin(2*phi);
   r = A*(1-ecc*cos(E))       + crc*cos(2*phi)+crs*sin(2*phi);
   i = i0+idot*t	      + cic*cos(2*phi)+cis*sin(2*phi);
   Omega = Omega0+Omegadot*t;
   x1 = cos(u)*r;
   y1 = sin(u)*r;
   satp(1,1) = x1*cos(Omega)-y1*cos(i)*sin(Omega);
   satp(2,1) = x1*sin(Omega)+y1*cos(i)*cos(Omega);
   satp(3,1) = y1*sin(i);

%%%%%%%%% end satposin.m %%%%%%%%%


function [logbf] = spm_mlm_posthoc (mlm,c,a)
% Post-hoc model comparison of multivariate linear models
% FORMAT [logbf] = spm_mlm_posthoc (mlm,c,a)
%
% mlm          MLM data structure - see spm_mlm_bayes.m
%              This contains eg. the [p x d] posterior mean regression
%              coefficient matrix mlm.wmean.
%
% c            [k x p*d] contrast matrix defining k-dimensional subspace
% a            hypothesized value (zeros(k,1) by default)
%
% The contrast matrix and hypothesized value define the reduced model.
% The contrast is applied to the vectorised parameters w = vec(mlm.wmean)
%
% The Bayes Factor in favour of the alternative hypothesis over the null
% is computed using a Savage-Dickey ratio (the probability of the
% hypothesized value under the prior versus its probability under the
% posterior)
%
% bf = p(c*w=a|mlm)/p(c*w=a|Y,mlm)
%
% logbf        Log Bayes Factor
%___________________________________________________________________________
% Copyright (C) 2011 Wellcome Trust Centre for Neuroimaging

% Will Penny
% $Id: spm_mlm_posthoc.m 4651 2012-02-09 16:03:39Z will $

wpost=mlm.wmean(:);

post_mean=c*wpost;
k=size(post_mean,1);
prior_mean=zeros(k,1);

post_cov=c*mlm.wcov*c';

% Get prior covariance matrix
prec_prior=size(mlm.wcov,1);
for g=1:mlm.prior.groups,
    prec_prior=prec_prior+mlm.prior.group(g).mean_alpha*mlm.prior.group(g).index;
end
w_prior_cov=diag(1./prec_prior);
prior_cov=c*w_prior_cov*c';

if nargin < 3 | isempty (a)
    a=zeros(k,1);
end

% Enforce symmetry - to avoid numerical issues
prior_cov=(prior_cov+prior_cov')/2;
post_cov=(post_cov+post_cov')/2;

% For now just use spm_mvNpdf. This can be made more efficient !
prior_prob=spm_mvNpdf(a,prior_mean,prior_cov);
post_prob=spm_mvNpdf(a,post_mean,post_cov);

logbf=log(prior_prob)-log(post_prob);


%GAUSSM Trainable mapping, mixture of Gaussians (MoG) density estimate
%
%  W = GAUSSM(A,K,R,S,M)
%  W = A*GAUSSM([],K,R,S,M)
%  W = A*GAUSSM(K,R,S,M)
%
% INPUT
%   A     Dataset
%   K     Number of Gaussians per class
%   R,S,M Regularization parameters, 0 <= R,S <= 1, see QDC
%
% OUTPUT
%   W     Mixture of Gaussians density estimate
%
% DESCRIPTION
% Estimation of a PDF by the dataset A by a mixture of Gaussians procedure.
% Use is made of EMCLUST(A,QDC,K). Unlabeled objects are neglected, unless
% A is entirely unlabeled or double. Then all objects are used. If A is a
% multi-class crisp labeled dataset the densities are estimated class by
% class and then weighted and combined according their prior probabilities.
% Use +A instead of A to obtain a single set of Gaussians. In all cases,
% just single density estimator W is returned.
%
% Note that it is necessary to set the label type of A to soft labels
% (A = LABTYPE(A,'soft') in order to use the traditional EM algorithm
% based on posterior probabilities instead of using crisp labels.
%
% The mapping W may be applied to a new dataset B using DENSITY = B*W.
%
%  W = A*GAUSSM
%
% uses a single Gaussian per class (K=1) and no regularisation. If
% regulariisation is desired, also K should be supplied.
%
% EXAMPLE
% a = gendatb;
% w = a*gaussm(2);
% scatterd(a)
% plotm(w)
%
% SEE ALSO (PRTools Guide)
% DATASETS, MAPPINGS, QDC, MOGC, EMCLUST, PLOTM, TESTC

% Copyright: R.P.W. Duin, r.p.w.duin@37steps.com
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands

% $Id: gaussm.m,v 1.8 2009/02/02 21:57:39 duin Exp $

function w = gaussm(varargin)

  mapname = 'Mixture of Gaussians';
	argin = shiftargin(varargin,'scalar');
  argin = setdefaults(argin,[],1,0,0,[]);
  if mapping_task(argin,'definition')
    w = define_mapping(argin,'untrained');
    w = setname(w,mapname);
  else
    [a,n,r,s,dim] = deal(argin{:});

    if isa(a,'prdataset')
      labname = getname(a);
    else
      labname = '';
    end

    if ((~isdataset(a) && ~isdatafile(a)) || ...
        (getsize(a,3) ~= 1 && islabtype(a,'crisp')))
      % this handles the multiclass situation
      w = mclassm(a,prmapping(mfilename,n),'weight');
      w = setlabels(w,labname);
      w = setname(w,mapname);

    else
      % here we have a single class
      [m,k] = getsize(a);
      if n == 1
        % just one Gaussian, esitmate it
        [U,G] = meancov(a);
        res.mean = +U;
        res.cov  = G;
        res.prior= 1;
        w = normal_map(res,labname,k,1);
      else
        % multiple Gaussians, run EM
        [e,v] = emclust(a,qdc([],r,s,dim),n);
        ncomp0 = size(v.data.mean,1);
        iter = 0;
        while (ncomp0 ~= n & iter < 5)   % repeat until exactly n components are found
          [e,v1] = emclust(a,qdc([],r,s,m),n);
          ncomp1 = size(v1.data.mean,1);
          if ncomp1 > ncomp0
            v = v1;
            ncomp0 = ncomp1;
          end
          iter = iter + 1;
        end
        res = v.data;
        res.nlab = ones(n,1); % defines that all Gaussian components have to be
                              % combined into a single class.
        w = prmapping('normal_map','trained',res,labname,k,1);
      end
      w = setname(w,mapname);

    end

  end

return


function ns = count_squares_fisheye_distorted(I,x1,y1,x2,y2,win, fg, cg, kg);

[ny,nx] = size(I);

if ((x1-win <= 0) || (x1+win >= nx) || (y1-win <= 0) || (y1+win >= ny) || ...
        (x2-win <= 0) || (x2+win >= nx) || (y2-win <= 0) || (y2+win >= ny))
    ns = -1;
    return;
end;

if ((x1 - x2)^2+(y1-y2)^2) <  win,
    ns = -1;
    return;
end;

nX = round(sqrt((x1-x2)^2 + (y1-y2)^2));
alpha_x = (0:nX)/nX;

pt1n = normalize_pixel_fisheye([x1;y1]-1,fg,cg,kg,0);
pt2n = normalize_pixel_fisheye([x2;y2]-1,fg,cg,kg,0);

ptsn = repmat(pt1n,[1 nX+1]) + (pt2n - pt1n)*alpha_x;

pts = apply_fisheye_distortion(ptsn,kg);
pts(1,:) = fg(1)*pts(1,:) + cg(1);
pts(2,:) = fg(2)*pts(2,:) + cg(2);

% Check that the curve is within the image:
good_line = (min(pts(1,:))-win > 0) && (max(pts(1,:))+win < (nx-1)) && ...
    (min(pts(2,:))-win > 0) && (max(pts(2,:))+win <(ny-1));

if ~good_line,
    ns = -1;
    return;
end;

% Deviate the trajectory orthogonally:
lambda = [y1 - y2 ; x2 - x1];
lambda = lambda / sqrt(sum(lambda.^2));

Np = size(pts,2);
xs_mat = ones(2*win + 1,1)*pts(1,:);
ys_mat = ones(2*win + 1,1)*pts(2,:);
win_mat = (-win:win)'*ones(1,Np);
xs_mat2 = round(xs_mat - win_mat * lambda(1));
ys_mat2 = round(ys_mat - win_mat * lambda(2));
ind_mat = (xs_mat2) * ny + ys_mat2 + 1;
ima_patch = zeros(2*win + 1,Np);
ima_patch(:) = I(ind_mat(:));

filtk = [ones(win,Np);zeros(1,Np);-ones(win,Np)];
out_f = sum(filtk.*ima_patch);
out_f_f = conv2(out_f,[1/4 1/2 1/4],'same');
out_f_f = out_f_f(win+1:end-win);
ns = length(find(((out_f_f(2:end)>=0)&(out_f_f(1:end-1)<0)) | ((out_f_f(2:end)<=0)&(out_f_f(1:end-1)>0))))+1;


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

function phi = cf_merton(u,lnS,T,r,d,sigma,a,b,lambda)
% characteristic function for the Merton model
    phi = exp(cf_black(u,lnS,T,r,d,sigma) ...
        + cf_lognormjump(u,a,b,lambda,T));
end


% computes the pose vector v from a homogeneous transform A
function v=t2v(A)
  v = [A(1:2,3); atan2(A(2,1),A(1,1))];
end


function model = mogUpdateCovariance(model)

% MOGUPDATECOVARIANCE Update the covariances of an MOG model.
% FORMAT
% DESC updates the covariance matrices of a mixtures of
% Gaussians model. The implementation currently uses an
% eigenvalue based update.
% ARG model : the model which is to be updated.
% RETURN model : the model with updated covariances.
%
% SEEALSO : mogCreate, mogUpdateMean, mogEstep
%
% COPYRIGHT : Neil D. Lawrence, 2006

% MLTOOLS

for i = 1:model.m

  centredY = model.Y - repmat(model.mean(i,:), model.N, 1);
  centredY = centredY.*repmat(sqrt(model.posterior(:,i)), 1, model.d);
  switch model.covtype
    case 'ppca'
     C = (centredY'*centredY+0.001*eye(model.d))/sum(model.posterior(:, i)+.001);
     [vec, val] = eig(C);
     val = diag(val);
     [val, ind] = sort(val);
     ind = ind(end:-1:1);
     val = val(end:-1:1);
     vec = vec(:, ind(1:model.q));
     sigma2 = mean(val(model.q+1:end));
     if sigma2<eps
       sigma2 = eps;
     end
     lambda = val(1:model.q) - sigma2;
     %[sigma2, eigVec, lambda] = ppca(C, model.q);
     if length(lambda) ~= model.q
       % Something's wrong here ...
       sigma2 = 1e-6;
       warning('Not enough eigenvalues extracted.')
       lambdaTemp = lambda;
       lambda = zeros(model.q, 1);
       lambda(1:length(lambdaTemp)) = lambdaTemp;
     end

     model.sigma2(i) = sigma2;
     model.W{i} = vec*diag(sqrt(lambda));
     model.U{i} = sqrt(sigma2)*eye(model.d);
     for j = 1:model.q
       model.U{i} = cholupdate(model.U{i}, model.W{i}(:, j));
     end
   case 'spherical'
    model.sigma2(i) = sum(sum(centredY.*centredY))/(model.d*sum(model.posterior(:, i)));
  end
end


function [connectivity, pValues, freq] = bst_granger_spectral(X, Y, Fs, order, inputs)
% BST_GRANGER_SPECTRAL  Granger causality at each frequency between any two
%                       signals.
%
% Inputs:
%   X                 - first set of signals, one signal per row
%                       [X: A x N or A x N x T matrix]
%   Y                 - second set of signals, one signal per row
%                       [Y: B x N or B x N x T matrix]
%                       (default: Y = X)
%   Fs                - sampling rate (we assume uniform sampling rate)
%                       [FS: scalar, FS > freq(end)*2]
%   order             - maximum order of autogressive model
%                       [p: integer > 1, default 10]
%   inputs            - structure of parameters:
%   |-freq            - frequencies of interest if desired
%   |-freqResolution  - maximum freq resolution in Hz, to limit NFFT
%   |                   [DF: double, default [] (i.e. no limit)]
%   |-nTrials         - # of trials in concantenated signal
%   |-flagFPE         - if true, optimize order for autoregression
%   |                   if false (default), use same order in autoregression
%   |-standardize     - if true (default), remove mean from each signal
%   |                   if false, assume signal has already been detrended
%
% Outputs:
%   connectivity      - A x B matrix of spectral Granger causalities from
%                       source to sink. For each signal pair (a,b) we calculate
%
%                                        S_{sink} (f)
%                  ------------------------------------------------------------
%                  S_{sink}(f) - |H_{sink, source} (f)|^2 sigma_{source | sink}
%
%                       with S_{sink}(f) as the power spectral density of a @ f
%                            H_{sink, source}(f) as the transfer function @ f
%                            sigma_{source | sink} as the conditional variance
%                             of the residual at b given the residual at a,
%                             calculated using the residual covariance.
%                       By default, GC(a,a) = 0 if Y is empty.
%                       [C: MX x MY x NF matrix]
%   pValues           - parametric p-value for corresponding spectral Granger
%                       causality in mean estimate
%                       [P: MX x MY x NF matrix]
%   freq              - frequencies corresponding to the previous two metrics
%                       [F: NF x 1 vector]
%
% See also BST_GRANGER, BST_COHERENCE_MVAR.
%
% Call:
%   connectivity = bst_granger_spectral(X, Y, 200, 10, inputs); % general call
%   connectivity = bst_granger_spectral(X, [], 200, 30, inputs); % every pair
%   connectivity = bst_granger_spectral(X, [], 200, 30, inputs); % more variance
% Parameter examples:
%   inputs.freq           = 0:0.1:100; % specify desired frequencies
%   inputs.freqResolution = 0.1; % have a high-point FFT
%   inputs.nTrials        = 9; % use trial-average covariances in AR estimation
%   inputs.flagFPE        = true; % use AR model with best information criteria

% Note: for those following Chicharro2012, I have used the equivalence
%                       sigma_{xx}^(xy) |H_{xx}^(xy) (w)|^2
%                                       =
%                S_{xx}(w) - sigma_{yy}^(xy) |H_{xy}^(xy) (w)|^2
% which follows Geweke1982 instead. As Chicharro notes, it may be better to use his
% formulation because it separates out instantaneous causality I think.

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Sergul Aydore & Syed Ashrafulla, 2012

% reformat to a 2D matrix if necessary, and pull out # of trials
if ndims(X) == 3
  inputs.nTrials = size(X,3);
  X = reshape(X, size(X, 1), []);
elseif ~isfield(inputs, 'nTrials')
  inputs.nTrials = 1;
end

% lengths of things
nSamples = size(X, 2);
nTimes = nSamples / inputs.nTrials;

% standardization: zero mean & unit variance, remove linear & quadratic trends as well
if isfield(inputs, 'standardize') && inputs.standardize
  detrender = [ ...
    ones(1, nTimes); ... % constant trend in data
    linspace(-1, 1, nTimes); ... % linear trend in data
    3/2 * linspace(-1, 1, nTimes).^2 - 1/2 ... % quadratic trend in data
  ];

  % detrend X
  for iTrial = 1:inputs.nTrials
    X(:, (iTrial-1)*nTimes + (1:nTimes)) = X(:, (iTrial-1)*nTimes + (1:nTimes)) - ( X(:, (iTrial-1)*nTimes + (1:nTimes)) / detrender ) * detrender;
    X(:, (iTrial-1)*nTimes + (1:nTimes)) = diag( sqrt(sum(X(:, (iTrial-1)*nTimes + (1:nTimes)).^2, 2)) ) \ X(:, (iTrial-1)*nTimes + (1:nTimes));
  end

  % detrend Y only if it is not empty
  if ~isempty(Y)
    Y = reshape(Y, size(Y, 1), []); % reshape to 2D matrix first
    for iTrial = 1:inputs.nTrials
      Y(:, (iTrial-1)*nTimes + (1:nTimes)) = Y(:, (iTrial-1)*nTimes + (1:nTimes)) - ( Y(:, (iTrial-1)*nTimes + (1:nTimes)) / detrender ) * detrender;
      Y(:, (iTrial-1)*nTimes + (1:nTimes)) = diag( sqrt(sum(Y(:, (iTrial-1)*nTimes + (1:nTimes)).^2, 2)) ) \ Y(:, (iTrial-1)*nTimes + (1:nTimes));
    end
  end
end

% number of FFT bins required
if ~isfield(inputs, 'freq') || isempty(inputs.freq) % frequencies of interest are not defined
  if isfield(inputs, 'freqResolution') && ~isempty(inputs.freqResolution) && (size(X,2) > round(Fs / inputs.freqResolution))
    nFFT = 2^nextpow2( round(Fs / inputs.freqResolution) );
  else % use a default frequency resolution of 1Hz to mirror the standard frequency resolution in bst_coherence_welch.m
    nFFT = 2^nextpow2( round(Fs / 1) );
  end
elseif numel(inputs.freq) == 1
  nFFT = inputs.freq;
else
  nFFT = 2^nextpow2(max( length(inputs.freq)-1, (Fs/2) / min(diff( sort(inputs.freq(:)) )) )) * 2;
end

% default: Order 10 used in BrainStorm
if isempty(order)
  order = 10;
end

% default: Single-trial
if ~isfield(inputs, 'nTrials') || isempty(inputs.nTrials)
  inputs.nTrials = 1;
end

% default: do not optimize model order
if ~isfield(inputs, 'flagFPE') || isempty(inputs.flagFPE)
  inputs.flagFPE = false;
end

%% Differentiate between auto-causality and cross-causality for speed

if isempty(Y) % auto-causality between signals in X, so we can halve the number of models to estimate

  % preallocate the spectral causality matrix
  connectivity = zeros(size(X, 1), size(X, 1), nFFT/2);

  % iterate over all pairs of sinks & sources
  for iX = 1:size(X, 1)
    for iY = iX+1 : size(X, 1) % to avoid auto-causality

        % two-variate model for given source
        [transfers, noiseCovariance, order] = bst_mvar([X(iX, :); X(iY, :)], order, inputs.nTrials, inputs.flagFPE);

        % spectra and power of forward system
        [spectra, freq, forward] = bst_granger_spectral_spectrum(transfers, noiseCovariance, nFFT, Fs);

        % Geweke-Granger spectral causality from source to sink
        unrestricted = abs(spectra(1, 1, :)); restriction = forward(1, 2, :); % S_{sink}(f) and |H_{sink, source} (f)|^2, w/ abs to get rid of 1e-16 imag part
        residualVariance = noiseCovariance(2,2) - noiseCovariance(2, 1) / noiseCovariance(1, 1) * noiseCovariance(1, 2); % partial variance of source
        restricted = abs(unrestricted) - abs(restriction).^2 * residualVariance; % S_{sink} (f) - |H_{sink, source} (f)|^2 sigma_{source | sink}
        connectivity(iX, iY, abs(restricted) > 1e-60) = unrestricted(abs(restricted) > 1e-60) ./ restricted(abs(restricted) > 1e-60) - 1;% Geweke-Granger
        % sigma_{source | sink} = partial covariance which is the formula above (sigma_{source} - rho_{source, sink} / sigma_{sink} * rho_{sink, source})

        % Geweke-Granger spectral causality from sink back to source (to halve the # of MVAR fittings)
        unrestricted = abs(spectra(2, 2, :)); restriction = forward(2, 1, :); % S_{source}(f) and |H_{source, sink} (f)|^2, w/ abs to get rid of 1e-16 imag part
        residualVariance = noiseCovariance(1,1) - noiseCovariance(1, 2) / noiseCovariance(2, 2) * noiseCovariance(2, 1); % partial variance of sink
        restricted = abs(unrestricted) - abs(restriction).^2 * residualVariance; % S_{source} (f) - |H_{source, sink} (f)|^2 sigma_{sink | source}
        connectivity(iY, iX, abs(restricted) > 1e-60) = unrestricted(abs(restricted) > 1e-60) ./ restricted(abs(restricted) > 1e-60) - 1; % Geweke-Granger
        % sigma_{sink | source} = partial covariance which is the formula above (sigma_{sink} - rho_{sink, source} / sigma_{source} * rho_{source, sink})

    end

    % diagonal will equal the maximum of all inflows and outflows for iX, specific to each frequency
    connectivity(iX, iX, :) = max( max(connectivity(iX, :, :), [], 2), max(connectivity(:, iX, :), [], 1) );

  end

else % we have to use all pairs of signals

  % preallocate the spectral causality matrix
  connectivity = zeros(size(X, 1), size(Y, 1), nFFT/2);
  duplicates = zeros(0, 2);

  % iterate over all pairs of sinks & sources
  for iX = 1:size(X, 1)
    for iY = 1:size(Y, 1)

      if max(abs(X(iX, :) - Y(iY, :))) > eps % by default, if X(sink) = Y(source), the causality is 0 everywhere

        % 2-variate model for given source
        [transfers, noiseCovariance, order] = bst_mvar([X(iX, :); Y(iY, :)], order, inputs.nTrials, inputs.flagFPE);

        % spectra and power of forward system
        [spectra, freq, forward] = bst_granger_spectral_spectrum(transfers, noiseCovariance, nFFT, Fs);
        spectra = abs(spectra(1, 1, :)); % limit to the autospectrum of the sink S_{sink} (f) and take absolute value to rid the 1e-16 imaginary part
        forward = forward(1, 2, :); % limit to the cross-transfer from source to sink H_{sink, source} (f)

        % partial covariance of residual
        residualVariance = noiseCovariance(2,2) - noiseCovariance(2,1) / noiseCovariance(1, 1) * noiseCovariance(1, 2);
        % sigma_{source | sink} = partial covariance which is the formula above (sigma_{source} - rho_{source, sink} / sigma_{sink} * rho_{sink, source})

        % Geweke-Granger spectral causality from source to sink
        restricted = spectra - abs(forward).^2 * residualVariance; % S_{sink} (f) - |H_{sink, source} (f)|^2 sigma_{source | sink}
        connectivity(iX, iY, abs(restricted) > 1e-60) = spectra(abs(restricted) > 1e-60) ./ restricted(abs(restricted) > 1e-60) - 1; % Geweke-Granger

      else % save duplicates to modify later

        duplicates(end+1, :) = [iX iY]; %#ok<AGROW>

      end

    end
  end

  % for duplicate indices, set the causality value to the maximum of all inflows for iX and outflows for iY
  for iDuplicate = 1:size(duplicates, 1)
    connectivity(duplicates(iDuplicate, 1), duplicates(iDuplicate, 2), :) = max( ...
      max(connectivity(duplicates(iDuplicate, 1), :, :), [], 2), ...
      max(connectivity(:, duplicates(iDuplicate, 2), :), [], 1) ...
      );
  end

end

%% Interpolate to desired frequencies & perform statistics if desired
if isfield(inputs, 'freq') && ~isempty(inputs.freq) && numel(inputs.freq) > 1
  connectivity = permute(interp1(freq, permute(connectivity, [3 1 2]), inputs.freq), [2 3 1]);
  % pValues = permute(interp1(freq, permute(pValues, [3 1 2]), inputs.freq), [2 3 1]);
  freq = inputs.freq;
end

pValues = NaN; % no parametric p-values for now

end

%% ======================================================== estimation for multivariate autoregression ========================================================
function [spectra, freq, forward] = bst_granger_spectral_spectrum(transfers, noiseCovariance, nFFT, Fs)
% BST_MVAR_SPECTRUM     Calculate the parametric spectra of a bivariate system
%                       with given MVAR coefficients & an estimate of the
%                       covariance matrix of the innovation (i.e. noise)
%                       process.
%
% Inputs:
%   transfers         - transfer matrices in AR process
%                       [A: 2 x 2P matrix, P = order]
%   noiseCovariance   - variance of residuals
%                       [C: 2 x 2 matrix]
%   nFFT              - number of FFT bins to calculate spectra
%                       [NF: positive number, usually power of 2]
%   Fs                - sampling frequency of data
%                       [FS: double, FS > freq(end)*2]
%
% Outputs:
%   spectra           - cross-spectrum between each pair of variables
%                       [S: 2 x 2 x NF/2 matrix]
%   freq              - frequencies used based on # of FFT bins
%                       [F: NF/2 x 1 matrix]
%   forward           - forward transform in frequency from source to sink
%                       [H: 2 x 2 x NF/2 matrix]
%   --> all outputs have length NF/2, ignoring frequenices past Fs/2
%
% Call:
%   spectra = bst_mvar_spectrum(transfers, C, 512, 200); % basic
%   spectra = bst_mvar_spectrum(transfers, C, 2048, 200); % add FFT interp
%   [spectra, freq] = bst_mvar_spectrum(transfers, C, 512, 200); % grab freqs
%   [~, ~, forward] = bst_mvar_spectrum(transfers, C, 64, 200); % causality

% Notes:
% The DTFT we want is
% H = I - sum_p C_p e^{-j 2 pi f/Fs p} = sum_p D_p e^{-j 2 pi f/Fs (p-1)} where D_1 = 1 and D_p = -C_{p-1} for p > 1
% MatLab's FFT provides
% G = sum_n x_n e^{-j 2 pi (k-1)/N (n-1)}
% so the matching is p = n and (k-1)/N = f/Fs, after vectorizing H.

% frequencies to estimate cross-spectra
freq = Fs/2*linspace(0, 1, nFFT/2 + 1);
freq(end) = [];

%% Inverse of transfer function in frequency
% Inverse transfer means the transfer function from the sources to the innovations. We calculate this at each frequency.
% The inverse transfer from source a to innovation b is
%                1 - \sum_{n=1}^N a_{ab} [n] e^{-j2pi * f * n}

inverse = fft(reshape([eye(2) -transfers], 4, [])', nFFT); % reshape so we can do a vector FFT quickly
inverse = inverse(1:nFFT/2, :); % restrict to the first symmetric half of the spectrum

%% Forward transfer in autoregressive model

% pieces of 2x2 inverse
forward = zeros(2, 2, nFFT/2); % an important caveat is that I did not reshape inverse earlier;
forward(1,1,:) = inverse(:,4); forward(1,2,:) = -inverse(:,3); % as a result, we have a column-wise index mapping: 4 = (2,2) and 3 = (1,2)
forward(2,1,:) = -inverse(:,2); forward(2,2,:) = inverse(:,1); % in addition, 2 = (2,1) and 1 = (1,1). then these elements fit the 2x2 matrix inverse
detInverse = inverse(:,1).*inverse(:,4) - inverse(:,3).*inverse(:,2); % the same thing happens here, using the indexing to avoid a reshape() call

% normalization by determinant to get inverse
forward = bst_bsxfun(@rdivide, forward, reshape(detInverse, [1 1 length(freq)])); % complete the inversion by dividing by frequency-dependent determinant

%% Cross-spectrum from forward model
% The forward transfer is the inverse of the inverse transfer at each frequency f. Denoted H(f), the power spectral density is then HH' at each frequency.

% the loop that we won't use
% for idxFreq = 1:nFFT
%   spectra(:, :, idxFreq) = H(:,:,idxFreq) * noiseCovariance * H(:,:,idxFreq)';
% end

% formula for the matrix multiplication
spectra(1,1,:) = ... % 1,1 element is H_11 C_11 H_11^* + H_12 C_12 H_11^* + H_11 C_12 H_12^* + H_12 C_22 H_12^* (and I combine the middle two into 2 Re{.})
  noiseCovariance(1,1) * forward(1,1,:) .* conj(forward(1,1,:)) ...
  + noiseCovariance(1,2) * real(forward(1,2,:) .* conj(forward(1,1,:))) * 2 ...
  + noiseCovariance(2,2) * forward(1,2,:) .* conj(forward(1,2,:));
spectra(1,2,:) = ... % 1,2 element is H_11 C_11 H_21^* + H_12 C_12 H_21^* + H_11 C_12 H_22^* + H_12 C_22 H_22^*
  noiseCovariance(1,1) * forward(2,1,:) .* conj(forward(1,1,:)) ...
  + noiseCovariance(1,2) * forward(2,2,:) .* conj(forward(1,1,:)) ...
  + noiseCovariance(1,2) * forward(2,1,:) .* conj(forward(1,2,:)) ...
  + noiseCovariance(2,2) * forward(1,2,:) .* conj(forward(1,2,:));
spectra(2,1,:) = conj(spectra(1,2,:)); % for speed, force the 2,1 element to be the conjugate of the 1,2 element so we have conjugate symmetry
spectra(2,2,:) = ... % 2,2 element is H_21 C_11 H_21^* + H_22 C_12 H_21^* + H_21 C_12 H_22^* + H_22 C_22 H_22^* (and I combine the middle two into 2 Re{.})
  noiseCovariance(1,1) * forward(2,1,:) .* conj(forward(2,1,:)) ...
  + noiseCovariance(1,2) * real(forward(2,2,:) .* conj(forward(2,1,:))) * 2 ...
  + noiseCovariance(2,2) * forward(2,2,:) .* conj(forward(2,2,:));

%% Normalize for sampling rate, and truncate if necessary

% normalization
forward = forward / sqrt(Fs);
spectra = spectra / Fs;

%% Confidence intervals
% taken from Kay, pp 194-195
% alpha = 1 - ci;
% original = -sqrt(2) * erfcinv( 2 * ( 1 - alpha/2) );
% lower = abs(spectra) * (1 - sqrt(2 * order / nTimes) * original);
% upper = abs(spectra) * (1 + sqrt(2 * order / nTimes) * original);

end %% <== FUNCTION END


function Y = sladdvec(X, v, d)
%SLADDVEC adds a vector to columns or rows of a matrix
%
% $ Syntax $
%   - Y = sladdvec(X, v, d)
%   - Y = sladdvec(X, v)
%
% $ Arguments $
%   - X:        The original matrix
%   - v:        The addend vector
%   - d:        The dimension along which the vector is to add
%   - Y:        The resultant matrix
%
% $ Description $
%   - Y = sladdvec(X, v, d) selects the most efficienct way to add a
%     vector v to every column/row of X. If d == 1, then v should be
%     a column vector, and is added to each column of X, if d == 2,
%     then v should be a row vector, and is added to each row of X.
%
%   - Y = sladdvec(X, v) will automatically determine d according to
%     the shape of v.
%
% $ Remarks $
%   - The implementation simply wraps the mex function vecop_core.
%
% $ History $
%   - Created by Dahua Lin, on Sep 10, 2006
%

if nargin < 3
    if size(v, 2) == 1
        d = 1;
    else
        d = 2;
    end
end

Y = vecop_core(X, v, d, 1);  % 1 is the opcode of addition in vecop_core


function [bcx,bcy] = specific_flow(xbd,ybd)
%regcavity_flow   Reference problem 5.3 default inflow condition
%   [bcx,bcy] = specific_flow(xbd,ybd);
%   input
%          xbd          x coordinate vector
%          ybd          y coordinate vector
%
%   specifies regularized cavity flow boundary condition
%   IFISS function: DJS; 6 March 2005.
% Copyright (c) 2005 D.J. Silvester, H.C. Elman, A. Ramage
bcx=0*xbd; bcy=0*xbd;
k=find(ybd==1 & xbd>-1 & xbd<1); bcx(k)=(1-xbd(k).*xbd(k)).*(1+xbd(k).*xbd(k));
return


% THE DIAGNOSTIC TOOLS (in the diag-folder):
%
% Covergence diagnostics
%   PSRF     - Potential Scale Reduction Factor
%   CPSRF    - Cumulative Potential Scale Reduction Factor
%   MPSRF    - Multivariate Potential Scale Reduction Factor
%   CMPSRF   - Cumulative Multivariate Potential Scale Reduction Factor
%   IPSRF    - Interval-based Potential Scale Reduction Factor
%   CIPSRF   - Cumulative Interval-based Potential Scale Reduction Factor
%   KSSTAT   - Kolmogorov-Smirnov goodness-of-fit hypothesis test
%   HAIR     - Brooks' hairiness convergence diagnostic
%   CUSUM    - Yu-Mykland convergence diagnostic for MCMC
%   SCORE    - Calculate score-function convergence diagnostic
%   GBINIT   - Initial iterations for Gibbs iteration diagnostic
%   GBITER   - Estimate number of additional Gibbs iterations
%
% Time series analysis
%   ACORR      - Estimate autocorrelation function of time series
%   ACORRTIME  - Estimate autocorrelation evolution of time series (simple)
%   GEYER_ICSE - Compute autocorrelation time tau using Geyer's
%                initial convex sequence estimator
%                (requires Optimization toolbox)
%   GEYER_IMSE - Compute autocorrelation time tau using Geyer's
%                initial monotone sequence estimator
%
% Kernel density estimation etc.:
%   KERNEL1  - 1D Kernel density estimation of data
%   KERNELS  - Kernel density estimation of independent components of data
%   KERNELP  - 1D Kernel density estimation, with automatic kernel width
%   NDHIST   - Normalized histogram of N-dimensional data
%   HPDI     - Estimates the Bayesian HPD intervals
%
% Manipulation of MCMC chains
%   THIN     - Delete burn-in and thin MCMC-chains
%   JOIN     - Join similar structures of arrays to one structure of arrays
%   BATCH    - Batch MCMC sample chain and evaluate mean/median of batches
%
% Misc:
%   CUSTATS   - Calculate cumulative statistics of data
%   BBPRCTILE - Bayesian bootstrap percentile
%   GRADCHEK  - Checks a user-defined gradient function using finite
%               differences.
%   DERIVATIVECHECK - Compare user-supplied derivatives to
%                     finite-differencing derivatives.
%


function determ = wilk04_determinant ( )

%*****************************************************************************80
%
%% WILK04_DETERMINANT returns the determinant of the WILK04 matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real DETERM, the determinant.
%
  determ = 0.9143E-04 * 0.7156E-04 * 0.9504E-04 * 0.7123E-04;

  return
end


function plot_fourier_approx(ai, n, m, normalized, color, line_width)

% This function will plot the fourier approximation, given a chain code (ai),
% number of harmonic elements (n), and number of points for reconstruction (m).
% Normalization can be applied by setting "normalized = 1".

    if (nargin < 5)
        color = 'b';
        line_width = 2;
    end

    if (nargin < 6)
        line_width = 2;
    end

    % Do Fourier approximatoin
    k = size(ai, 2);
    x_ = fourier_approx(ai, n, m, normalized);

    % Make it closed contour
    x = [x_; x_(1,1) x_(1,2)];

    plot(x(:,1), x(:,2), color, 'linewidth', line_width);

end


%==============================================================================
% This code is part of the Matlab-based toolbox
% FAIR - Flexible Algorithms for Image Registration.
% For details see
% - https://github.com/C4IR and
% - http://www.siam.org/books/fa06/
% ##2
%==============================================================================
%
% - initialize
%     data:            Hands,           see setup2DhandData, level = 5;
%     visualization:   viewImage2D,     see viewImage.m
%     interpolation:   splineInter,   see inter.m
%     distance:        SSD,             see distance.m
%     regularizer:     mfElastic,       see regularizer.m
% - initialize FAIR plots
% - run optimization
%     NPIR:            Non-Parametric Image Registration, Trust-Region
% ===============================================================================

clear; close all; help(mfilename)

setup2DhandData
level = 5; omega = ML{level}.omega; m = ML{level}.m;
imgModel('reset','imgModel','splineInter','regularizer','moments','theta',0.01);
distance('reset','distance','SSD');
regularizer('reset','regularizer','mfElastic','alpha',1000,'mu',1,'lambda',0);

[T,R] = imgModel('coefficients',ML{level}.T,ML{level}.R,omega);
xc    = getStaggeredGrid(omega,m); % starting guess and reference for regularization
Rc    = imgModel(R,omega,center(xc,m));

% - initialize FAIR plots
FAIRplots('set','mode','TR-mf','fig',1);
FAIRplots('init',struct('Tc',T,'Rc',R,'omega',omega,'m',m));

% - run Non-Parametric Image Registration (Gauss-Newton)
fctn = @(yc) NPIRobjFctn(T,Rc,omega,m,xc,yc);  fctn([]);
yc = TrustRegion(fctn,xc,'Plots',@FAIRplots);
%==============================================================================


function [D,S,C] = signed_distance_direction(P,V,F)
  % SIGNED_DISTANCE_DIRECTION Compute a direction which decreases signed
  % distance with respect to an input mesh (V,F) at a set of points P.
  %
  % [D,S,C] = signed_distance_direction(P,V,F)
  %
  % Inputs:
  %   P  #P by dim list of query points
  %   V  #V by dim list of mesh vertex positions
  %   F  #F by dim+1 list of mesh indices into V
  % Outputs:
  %   D  #P by dim list of normalized directions
  %   S  #P signed distances
  %   C  #P by dim list of closest points
  %

  dim = size(F,2);
  switch dim
  case 2
    % Facets are really edges
    E = F;
    % O(n*m) too slow...
    [T,sqrD] = project_to_lines(P,V(E(:,1),:),V(E(:,2),:),'Segments',true);
    % snap to line segment
    [~,J] = min(sqrD,[],2);
    T = T(sub2ind(size(T),1:size(P,1),J'))';
    C = V(E(J,1),:) + bsxfun(@times,T,(V(E(J,2),:)-V(E(J,1),:)));
    s = -2*(winding_number(V,E,P))+1;
    vec = C-P;
    % signed distance direction
    D = bsxfun(@times,s,normalizerow(vec));
    % signed distance
    S = s.*normrow(D);
  case 3
    [S,I,C,N] = signed_distance(P,V,F,'SignedDistanceType','pseudonormal');
    D = normalizerow(C-P);
    D = bsxfun(@times,sign(S),D);
    min_dist = 1e-5;
    too_close = abs(S) < min_dist;
    % Normals always point outside regardless of the eval point.
    D(too_close,:) = -N(too_close,:);
  end

  %% Find closest points
  %[sqrD,I,C] = point_mesh_squared_distance(P,V,F);
  %% Compute barycentric coordinates on closest faces
  %B = barycentric_coordinates(C,V(F(I,1),:),V(F(I,2),:),V(F(I,3),:));
  %% Direction to closest point
  %D = normalizerow(C-P);
  %% Determine which are too close to trust
  %min_sqr_dist = 1e-10;
  %too_close = sqrD < min_sqr_dist;
  %% Determine if closest point is on vertex, edge, or face AND too clost to
  %% trust direction.
  %epsilon = 1e-15;
  %on_face = (sum(B<=epsilon,2)==0) & too_close;
  %on_edge = (sum(B<=epsilon,2)==1) & too_close;
  %on_vertex = (sum(B<=epsilon,2)==2) & too_close;
  %% Determine which vertex or edge of that face
  %[~,which_vertex] = find(B(on_vertex,:)>epsilon);
  %[~,which_edge] = find(B(on_edge,:)<=epsilon);
  %% Compute normals for faces, vertices and edges
  %% Q: Are area normals OK?
  %% H: [Bærentzen 2002/2005] suggests angle weighting.
  %N_face = normalizerow(normals(V,F));
  %N_vertex = per_vertex_normals(V,F);
  %% map to corners
  %N_vertex = N_vertex(F,:);
  %[N_edge,E,EMAP] = per_edge_normals(V,F);
  %% map to directed edges
  %N_edge = N_edge(EMAP,:);
  %% This is an expensive way to find out if inside/outside a closed mesh
  %w = winding_number(V,F,P);
  %% Flip sign for interior points
  %S = (1-2*w);
  %D = bsxfun(@times,S,D);
  %% Use inverse normals for those that are too close
  %if any(on_vertex)
  %  D(on_vertex,:) = ...
  %    -N_vertex(sub2ind(size(F),I(on_vertex),which_vertex),:);
  %end
  %if any(on_edge)
  %  D(on_edge,:) = -N_edge(sub2ind(size(F),I(on_edge),which_edge),:);
  %end
  %if any(on_face)
  %  D(on_face,:) = -N_face(I(on_face),:);
  %end
end


function [fProbability_] = callback_LogLikelihoodA1A2Value(fAValues, caCatalogs, mControl, fBValue)
% function [fProbability] = callback_LogLikelihoodAValue(fAValue, caCatalogs, mControl)
% -------------------------------------------------------------------------------------
% Helper callback-function for calc_MaxLikelihoodA.m
%   Computes the negative log-likelihood sum of a given a- and fixed b-value for a
%   set of given catalogs
%
% Input parameters:
%   fAValue        a-value
%   caCatalogs      Cell array containing the set of catalogs
%   mControl        Controlmatrix containing informations about the single catalogs
%                   mControl(n,:) contains information about caCatalogs{n}
%                   Column 1: Starting time of catalog
%                   Column 2: Magnitude of completeness
%                   Column 3: Starting magnitude bin
%                   Column 4: Magnitude bin stepsize (must be 0.1)
%   fBValue         Fixed b-value
%
% Output parameters:
%   fProbability    Negative log-likelihood of the given a- and b-value for the set of given catalogs
%
% Danijel Schorlemmer
% July 5, 2002

% Init variable
global fProbability;
vProbabilities = [];

[nRow_, nColumn_] = size(mControl);
fTotalLength_ = mControl(nRow_,6)-mControl(1,1);

% Loop over all catalogs
for nCnt_ = 1:length(caCatalogs)
  % Extract catalog from cell array
  mCatalog_ = caCatalogs{nCnt_};
  % Determine maximum magnitude of catalog
  fMaxMag_ = max(mCatalog_(:,6));
  % Set up vector of available magnitude bins
  vCnt_ = (mControl(nCnt_,2):mControl(nCnt_,4):(fMaxMag_+mControl(nCnt_,4)))'; % Add one more magnitude bin for later use of diff()
  % Compute lengths of periods and ajust thea-value
  fTimeLength_ = mControl(nCnt_,6) - mControl(nCnt_,1);
  fTimeRatio_ = fTimeLength_/fTotalLength_;
  % Compute the cumulative FMD
  if mControl(nCnt_,5) == 1;  % this is activity rate 1
      fA_ = fAValues(1) + log10(fTimeRatio_);
      vNumber_ = 10.^(fA_ - (fBValue * vCnt_));
  elseif  mControl(nCnt_,5) == 2;  % this is activity rate 1
      fA_ = fAValues(2) + log10(fTimeRatio_);
      vNumber_ = 10.^(fA_ - (fBValue * vCnt_));
  end
  % Determine the number of events in each magnitude bin
  mPredictionFMD_ = -diff(vNumber_);
  % Create the FMD for the period of observation
  vObservedFMD_ = histogram(mCatalog_(:,6), mControl(nCnt_,2):mControl(nCnt_,4):fMaxMag_);
  % Calculate the likelihoods for both of the models
  vProb_ = calc_log10poisspdf(vObservedFMD_', mPredictionFMD_);
  % Return the values (multiply by -1 to return the lowest value for the highest probability
  vProbabilities = [vProbabilities; sum(vProb_)];
end
% Sum the probabilities for all given catalogs
fProbability_ = (-1) * sum(vProbabilities);

fProbability = fProbability_;


% Fig. 5.28  Feedback Control of Dynamic Systems, 6e
%             Franklin, Powell, Emami
% script for LEFT side of Figure 5.28.  Use fig5_28b to see RIGHT side.

clf
n=[1 2];
d=conv([1 1 0],[1 13]);
nc=91*[1 .05];
dc=[1 .01];
nol=conv([0 0 n],nc);
dol=conv(d,dc);
 rlocus(nol,dol);
 hold on
 title('Fig.5.28a Root locus for lead plus lag')
 axis([-20 4 -9 9])
 z=0:.1:.9;
 wn=2:2:19;
 sgrid(z, wn)
 dcl=nol+dol;
 r=roots(dcl);
 plot(r,'*')
 hold off


function [PDR, deltaHD, deltaSEN, deltaPRO, deltaCOL, CBR] = CV2XMode4(beta,lambda,Pt,S,B);

% CV2XMode4 is the main script of the implementation of the analytical
% models of the communication performance of C-V2X or LTE-V Mode 4
% described in the following paper:
%
%    Manuel Gonzalez-Martín, Miguel Sepulcre, Rafael Molina-Masegosa, Javier Gozalvez,
%    "Analytical Models of the Performance of C-V2X Mode 4 Vehicular Communications",
%    IEEE Transactions on Vehicular Technology, Vol. 68, Issue 2, Feb. 2019. DOI: 10.1109/TVT.2018.2888704
%    Final version available at: https://ieeexplore.ieee.org/document/8581518
%    Post-print version available at: https://arxiv.org/abs/1807.06508
%
% The paper presents analytical models for the average PDR (Packet Delivery Ratio) as a
% function of the distance between transmitter and receiver, and for the four different
% types of transmission errors that can be encountered in C-V2X or LTE-V Mode 4. The models
% have been validated for a wide range of transmission parameters and traffic densities by
% comparing the results obtained with the analytical models to those obtained with a C-V2X
% or LTE-V Mode 4 simulator implemented by the authors over the Veins simulation platform.
%
% CV2XMode4.m is the main script you have to run to get the PDR curve as a function of the
% distance for a given set of parameters, and the probability of each of the four
% transmission errors.
%
% The resulting figures are compared with simulations when the same configuration
% is available in the ./simulations folder.
%
% The resulting figures are stored in the ./fig folder.
%
% Input parameters:
%    beta: traffic density in veh/m. Values tested: 0.1, 0.2 and 0.3.
%    lambda: packet transmission frequency in Hz. Values tested: 10 and 20.
%    Pt: transmission power in dBm. Values tested: 20 and 23.
%    S: number of sub-channels. Values tested: 2 and 4.
%    B: packet size in bytes. Values tested: 190.
%
% Output metrics:
%    PDR: Packet Delivery Ratio for different Tx-Rx distances
%    deltaHD: probability of packet loss due to half-duplex transmissions for different Tx-Rx distances
%    deltaSEN: probability of packet loss due to a received signal power below the sensing power threshold for different Tx-Rx distances
%    deltaPRO: probability of packet loss due to propagation effects for different Tx-Rx distances
%    deltaCOL: probability of packet loss due to packet collisions for different Tx-Rx distances
%    CBR: Channel Busy Ratio between 0 and 1
%
% Overall code structure:
%     CV2XMode4.m
%         |---->   CV2XMode4_common.m   ----> get_PL_SH.m, get_SINRdistribution.m, get_BLER.m
%         |---->   CV2XMode4_Step2.m    ----> get_PL_SH.m, get_SINRdistribution.m, get_BLER.m
%         |---->   CV2XMode4_Step3.m    ----> get_PL_SH.m, get_SINRdistribution.m, get_BLER.m
%
% The equations that are identified with a number between brackets in this script are the ones
% that also appear in the paper so that they can be easily identified.

    disp('=========================================================')
    disp('Input parameters:')
    fprintf('  beta   = %f veh/m \n', beta)
    fprintf('  lambda = %d Hz \n', lambda)
    fprintf('  Pt     = %d dBm \n', Pt)
    fprintf('  S      = %d subchannels \n', S)
    fprintf('  B      = %d bytes \n', B)

    distance = [0:25:500];  % Tx-Rx distances to evaluate (m)

    Psen = -90.5;               % Sensing threshold (dBm)

    step_dB = 0.1;              % Discrete steps to compute the PDF of the SNR and SINR (dB)

    % Calculate the number of RBs that are needed to transmit each message
    % and the coding used based on the number of sub-channels and packet size:
    switch B
        case 190
            switch S
                case 4
                    coding = 1;   % Used to identify the BLER vs SINR curve to be used (190 Bytes, QPSK r=0.7, Vr = 280 km/h)
                    RBs = 10;     % Number of RBs needed to transmit the DATA field of each message
                case 2
                    coding = 2;   % Used to identify the BLER vs SINR curve to be used (190 Bytes, QPSK r=0.5, Vr = 280 km/h)
                    RBs = 12;     % Number of RBs needed to transmit the DATA field of each message
            end
    end

    noise = -95 - 10*log10(50/RBs);     % Noise corresponding to the DATA field of each message. Assumes a noise figure of 9dB and 10MHz channel (background noise of -95dBm). The total number of RBs in 10MHz is 50.

    % Calculate errors associated to HD, SEN and PRO:
    [ deltaHD_pre , deltaSEN_pre , deltaPRO_pre ] = CV2XMode4_common( lambda , Pt , distance, Psen , step_dB , noise , coding );

    % Calculate probability of collision considering only Step 2 and CBR:
    [ deltaCOL2_pre , CBR ] = CV2XMode4_Step2( beta , lambda , Pt , S , distance , Psen , step_dB , noise , coding , deltaPRO_pre );

    % Calculate weighting factor alpha using equation (22):
    if CBR < 0.2
        alpha = 0;
    elseif CBR <= 0.7
        alpha = 2*CBR - 0.4;
    else
        alpha = 1;
    end

    % Calculate probability of collision considering only Step 3:
    if alpha < 1
         [ deltaCOL3_pre ] = CV2XMode4_Step3( beta , lambda , Pt , S , distance , Psen , step_dB , noise , coding , deltaPRO_pre );
    else
        deltaCOL3_pre = 0;
    end

    % Calculate final probabilities for each type of error:
    deltaHD   = deltaHD_pre;                               % Equation (6.1)
    deltaSEN  = deltaSEN_pre .* (1 - deltaHD);             % Equation (6.2)
    deltaPRO  = deltaPRO_pre .* (1 - deltaHD_pre) .* (1 - deltaSEN_pre);  % Equation (6.3)
    deltaCOL2 = deltaCOL2_pre .* (1 - deltaHD_pre) .* (1 - deltaSEN_pre) .* (1 - deltaPRO_pre); % Equation (6.4)
    deltaCOL3 = deltaCOL3_pre .* (1 - deltaHD_pre) .* (1 - deltaSEN_pre) .* (1 - deltaPRO_pre); % Equation (6.5)
    deltaCOL = alpha*deltaCOL2 + (1-alpha)*deltaCOL3; % Equation (21)

    % Calculate PDR:
    PDR = 1 - deltaHD - deltaSEN - deltaPRO - deltaCOL; % Equation (6)

    % Presentation of the obtained results:

    % Load simulation results (if available):
    simulation_path = [pwd '\simulations\' num2str(S) 'subchannels\'  num2str(Pt) 'dBm'];
    sim_file = [ simulation_path '\FALLOS_LOS_D2D_' num2str(beta*1000) 'vehpkm_16Alg_' num2str(1/lambda) 's_' num2str(8*B) 'bit.fig' ];
    fig_name = ['CV2XMode4_beta' num2str(beta) '-lambda' num2str(lambda) '-Pt' num2str(Pt) '-S' num2str(S) '-B' num2str(B)];

    if exist(sim_file,'file')==2
        open(sim_file)
        lh = findall(gca, 'type', 'line');
        X = get(lh,'xdata');
        Y = get(lh,'ydata');
        deltaHD_sim = Y{5};
        deltaSEN_sim = Y{1};
        deltaPRO_sim = Y{4};
        deltaCOL_sim = Y{3};
        close

        figure; hold on; grid on; box on
        plot(distance , deltaHD_sim/100,'b-','LineWidth',2)
        plot(distance , deltaSEN_sim/100,'m-','LineWidth',2)
        plot(distance , deltaPRO_sim/100,'r-','LineWidth',2)
        plot(distance , deltaCOL_sim/100,'k-','LineWidth',2)

    else
        figure; hold on; grid on; box on
    end

    % Plot errors:
    ylabel('Error probability')
    xlabel('Distance [m]')
    plot(distance , deltaHD,'b--','LineWidth',2)
    plot(distance , deltaSEN,'m--','LineWidth',2)
    plot(distance , deltaPRO,'r--','LineWidth',2)
    plot(distance , deltaCOL,'k--','LineWidth',2)
    ylim([0 1])

    if exist(sim_file,'file')==2
        legend('\delta_{HD} Simulation','\delta_{SEN} Simulation','\delta_{PRO} Simulation','\delta_{COL} Simulation','\delta_{HD} Analytical','\delta_{SEN} Analytical','\delta_{PRO} Analytical','\delta_{COL} Analytical','Location','northwest')
    else
        legend('\delta_{HD} Analytical','\delta_{SEN} Analytical','\delta_{PRO} Analytical','\delta_{COL} Analytical','Location','northwest')
    end
    hgsave(['fig/' fig_name '_errors.fig'])

    % Plot PDR:
    figure; hold on; grid on; box on
    if exist(sim_file,'file')==2
        PDR_sim = (100 - deltaHD_sim - deltaSEN_sim - deltaPRO_sim - deltaCOL_sim)/100;
        plot(distance,PDR_sim,'b-','LineWidth',2)
        plot(distance,PDR,'b--','LineWidth',2)
        legend('PDR Simulation','PDR Analytical')
    else
        plot(distance,PDR,'--')
        legend('PDR Analytical')
    end
    ylim([0 1])
    ylabel('PDR')
    xlabel('Distance [m]')
    hgsave(['fig/' fig_name '_PDR.fig'])

    fprintf('Channel load: CBR = %.2f, alpha = %f \n',CBR, alpha)

    if exist(sim_file,'file')==2
        MAD_HD  = mean( abs(deltaHD*100 - deltaHD_sim) );    % Equation (35)
        MAD_SEN = mean( abs(deltaSEN*100 - deltaSEN_sim) );  % Equation (35)
        MAD_PRO = mean( abs(deltaPRO*100 - deltaPRO_sim) );  % Equation (35)
        MAD_COL = mean( abs(deltaCOL*100 - deltaCOL_sim) );  % Equation (35)
        MAD     = mean( abs(PDR - PDR_sim) * 100 );          % Equation (35)

        disp('Mean Absolute Deviation results : ')
        fprintf('PDR \tHD  \tSEN \tPRO \tCOL \n')
        fprintf('%.2f\t%.2f\t%.2f\t%.2f\t%.2f \n', MAD, MAD_HD, MAD_SEN, MAD_PRO, MAD_COL)
    end

    disp('=========================================================')

 return


% RES = pointOp(IM, LUT, ORIGIN, INCREMENT, WARNINGS)
%
% Apply a point operation, specified by lookup table LUT, to image IM.
% LUT must be a row or column vector, and is assumed to contain
% (equi-spaced) samples of the function.  ORIGIN specifies the
% abscissa associated with the first sample, and INCREMENT specifies the
% spacing between samples.  Between-sample values are estimated via
% linear interpolation.  If WARNINGS is non-zero, the function prints
% a warning whenever the lookup table is extrapolated.
%
% This function is much faster than MatLab's interp1, and allows
% extrapolation beyond the lookup table domain.  The drawbacks are
% that the lookup table must be equi-spaced, and the interpolation is
% linear.

% Eero Simoncelli, 8/96.

function res = pointOp(im, lut, origin, increment, warnings)

%% NOTE: THIS CODE IS NOT ACTUALLY USED! (MEX FILE IS CALLED INSTEAD)

fprintf(1,'WARNING: You should compile the MEX version of "pointOp.c",\n         found in the MEX subdirectory of matlabPyrTools, and put it in your matlab path.  It is MUCH faster.\n');

X = origin + increment*[0:size(lut(:),1)-1];
Y = lut(:);

res = reshape(interp1(X, Y, im(:), 'linear', 'extrap'),size(im));


function [qp,QP_ep] = epose2qpose(ep)

% EPOSE2QPOSE  Euler-specified to quaternion-specified pose conversion.
%
%   QP = EPOSE2QPOSE(EP) returns a full 7-pose QP=[X;Q] from a full 6-pose
%   QE=[X;E], where X is 3D opsition and Q and E are 3D orientations.
%
%   [QP,Jep] = EPOSE2QPOSE(...) returns also the Jacobian matrix
%
%   See also QPOSE2EPOSE, EULERANGLES, QUATERNION, FRAME.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

if any(size(ep) ~= [6,1])
    warning('Input Euler-pose should be a column 6-vector')
end

qp            = zeros(7,1);  % empty quaternion pose
qp(1:3)       = ep(1:3);     % position copy
P             = eye(3);      % Jacobian of copy function
[qp(4:7),Q_e] = e2q(ep(4:6));% orientation and Jacobian

QP_ep         = [P zeros(3);zeros(4,3) Q_e]; % Full Jacobian

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   SLAMTB is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function varargout = dblquad(varargin)
%DBLQUAD   Complete definite integral of SPHEREFUN.
%   I = DBLQUAD(F, a, b, c, d), returns the definite integral of a SPHEREFUN over
%   the region [a, b, c, d].
%
%   This function is a wrapper for quad2d.
%
% See also SPHEREFUN/QUAD2D, SPHEREFUN/INTEGRAL2, SPHEREFUN/SUM2.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

[varargout{1:nargout}] = dblquad@separableApprox(varargin{:});

end


function [lab,q] = psdeig(x,K)
% [lab,q] = psdeig(x,K)
%
% PSDEIG  Computes spectral coefficients of x w.r.t. K
%   Arguments "q" is optional - without it's considerably faster.
%   FLOPS indication: 1.3 nk^3 versus 9.0 nk^3 for nk=500,
%                     1.5 nk^3        9.8 nk^3 for nk=50.
%
% **********  INTERNAL FUNCTION OF SEDUMI **********
%
% See also sedumi

% This file is part of SeDuMi 1.1 by Imre Polik and Oleksandr Romanko
% Copyright (C) 2005 McMaster University, Hamilton, CANADA  (since 1.1)
%
% Copyright (C) 2001 Jos F. Sturm (up to 1.05R5)
%   Dept. Econometrics & O.R., Tilburg University, the Netherlands.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% Affiliation SeDuMi 1.03 and 1.04Beta (2000):
%   Dept. Quantitative Economics, Maastricht University, the Netherlands.
%
% Affiliations up to SeDuMi 1.02 (AUG1998):
%   CRL, McMaster University, Canada.
%   Supported by the Netherlands Organization for Scientific Research (NWO).
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
% 02110-1301, USA

Ks = K.s;
if isempty(Ks),
    lab = [];
    return
end
Kq  = Ks .* Ks;
nr  = K.rsdpN;
nc  = length(Ks);
N   = sum(Kq) + sum(Kq(nr+1:end));
xi  = length(x) - N;
ei  = 0;
lab = zeros(sum(Ks),1);
needv = nargout > 1;
if needv,
    q = zeros(N,1);
    vi = 0;
end
for i = 1 : nc,
    ki = Ks(i);
    qi = Kq(i);
    XX = x(xi+1:xi+qi);
    xi = xi+qi;
    if i > nr,
        XX = XX + 1i*x(xi+1:xi+qi);
        xi = xi+qi;
    end
    XX = reshape(XX,ki,ki);
    XX = XX + XX';
    try
        if needv,
            [QQ,DD] = eig(XX);
            DD = diag(DD);
        else
            DD = eig(XX);
        end
    catch
        % If eig() fails to converge, fall back onto svd(). This costs
        % more, so we don't want to use it every time.
        [QQ,DD,VV] = svd(XX);
        DD = diag(DD).*sign(real(sum(conj(QQ).*VV)'));
    end
    lab(ei+1:ei+ki) = 0.5*DD;
    ei = ei + ki;
    if needv,
        q(vi+1:vi+qi) = real(QQ);
        vi = vi + qi;
        if i > nr,
            q(vi+1:vi+qi) = imag(QQ);
            vi = vi + qi;
        end
    end
end


function channels = EPW(N, beta)
m = log2(N);
channels = zeros(N, 1);
for i = 0 : N - 1
    bin_seq_str = dec2bin(i, m);
    bin_seq = zeros(m, 1);
    for j = 1 : m
        if bin_seq_str(j) == '1'
            bin_seq(j) = 1;
        end
    end
    bin_seq = bin_seq(m : -1 : 1);
    sum = 0;
    for j = 1 : m
        if m >= 9
            sum = sum + bin_seq(j) * (beta^(j - 1) + 0.221 * 0.9889^(j - 1) - bin_seq(9) * 0.0371 * 0.5759^(j - 1) - bin_seq(8) * 0.047 * 0.4433^(j - 1));
        else
            if m == 8
                sum = sum + bin_seq(j) * (beta^(j - 1) + 0.221 * 0.9889^(j - 1) - bin_seq(8) * 0.047 * 0.4433^(j - 1));
            else
                sum = sum + bin_seq(j) * (beta^(j - 1) + 0.221 * 0.9889^(j - 1));
            end
        end
    end
    channels(i + 1) = sum;
end
end


% Pattern Recognition Tools (PRTools Guide)
% Version 5.1.1 14-May-2014
%
%Datasets and Mappings (just most important routines)
%---------------------
%prdataset      - Define dataset from datamatrix and labels
%datasets       - List information on datasets (just help, no command)
%prdatafile     - Define dataset from directory of object files
%datafiles      - List information on datafiles (just help, no command)
%cat2data       - Create categorical dataset
%classnames     - Retrieve names of classes
%classsizes     - Retrieve sizes of classes
%feat2lab       - Label dataset by one of its features and remove this feature
%gencirc        - Generation of a one-class circular dataset
%genclass       - Generate class frequency distribution
%genlab         - Generate dataset labels
%getlab         - Retrieve object labels from datasets and mappings
%getnlab        - Retrieve nummeric object labels from dataset
%setfeatlab     - Set feature labels in dataset
%getfeatlab     - Get feature labels in dataset
%getfeat        - Retrieve feature labels from datasets and mappings
%setdat         - Change data in dataset for classifier output
%setdata        - Change data in dataset or mapping
%getdata        - Retrieve data from dataset or mapping
%setlabels      - Change labels of dataset or mapping
%getlabels      - Retrieve labels from a dataset
%setprior       - Reset class prior probabilities of dataset
%getprior       - Retrieve class prior probabilities from dataset
%addlabels      - Add additional labelling
%changelablist  - Change current active labeling
%misval         - Fix missing values in a dataset
%multi_labeling - List information on multi-labeling (help only)
%prmapping      - Define and retrieve mapping and classifier from data
%mappings       - List information on mappings (just help, no command)
%renumlab       - Convert labels to numbers
%matchlab       - Match different labelings
%prarff         - Convert ARFF file (WEKA) to PRTools dataset
%remclass       - Remove a class from a dataset
%seldat         - Retrieve a part of a dataset
%selclass       - Retrieve a class from a dataset
%
%Data Generation (more in prdatasets)
%---------------
%circles3d   - Create a dataset containing 2 circles in 3 dimensions
%lines5d     - Create a dataset containing 3 lines in 5 dimensions
%gendat      - Random sampling of datasets for training and testing
%gensubsets  - Generation of a consistent series of subsets of a dataset
%gendatgauss - Generation of multivariate Gaussian distributed data
%gendatb     - Generation of banana shaped classes
%gendatc     - Generation of circular classes
%gendatd     - Generation of two difficult classes
%gendath     - Generation of Highleyman classes
%gendati     - Generation of random windows from images
%gendatk     - Nearest neighbour data generation
%gendatl     - Generation of Lithuanian classes
%gendatm     - Generation of 8 2d classes
%gendatp     - Parzen density data generation
%gendatr     - Generate regression dataset from data and target values
%gendats     - Generation of two Gaussian distributed classes
%gendatw     - Sample dataset by given weigths
%gendatv     - Generation of a very large dataset
%gentrunk    - Generation of Trunk's example
%prdata      - Read data from file
%seldat      - Select classes / features / objects from dataset
%spirals     - Generation of a two-class spiral dataset
%getwindows  - Get pixel feature vectors around given pixels in image dataset
%prdataset   - Read existing dataset from file
%prdatasets  - Overview and download of standard datasets
%
%Datafiles
%---------
%prdatafile     - Define datafile from set of files in directory
%createdatafile - Save datafile, store intermediate result as raw datafile
%savedatafile   - Save datafile, store intermediate result as mature datafile
%filtm          - Mapping for arbitrary processing of a datafile
%prdatafiles    - Overview and download of standard datafiles
%
%Linear and Quadratic Classifiers (*operate on datasets and datafiles)
%--------------------------------
%fisherc     - Minimum least square linear classifier
%ldc         - Normal densities based linear (muli-class) classifier
%loglc       - Logistic linear classifier
%nmc         - Nearest mean linear classifier
%nmsc        - Scaled nearest mean linear classifier
%quadrc      - Quadratic classifier
%qdc         - Normal densities based quadratic (multi-class) classifier
%udc         - Uncorrelated normal densities based quadratic classifier
%klldc       - Linear classifier based on KL expansion of common cov matrix
%pcldc       - Linear classifier based on PCA expansion on the joint data
%polyc       - Add polynomial features and run arbitrary classifier
%subsc       - Subspace classifier
%statslinc   - Linear classifier from the Stats toolbox
%
%classc      - Converts a mapping into a classifier
%labeld      - Find labels of objects by classification
%logdens     - Convert density estimates to log-densities for more accuracy
%rejectc     - Creates reject version of exisiting classifier
%testc       - General error estimation routine for trained classifiers
%
%Other Classifiers
%-----------------
%knnc        - k-nearest neighbour classifier (find k, build classifier)
%testk       - Error estimation for k-nearest neighbour rule
%edicon      - Edit and condense training sets
%statsknnc   - k-nearest neighbour classifier from the Stats toolbox
%
%weakc       - Weak classifier
%stumpc      - Decision stump classifier
%adaboostc   - ADABoost classifier
%
%parzenc     - Parzen classifier
%parzendc    - Parzen density based classifier
%testp       - Error estimation for Parzen classifier
%
%treec       - Construct binary decision tree classifier
%dtc         - Decision tree classifier, rewritten, also for nominal features
%statsdtc    - Decision tree classifier from the Stats toolbox
%randomforestc - Breiman's random forest classifier
%naivebc     - Naive Bayes classifier
%statsnbc    - Naive Bayes classifier from the Stats toolbox
%bpxnc       - Feed forward neural network classifier by backpropagation
%lmnc        - Feed forward neural network by Levenberg-Marquardt rule
%neurc       - Automatic neural network classifier
%perlc       - Linear perceptron
%rbnc        - Radial basis neural network classifier
%rnnc        - Random neural network classifier
%ffnc        - Feed-forward neural net classifier back-end routine
%bagc        - Feature set classifier, e.g. for multiple-instance learning
%
%fdsc        - Feature based dissimilarity space classifier
%mdsc        - Manhatten distance feature based dissimilarity space classifier
%vpc         - Voted perceptron classifier
%drbmc       - Discriminative restricted Boltzmann machine classifier
%
%libsvc      - Support vector classifier by LIBSVM
%nulibsvc    - Support vector classifier by LIBSVM
%svc         - Support vector classifier
%svo         - Support vector optimizer
%nusvc       - Support vector classifier
%nusvo       - Support vector optimizer
%rbsvc       - Radial basis SV classifier
%kernelc     - General kernel/dissimilarity based classification
%
%Normal Density Based Classification
%-----------------------------------
%distmaha    - Mahalanobis distance
%meancov     - Estimation of means and covariance matrices from multiclass data
%nbayesc     - Bayes classifier for given normal densities
%ldc         - Normal densities based linear (muli-class) classifier
%qdc         - Normal densities based quadratic (multi-class) classifier
%udc         - Uncorrelated normal densities based quadratic classifier
%mogc        - Mixture of gaussians classification
%testn       - Error estimate of discriminant on normal distributions
%
%Feature Selection
%-----------------
%feateval    - Evaluation of a feature set
%featrank    - Ranking of individual feature permormances
%featsel     - Feature Selection
%featselb    - Backward feature selection
%featself    - Forward feature selection
%featsellr   - Plus-l-takeaway-r feature selection
%featseli    - Feature selection on individual performance
%featselm    - Feature selection map, general routine for feature selection
%featselo    - Branch and bound feature selection
%featselp    - Floating forward feature selection
%featselv    - Selection of varying features
%
%Classifiers and tests (general)
%-------------------------------
%bayesc      - Bayes classifier by combining density estimates
%classim     - Classify image using a given classifier
%classc      - Convert mapping to classifier
%labeld      - Find labels of objects by classification
%cleval      - Classifier evaluation (learning curve)
%clevalb     - Classifier evaluation (learning curve), bootstrap version
%clevalf     - Classifier evaluation (feature size curve)
%clevals     - Classifier evaluation (feature /learning curve), bootstrap
%confmat     - Computation of confusion matrix
%costm       - Cost mapping, classification using costs
%prcrossval  - Crossvalidation
%cnormc      - Normalisation of classifiers
%disperror   - Display error matrix with information on classifiers and datasets
%labelim     - Construct image of labeled pixels
%logdens     - Convert density estimates to log-densities for more accuracy
%loso        - Leave_one_set_out crossvalidation
%mclassc     - Computation of multi-class classifier from 2-class discriminants
%regoptc     - Optimisation of regularisation and complexity parameters
%reject      - Compute error-reject trade-off curve
%prroc       - Receiver-operator curve (ROC)
%shiftop     - Shift operating point of classifier
%testc       - General error estimation routine for trained classifiers
%testd       - Error of dataset applied to given classifier
%testauc     - Estimate error as area under the ROC
%
%Mappings
%--------
%affine      - Construct affine (linear) mapping from parameters
%bhatm       - Two-class Bhattacharryya mapping
%cmapm       - Compute some special maps
%datasetm    - Mapping conversion dataset
%disnorm     - Normalization of a dissimilarity matrix
%featselm    - Feature selection map, general routine for feature selection
%fisherm     - Fisher mapping
%chernoffm   - Chernoff mapping
%invsigm     - Inverse sigmoid map
%filtm       - Arbitrary operation on datafiles/datasets, object by object
%mapm        - Arbitrary mapping operation on doubles and datasets
%gaussm      - Mixture of Gaussians density estimation
%kernelm     - Kernel mapping
%klm         - Decorrelation and Karhunen Loeve mapping (PCA)
%klms        - Scaled version of klm, useful for prewhitening
%knnm        - k-Nearest neighbor density estimation
%mclassm     - Computation of mapping from multi-class dataset
%prmap       - General routine for computing and executing mappings
%mappingtools - Macro defining some mappings
%nlfisherm   - Nonlinear Fisher mapping
%normm       - Object normalization map
%parzenm     - Parzen density estimation
%parzenml    - Optimization of smoothing parameter in Parzen density estimation.
%pcam        - Principal Component Analysis
%pcaklm      - Backend routine for PC and KL mappings
%proxm       - Proximity mapping and kernel construction
%reducm      - Reduce to minimal space mapping
%remoutl     - Remove outliers
%rejectm     - Creates rejecting mapping
%scalem      - Compute scaling data
%sigm        - Simoid mapping
%spatm       - Augment image dataset with spatial label information
%tsnem       - tSNE mapping
%sammonm     - Multi-dimensional scaling by Sammon mapping
%userkernel  - User supplied kernel definition
%
%gtm         - Fit a Generative Topographic Mapping (GTM) by EM
%plotgtm     - Plot a Generative Topographic Mapping in 2D
%som         - Simple routine computing a Self-Organizing Map (SOM)
%prplotsom   - Plot a Self-Organizing Map in 2D
%
%Classifier combiners
%--------------------
%averagec    - Combining linear classifiers by averaging coefficients
%baggingc    - Bootstrapping and aggregation of classifiers
%dcsc        - Dynamic Classifier Selecting Combiner
%modselc     - Model Selection Combiner (Static selection)
%rsscc       - Random subspace combining classifier
%votec       - Voting classifier combiner
%wvotec      - Weighted voting classifier combiner
%maxc        - Maximum classifier combiner
%minc        - Minimum classifier combiner
%meanc       - Mean classifier combiner
%medianc     - Median classifier combiner
%mlrc        - Muli-response linear regression combiner
%naivebcc    - Naive Bayes classifier combiner
%perc        - Percentile combiner
%prodc       - Product classifier combiner
%traincc     - Train combining classifier
%fixedcc     - Fixed combiner construction, back end
%parsc       - Parse classifier or map
%rejectc     - Creates reject version of exisiting classifier
%parallel    - Parallel combining of classifiers
%bagcc       - Feature set combining classifier
%stacked     - Stacked combining of classifiers
%sequential  - Sequential combining of classifiers
%
%
%Regression
%----------
%linearr     - Linear regression
%ridger      - Ridge regression
%lassor      - LASSO
%svmr        - Support vector regression
%ksmoothr    - Kernel smoother
%knnr        - k-nearest neighbor regression
%pinvr       - Pseudo-inverse regression
%plsr        - Partial least squares regression
%plsm        - Partial least squares mapping
%gpr         - Gaussian Process regression
%
%testr       - Mean squared regression error
%rsquared    - R^2-statistic
%
%Handling images in datasets and datafiles
%-----------------------------------------
%data2im     - Convert dataset to image
%getobjsize  - Retrieve image size of feature images in datasets
%getfeatsize - Retrieve image size of object images in datasets
%obj2feat    - Transform object images to feature images in dataset
%feat2obj    - Transform feature images to object images in dataset
%im2feat     - Convert image to feature in dataset
%im2obj      - Convert image to object in dataset
%imsize      - Retrieve size of specific image in datafile
%im_patch    - Find / generate patches in object images
%band2obj    - Convert image bands to objects in dataset
%bandsel     - Select image bands in dataset or datafile
%selectim    - Select image in multi-band object image dataset/datafile
%show        - Display objects in datasets, datafiles and mappings
%im_dbr      - Image Database Retrieval GUI
%
%Operations on images in datasets and datafiles
%----------------------------------------------
%classim     - Classify image using a given classifier
%doublem     - Convert datafile images into double
%filtim      - Image operation on objects in datafiles/datasets
%spatm       - Augment image dataset with spatial label information
%im_box            - Bounding box
%im_center         - Center image
%im_fft            - FFT transform (and more)
%im_gauss          - Gaussian filtering by Matlab
%im_gray           - Multi-band to gray-value conversion
%im_hist_equalize  - Histogram equalization
%im_invert         - Invert image
%im_label          - Labeling binary images
%im_norm           - Normalize images w.r.t. mean and variance
%im_resize         - Resize images
%im_rotate         - Rotate images
%im_scale          - Scale images
%im_select_blob    - Select largest blob
%im_stretch        - Contrast stretching of images
%im_threshold      - Threshold images
%im_unif           - Uniform filtering
%
%Feature extraction from images in datasets and datafiles
%--------------------------------------------------------
%histm         - Convert images to histograms. Trains the bin positions
%im_hist       - Convert images to histograms for fixed bin positions
%im_harris     - Find Harris points in images
%im_moments    - Computes moments as features from object images
%im_mean       - Computes center of gravity
%im_measure    - Computes some measurements
%im_profile    - Computes image profiles
%im_skel_meas  - Skeleton measurements
%im_stat       - Compute some simple statistics
%
%Clustering and distances
%------------------------
%distm       - Distance matrix between two data sets
%emclust     - Expectation - maximization clustering
%proxm       - Proximity mapping and kernel construction
%hclust      - Hierarchical clustering
%kcentres    - k-centres clustering
%prkmeans    - k-means clustering
%modeseek    - Clustering by modeseeking
%
%mds         - Non-linear mapping by multi-dimensional scaling (Sammon)
%mds_cs      - Linear mapping by classical scaling
%mds_init    - Initialisation of multi-dimensional scaling
%mds_stress  - Dissimilarity of distance matrices
%
%Plotting
%--------
%gridsize    - Set gridsize used in the PRTools plot commands
%plotc       - Plot discriminant function for two features
%plote       - Plot error curves
%plotf       - Plot feature distribution
%plotm       - Plot mapping
%ploto       - Plot object functions
%plotr       - Plot regression functions
%plotdg      - Plot dendrgram (see hclust)
%scatterd    - Scatterplot
%scatterdui  - Scatterplot scatterplot with feature selection
%scattern    - Simple, unannotated scatterplot, no axes.
%scatterr    - Scatter regression dataset
%
%Various tests and support routines
%----------------------------------
%cdats              - Support routine for checking datasets
%concatm            - Concatenate cell array of mappings or datasets ({} --> [])
%iscomdset          - Test on compatible datasets
%isdataim           - Test on image dataset
%isdataset          - Test on dataset
%isfeatim           - Test on feature image dataset
%ismapping          - Test on mapping
%isobjim            - Test on object image dataset
%issequential       - Test on sequential mapping
%isstacked          - Test on stacked mapping
%isparallel         - Test on parallel mapping
%issym              - Test on symmetric matrix
%isvaldset          - Test on valid dataset
%isvaldfile         - Test on valid datafile
%matchlablist       - Match entries of label lists
%mapex              - Train and execute mapping on the same dataset
%labcmp             - Compare two label lists and find the differences
%nlabcmp            - Compare two label lists and count the differences
%testdatasize       - Check datasize and convert datafile to dataset
%define_mapping     - Define empty mapping
%mapping_task       - Check mapping task
%trained_mapping    - Defined trained mapping
%trained_classifier - Define trained classifier
%setdefaults        - Substitute defaults
%shiftargin         - Conditional shift of input arguments
%prload             - Load prtools4 mat-files and convert to prtools5
%prtools4to5        - Convert prtools4 directory to prtools5
%
%Examples
%--------
%prex_cleval     - learning curves
%prex_combining  - classifier combining
%prex_confmat    - confusion matrix, scatterplot and gridsize
%prex_datafile   - datafile usage
%prex_datasets   - standard datasets
%prex_density    - Various density plots
%prex_eigenfaces - Use of images and eigenfaces
%prex_matchlab   - K-means clustering and matching labels
%prex_mcplot     - Multi-class classifier plot
%prex_plotc      - Dataset scatter and classifier plot
%prex_mds        - Multi-dimensional scaling and visualisation
%prex_som        - Training a SelfOrganizing Maps
%prex_spatm      - Spatial smoothing of image classification
%prex_cost       - Cost matrices and rejection
%prex_logdens    - Density based classifier improvement
%prex_soft       - Soft label example
%prex_regr       - Regression example
%
%prdownload  - low level routine for retrieving datasets
%prglobal    - set / list all globals and settings
%prversion   - returns version information on PRTools
%prwaitbar   - report PRTools progress by single waitbar
%prwarning   - control PRTools warning level
%prmemory    - controol PRTools large dataset handling
%prtver      - prtools version back end
%typp        - list prtools routine nicely
%
%--- PRTools Guide ---

% Copyright: R.P.W. Duin, r.p.w.duin@37steps.com
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands


function [dnum_bin, counts_per_bin, sum_per_bin, smallest_per_bin, biggest_per_bin, median_per_bin, std_per_bin, median_time_interval] = bin_irregular(dnum, data, binsize, snum, enum, stepsize)
% BIN_IRREGULAR bin an irregularly-sampled timeseries (like earthquake origin times).
%
%    Usage:
%      [dnum_bin, counts_per_bin, sum_per_bin, smallest_per_bin, biggest_per_bin, median_per_bin, std_per_bin, median_time_interval] = bin_irregular(dnum, data, binsize, snum, enum, [stepsize])
%
%    INPUTS:
%      dnum            - irregular spaced date vector in datenum format
%      data            - data values corresponding to dnum samples
%      binsize         - binsize (in days) to use for output series
%      snum            - start datenum (first centre used for output data)
%      enum            - end datenum (last centre used for output data)
%      stepsize        - (optional) Normally bins do not overlap. But if stepsize is set to a value smaller than binsize, bins will overlap.
%
%    OUTPUTS:
%      dnum_bin        	- regular space date vector (centres of bins)
%      counts_per_bin  	- number of values per bin
%      sum_per_bin     	- sum of all values in each bin
%      smallest_per_bin 	- smallest data value in each bin
%      biggest_per_bin 	- biggest data value in each bin
%      median_per_bin  	- median value in each bin
%      std_per_bin     	- standard deviation of all values in each bin
%      median_time_interval - median time interval between values in each bin
%
%    See also:

% AUTHOR: Glenn Thompson
% $Date$
% $Revision$
l1=length(dnum);
l2=length(data);
dnum_bin = [];
counts_per_bin = [];
sum_per_bin = [];
smallest_per_bin = [];
biggest_per_bin = [];
median_per_bin = [];
std_per_bin = [];
median_time_interval = [];

if (l1==l2)
    dnum_bin = snum+binsize/2 : stepsize : enum-binsize/2; % centres of the bins
    for c=1:length(dnum_bin)
	binstart = dnum_bin(c) - binsize/2; % start of this bin
	binend = dnum_bin(c) + binsize/2;   % end of this bin
	i = find(dnum >= binstart & dnum < binend);
	if length(i)>0
		d = data(i);
		thisdnum = dnum(i);
		counts_per_bin(c) = length(d);
		sum_per_bin(c)=nansum(d);
		median_per_bin(c)=nanmedian(d);
		std_per_bin(c) = std(d);
        	smallest_per_bin(c)=min(d);
        	biggest_per_bin(c)=max(d);
		median_time_interval(c)=median(thisdnum(2:end)-thisdnum(1:end-1));
	else
		counts_per_bin(c) = 0;
		sum_per_bin(c) = 0;
		std_per_bin(c) = 0;
		median_per_bin(c) = NaN;
		smallest_per_bin(c)=NaN;
		biggest_per_bin(c)=NaN;
	end
    end
else
    disp('Could not bin - vector lengths dont match');
end


function img = discreteCurve(varargin)
%DISCRETECURVE Discretize a planar curve
%
%   IMG = discreteCurve(DIM, CURVE, WIDTH)
%   DIM is the size of image, with the format [x0 dx x1;y0 dy y1]
%   CURVE is a series of points describing the curve
%   WIDTH is the max distance between pixel centers and points of the
%   curve.
%
%   IMG = discreteCurve(LX, LY, ...);
%   Specifes the pixels coordinates with the two row vectors LX and LY.
%
%   Example
%   % creates a ring
%   circle = circleAsPolygon([25 25 15], 120);
%   img = discreteCurve([1 1 50;1 1 50], circle, 3);
%   imshow(img);
%
%   See Also
%   imShapes, discretePolyline, discretePolygon

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2007-03-19
% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas).

%   HISTORY
%   19/06/2007: update doc
%   04/03/2009: use meshgrid
%   29/05/2009: use more possibilities for specifying grid

% compute coordinate of image voxels
[lx, ly, varargin] = parseGridArgs(varargin{:});
[x, y]   = meshgrid(lx, ly);

% get polyline vertex coordinates
curve = varargin{1};
varargin(1) = [];

% determines width of the polyline
width = 2;
if ~isempty(varargin)
    width = varargin{1};
end

try
    % try with vectorized version (greedy !!!)
    dist = reshape(minDistancePoints([x(:) y(:)], curve), size(x));
catch
    % if not enough memory, use loop instead
    dist = zeros(size(x));
    for i = 1:length(lx)
        dist(:, i) = minDistancePoints([x(:,i) y(:,i)], curve);
    end
end

% create image : simple threshold over 2 dimensions
img = abs(dist) < width;