function qInv=quatInv(q)
%%QUATINV Find the inverse of a quaternion. The inverse of a quaternion
%         left-or-right multiplied by the quaternion (using quatMult) is
%         equal to one (a real number). As with real numbers, issues arise
%         taking the inverse of the zero quaternion. Note that the inverse
%         does not depend on the handedness of the quaternion algebra, even
%         though the quatMult function does.
%
%%INPUTS: q  A 4XN set of N quaternions, each whose inverse is desired,
%           where the first element in each column is the scalar part of
%           the quaternion (sometimes called q0 or q4) and the next three
%           elements are the (hypercomplex) vector part. That is, the
%           hypercomplex quaternion given by q(:,1) can be written in
%           hypercomplex, non-vector form as
%           q(1,1)+i*q(2,1)+j*q(3,1)+k*q(4,1), where i, j, and k are all
%           roots of -1.
%
%OUTPUTS: qInv The 4XN set of inverses of the quaternions.
%
%Properties of quaternions including inversion are described in [1]. When a
%quaternion has unit magnitude, its conjugate it also its inverse.
%
%REFERENCES:
%[1] Weisstein, Eric W. "Quaternion." From MathWorld--A Wolfram Web
%    Resource. http://mathworld.wolfram.com/Quaternion.html
%
%September 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

qC=quatConj(q);
%The multiplication of a quaternion with its conjugate produces scalar
%values given in the first entries of qMags
qMags=quatMult(q,qC);
qMags=qMags(1,:);

qInv=bsxfun(@rdivide,qC,qMags);
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function [p,npix] = histroi(f,c,r)
%HISTROI Computes the histogram of an ROI in an image.
%   [P,NPIX] = HISTROI(F,C,R) computes the histogram, P, of a polygonal
%   region of interest (ROI) in image F. The polygonal region is defined
%   by the column and row coordinates of its vertices, which are
%   specified (sequentially) in vectors C and R, respectively. All
%   pixels of F must be >= 0. Parameter NPIX is the number of pixels in
%   the polygonal region. For consistency with Toolbox function imhist,
%   histogram p is unnormalized. To normalize it, let p = p/npix.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% Generate the binary mask image.
B = roipoly(f,c,r);

% Compute the histogram of the pixels in the ROI.
p = imhist(f(B));

% Obtain the number of pixels in the ROI if requested in the output. All
% ROI pixels have value 1.
if nargout > 1
   npix = sum(B(:));
end


function [nrows ncols] = subplotSz(n)
% [nrows ncols] = subplotSz(n)
%
% Choose the size, rows x cols, of a subplot. Make it as small as possible
% and as close to square as possible.
%
% Example:
%
% [nrows, ncols] = subplotSz(19)

if nargin < 1,
    help subplotSz
    return
end

nrows = round(sqrt(n));
ncols = ceil(n/nrows);

end


function perf=mae(e)
%
% calculate the absolute error of the given errors
%
%  'perf = mae(E);'
%
% see also:
%    mse, linf
%

% Copyright (c) 2011,  KULeuven-ESAT-SCD, License & help @ http://www.esat.kuleuven.be/sista/lssvmlab

perf = sum(sum(abs(e))) / numel(e);


function vol = imVolumeEstimate(img, varargin)
% Estimate volume of a 3D binary structure with edge correction.
%
%   Vest = imVolumeEstimate(IMG);
%   Vest = imVolumeEstimate(IMG, DELTA);
%
%   Example
%   imVolumeEstimate
%
%   See also
%     imVolume, imSurfaceEstimate

% ------
% Author: David Legland
% e-mail: david.legland@inrae.fr
% Created: 2010-01-21,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2010 INRA - Cepia Software Platform.

%% Input arguments processing

% check image dimension
if ndims(img) ~= 3
    error('first argument should be a 3D binary or label image');
end

% in case of a label image, return a vector with a set of results
if ~islogical(img)
    labels = unique(img);
    labels(labels==0) = [];
    vol = zeros(length(labels), 1);
    for i = 1:length(labels)
        vol(i) = imVolumeEstimate(img==labels(i), varargin{:});
    end
    return;
end

% check image resolution
delta = [1 1 1];
if ~isempty(varargin)
    delta = varargin{1};
end

%% main processing

% compute volume in whole image
vol = sum(img(:));

% compute volume on border faces
f1 = sum(sum(sum(img([1 end], :, :))));
f2 = sum(sum(sum(img(:, [1 end], :))));
f3 = sum(sum(sum(img(:, :, [1 end]))));

% compute volume on border edges
e1 = sum(sum(sum(img(:, [1 end], [1 end]))));
e2 = sum(sum(sum(img([1 end], :, [1 end]))));
e3 = sum(sum(sum(img([1 end], [1 end], :))));

% compute volume on corners
v = sum(sum(sum(img([1 end], [1 end], [1 end]))));

% estimate area using edge weighting according to multiplicity
vol = vol -(f1+f2+f3)/2 + (e1+e2+e3)/4 - v/8;

% multiply by volume of a single voxel
vol = vol * prod(delta);


function epochJ=JulDate2JulEpoch(Jul1,Jul2)
%%JULDATE2JULEPOCH Convert two-part Julian dates given in a uniform
%                  timescale, such as terrestrial time (TT) date to a
%                  Julian epoch in the same scale. The timescale
%                  should be uniform (i.e. not UTC).
%
%INPUTS: Jul1, Jul2  Matrices of two parts of a Julian date given in the
%                    same timescale as the epoch The units of the date are
%                    days. The full date is the sum of both terms. The
%                    entries in the matrices correspond to different
%                    dates to be converted.
%
%OUTPUTS: epochJ A matrix of Julian epochs as fractional years in the same
%                timescale as the input.
%
%A Julian epoch is a factional year number denominated in terms of a
%year of exactly 365.25 days in TT. For example 2000.5 is a Julian epoch
%in the middle of the year 2000.
%
%This is a wrapper for the function iauEpj in the International
%Astronomical Union's (IAU) Standard's of Fundamental Astronomy library.
%
%The algorithm can be compiled for use in Matlab  using the
%CompileCLibraries function.
%
%The algorithm is run in Matlab using the command format
%epochJ=JulDate2JulEpoch(Jul1,Jul2);
%
%March 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.

%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

error('This function is only implemented as a mexed C or C++ function. Please run CompileCLibraries.m to compile the function for use.')

end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


function centroids = kMeansInitCentroids(X, K)
%KMEANSINITCENTROIDS This function initializes K centroids that are to be
%used in K-Means on the dataset X
%   centroids = KMEANSINITCENTROIDS(X, K) returns K initial centroids to be
%   used with the K-Means on the dataset X
%

% You should return this values correctly
centroids = zeros(K, size(X, 2));

% ====================== YOUR CODE HERE ======================
% Instructions: You should set centroids to randomly chosen examples from
%               the dataset X
%

% Initialize the centroids to be random examples

% Randomly reorder the indices of examples
randidx = randperm(size(X, 1));
% Take the first K examples as centroids
centroids = X(randidx(1:K), :);

% =============================================================

end


function [ i_lt, i_gt ] = r8vec_sorted_split ( n, a, split )

%*****************************************************************************80
%
%% R8VEC_SORTED_SPLIT "splits" a sorted R8VEC, given a splitting value.
%
%  Discussion:
%
%    Given SPLIT, the routine seeks indices I_LT and I_GT so that
%
%      A(I_LT) < SPLIT < A(I_GT),
%
%    and if there are intermediate index values between I_LT and
%    I_GT, then those entries of A are exactly equal to SPLIT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 May 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters
%
%    Input, integer N, the number of entries in A.
%
%    Input, real A(N), a sorted array.
%
%    Input, real SPLIT, a value to which the entries in A are
%    to be compared.
%
%    Output, integer I_LT:
%    0 if no entries are less than SPLIT;
%    N if all entries are less than SPLIT;
%    otherwise, the index of the last entry in A less than SPLIT.
%
%    Output, integer I_GT:
%    1 if all entries are greater than SPLIT;
%    N+1 if no entries are greater than SPLIT;
%    otherwise the index of the first entry in A greater than SPLIT.
%
  if ( n < 1 )
    i_lt = -1;
    i_gt = -1;
    return
  end

  if ( split < a(1) )
    i_lt = 0;
    i_gt = 1;
    return
  end

  if ( a(n) < split )
    i_lt = n;
    i_gt = n + 1;
    return
  end

  lo = 1;
  hi = n;

  while ( 1 )

    if ( lo + 1 == hi )
      i_lt = lo;
      break
    end

    mid = round ( ( lo + hi ) / 2 );

    if ( split <= a(mid) )
      hi = mid;
    else
      lo = mid;
    end

  end

  for i = i_lt + 1 : n
    if ( split < a(i) )
      i_gt = i;
      return
    end
  end

  i_gt = n + 1;

  return
end


function [Xnorm] = L1infnorm(X)
% ||X||_{1,2} = sum_i||X^i||_inf
Xnorm = sum(max(abs(X),[],2));


function phi = rad(phi)
%RAD returns the given angle in radians
%
%   Usage: phi = rad(phi)
%
%   Input parameters:
%       phi     - angle, can be a scalar or matrix / degree
%
%   Output parameters:
%       phi     - angle / rad
%
%   See also: deg

%*****************************************************************************
% The MIT License (MIT)                                                      *
%                                                                            *
% Copyright (c) 2010-2019 SFS Toolbox Developers                             *
%                                                                            *
% Permission is hereby granted,  free of charge,  to any person  obtaining a *
% copy of this software and associated documentation files (the "Software"), *
% to deal in the Software without  restriction, including without limitation *
% the rights  to use, copy, modify, merge,  publish, distribute, sublicense, *
% and/or  sell copies of  the Software,  and to permit  persons to whom  the *
% Software is furnished to do so, subject to the following conditions:       *
%                                                                            *
% The above copyright notice and this permission notice shall be included in *
% all copies or substantial portions of the Software.                        *
%                                                                            *
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
% IMPLIED, INCLUDING BUT  NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY, *
% FITNESS  FOR A PARTICULAR  PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL *
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
% LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT  OR OTHERWISE, ARISING *
% FROM,  OUT OF  OR IN  CONNECTION  WITH THE  SOFTWARE OR  THE USE  OR OTHER *
% DEALINGS IN THE SOFTWARE.                                                  *
%                                                                            *
% The SFS Toolbox  allows to simulate and  investigate sound field synthesis *
% methods like wave field synthesis or higher order ambisonics.              *
%                                                                            *
% https://sfs.readthedocs.io                            sfstoolbox@gmail.com *
%*****************************************************************************

%% ===== Checking of input parameters ====================================
nargmin = 1;
nargmax = 1;
narginchk(nargmin,nargmax);

%% ===== Computation =====================================================
phi = phi./180*pi;


function [u,sigma,eqn,info] = PoissonRT0(node,elem,bdFlag,pde,option)
%% POISSONRT0 Poisson equation: lowest order RT element.
%
%  [u,sigma] = PoissonRT0(node,elem,bdFlag,pde) produces an approximation of
%  the Poisson equation
%
%       -div(d*grad(u))=f  in \Omega, with
%       Dirichlet boundary condition u=g_D on \Gamma_D,
%       Neumann boundary condition   d*grad(u)*n=g_N on \Gamma_N
%
%  in the mixed formulation:
%
%  Find (\sigma , u) in H_{g_N,\Gamma_N}(div,\Omega)\times L^2(\Omega) s.t.
%
%  (d^-1\sigma,\tau) + (div \tau, u)  = <\tau*n,g_D>_{\Gamma_D}
%  \forall \tau in H_{0,\Gamma_N}(div,\Omega)
%  (div \sigma, v)                =  -(f,v)
%  \forall v in L^2(\Omega)
%
%  where
%  H_{g,\Gamma}(div,\Omega) = {\sigma \in H(div,\Omega); \sigma*n = g
%  on \Gamma \subset \partial\Omega }.
%
%  The unknown sigma = d*grad(u) is approximated using the lowest order
%  Raviart-Thomas element and u by piecewise constant element (with basis 1).
%
%  [u,sigma] = PoissonRT0(node,elem,bdFlag,pde,option) specifies options
%   - option.solver
%     'direct': the built in direct solver \ (mldivide)
%     'tri':    triangular preconditioner
%     'uzawapcg': PCG for the Schur complement equation
%     'none': only assemble the matrix equation but not solve
%
%   The default setting is to use the direct solver for small size problems
%   and transforming based multigrid solvers for large size problems.
%
%  Example
%
%    squarePoissonRT0
%
% Created by Ming Wang. Reorganized by Long Chen. Change basis for u.
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

%% Preprocess
if ~exist('bdFlag','var'), bdFlag = []; end
if ~exist('option','var'), option = []; end

%% Diffusion coefficient
time = cputime;  % record assembling time
if ~isfield(pde,'d'), pde.d = []; end
if isfield(pde,'d') && ~isempty(pde.d)
   if isnumeric(pde.d)
      K = pde.d;                   % d is an array
   else                            % d is a function
      center = (node(elem(:,1),:) + node(elem(:,2),:) + node(elem(:,3),:))/3;
      K = pde.d(center);  % take inverse sequencil.
   end
else
    K = [];
end

%% Data structure
elemold = elem;
[elem,bdFlag] = sortelem(elem,bdFlag);  % ascend ordering of elem
[elem2edge,edge] = dofedge(elem);
NT = size(elem,1); NE = size(edge,1);
[Dlambda,area,elemSign] = gradbasis(node,elem);

%% Assemble matrix
Nsigma = NE; Nu = NT; Ndof = Nsigma + Nu;

% M. Mass matrix for RT0 element
M = getmassmatvec(elem2edge,area,Dlambda,'RT0',K); % ascend ordering of loc edge

% B. divergence operator
B = icdmat(double(elem2edge),elemSign*[1 -1 1]); % inconsistency with the induced ordering

% C. zero matrix.
C = sparse(Nu,Nu);

A = [M B';B C];

%% Assemble right hand side.
fu = zeros(Nu,1);
if ~isfield(pde,'f') || (isreal(pde.f) && (pde.f==0))
    pde.f = [];
end
if ~isfield(option,'fquadorder')
    option.fquadorder = 2;   % default order
end
if ~isempty(pde.f)
	[lambda,w] = quadpts(option.fquadorder);
	nQuad = size(lambda,1);
    for p = 1:nQuad
		% quadrature points in the x-y coordinate
		pxy = lambda(p,1)*node(elem(:,1),:) ...
			+ lambda(p,2)*node(elem(:,2),:) ...
			+ lambda(p,3)*node(elem(:,3),:);
		fp = pde.f(pxy);
		fu = fu - fp*w(p);  % div u = -f;
    end
    fu = fu.*area;
end
clear fp
F((Nsigma+1):Ndof,1) = fu;

%% Boundary Conditions
if ~exist('bdFlag','var'), bdFlag = []; end
[AD,F,bigu,freeDof,isPureNeumannBC] = getbdRT0(F);
eqn = struct('M',AD(1:NE,1:NE),'B',AD(NE+1:end,1:NE),'C',AD(NE+1:end,NE+1:end),...
             'f',F(1:NE),'g',F(NE+1:end),'freeDof',freeDof,'A',AD);

%% Record assembling time
assembleTime = cputime - time;
if ~isfield(option,'printlevel'), option.printlevel = 1; end
if option.printlevel >= 2
    fprintf('Time to assemble matrix equation %4.2g s\n',assembleTime);
end

%% Solve the linear system.
% Set up solver type
if isempty(option) || ~isfield(option,'solver')    % no option.solver
    if Ndof <= 2e3  % Direct solver for small size systems
        option.solver = 'direct';
    else         % MGCG  solver for large size systems
        option.solver = 'tri';
    end
% elseif strcmp(option.solver,'mg')
%     option.solver = 'tripremixPoisson';
end
solver = option.solver;
% solve
switch lower(solver)
    case 'direct'
        t = cputime;
        bigu(freeDof) = AD(freeDof,freeDof)\F(freeDof);
        sigma = bigu(1:NE);
        u = bigu(NE+1:end);
        info = struct('solverTime',cputime - t,'itStep',1,'error',0,'flag',0,'stopErr',0);
    case 'none'
        sigma = zeros(NE,1); u = zeros(NT,1); info =[];
    case 'tri'
        [sigma,u,info] = tripremixPoisson(eqn.M,eqn.B,eqn.C,eqn.f,eqn.g,elemold);
    case 'uzawapcg'
        [sigma,u,info] = uzawapcg(eqn.M,eqn.B,eqn.C,eqn.f,eqn.g,elemold);
%     case 'mg'
%         option.freeEdge = freeEdge;
%         option.isPureNeumannBC = isPureNeumannBC;
%         [sigma0,u,info] = mgDarcy(eqn.M,eqn.B,eqn.f,eqn.g,elemold,option);
%         sigma = bigu(1:NE);
%         sigma(freeEdge) = sigma0;
end
if isPureNeumannBC % post process for u for pure Neumann boundary condition
    ubar = sum(u.*area)/sum(area);
    u = u - ubar;
end

%% Output information
info.assembleTime = assembleTime;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% subfunction getbdRT0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    function [AD,F,bigu,freeDof,isPureNeumannBC] = getbdRT0(F)
    %% GETBDRT0 Boundary conditions for Poisson equation: RT0 element.
    %
    %  Created by Ming Wang. Improved the check of edgeSign by Long Chen.

    bigu = zeros(Ndof,1);

    %% No boundary conditions
    if ~isfield(pde,'g_D'), pde.g_D = []; end
    if ~isfield(pde,'g_N'), pde.g_N = []; end

    %% Set up bdFlag
    if isempty(bdFlag) % no bdFlag information
       if ~isempty(pde.g_N) % case: Neumann
           bdFlag = setboundary(node,elem,'Neumann');
       elseif ~isempty(pde.g_D) % case: Dirichlet
           bdFlag = setboundary(node,elem,'Dirichlet');
       end
    end

    %% Find Dirichlet and Neumann dofs
    edgeSign = ones(NE,1);
    isDirichlet = false(NE,1);
    isNeumann = false(NE,1);
    if ~isempty(bdFlag)
        isDirichlet(elem2edge(bdFlag(:)==1)) = true;
          isNeumann(elem2edge(bdFlag(:)==2)) = true;
        % Direction of boundary edges may not be the outwards normal direction
        % of the domain. edgeSign is introduced to record this inconsistency.
        edgeSign = ones(NE,1);
        idx = (bdFlag(:,1) ~= 0) & (elemSign == -1);% first edge is on boundary
        edgeSign(elem2edge(idx,1)) = -1;
        idx = (bdFlag(:,2) ~= 0) & (elemSign == 1); % second edge is on boundary
        edgeSign(elem2edge(idx,2)) = -1;
        idx = (bdFlag(:,3) ~= 0) & (elemSign == -1);% third edge is on boundary
        edgeSign(elem2edge(idx,3)) = -1;
    end
    Dirichlet = edge(isDirichlet,:);
    Neumann = edge(isNeumann,:);
    isBdDof = false(Ndof,1);
    isBdDof(isNeumann) = true;   % for mixed method, Neumann edges are fixed
    freeDof = find(~isBdDof);
%     isFreeEdge = true(NE,1);
%     isFreeEdge(isNeumann) = false;
%     freeEdge = find(isFreeEdge);

    %% Dirichlet boundary condition (Neumann BC in the mixed form)
    %   We need only modify the rhs on dof associated with Dirichlet
    %   boundary. Compute the int_e g_D \phi_e\cdot n ds on the boundary.
    if ~isempty(pde.g_D) && isnumeric(pde.g_D) && (pde.g_D==0)
        pde.g_D = [];
    end
    if ~isempty(pde.g_D) && any(isDirichlet)
        if ~isfield(option,'gNquadorder')
            option.gNquadorder = 2;   % default order exact for quadratic gN
        end
        [lambda,w] = quadpts1(option.gNquadorder);
        nQuad = size(lambda,1);
        % <\phi\cdot n, g_D> = 1/|e_{i,j}|\int e_{i,j} g_D ds
        for ip = 1:nQuad
        	pxy = lambda(ip,1)*node(Dirichlet(:,1),:)+...
                  lambda(ip,2)*node(Dirichlet(:,2),:);
            F(isDirichlet) = F(isDirichlet) + w(ip)*pde.g_D(pxy);
        end
        F(isDirichlet) = F(isDirichlet).*edgeSign(isDirichlet);
        % no edge length since the basis of sigma contains it.
    end

    %% Neumann boundary condition (Dirichlet BC in mixed form)
    % We compute the integral int_e g_N ds and assign to boundary dof
    if ~isempty(pde.g_N) && isnumeric(pde.g_N) && (pde.g_N==0)
        pde.g_N = [];
    end
    if ~isempty(pde.g_N) && any(isNeumann)
        % modify the rhs to include Dirichlet boundary condition
        ve = node(Neumann(:,1),:)-node(Neumann(:,2),:);
        edgeLength = sqrt(sum(ve.^2,2));
        % compute the integral int_e g_N ds
        if ~isfield(option,'gNquadorder')
            option.gNquadorder = 2;   % default order exact for quadratic gN
        end
        [lambda,w] = quadpts1(option.gNquadorder);
        nQuad = size(lambda,1);
        bigu(isNeumann) = 0;
        for ip = 1:nQuad
        	pxy = lambda(ip,1)*node(Neumann(:,1),:)+...
                  lambda(ip,2)*node(Neumann(:,2),:);
            bigu(isNeumann) = bigu(isNeumann) + w(ip)*pde.g_N(pxy).*edgeLength;
        end
        % correct the sign
        bigu(isNeumann) = bigu(isNeumann).*edgeSign(isNeumann);
        F = F - A*bigu;
        F(isNeumann) = bigu(isNeumann);
    end

    %% Pure Neumann boundary condition
    isPureNeumannBC = false;
    if ~any(isDirichlet) && any(isNeumann)
        freeDof = freeDof(1:end-1);  % eliminate the kernel by enforcing u(NT) = 0;
        isBdDof(end) = true;
        isPureNeumannBC = true;
        F(NE+1:end) = F(NE+1:end) - mean(F(NE+1:end)); % normalize
%         F(end) = 0;
    end

    %% Modify the matrix
    %  Build Neumann boundary condition(Dirichlet BC in mixed form) into the
    %  matrix AD by enforcing  |AD(bdNode,bdNode)=I,
    %  AD(bdNode,FreeNode)=0, AD(FreeNode,bdNode)=0|.
    if any(isBdDof)
       bdidx = zeros(Ndof,1);
       bdidx(isBdDof) = 1;
       Tbd = spdiags(bdidx,0,Ndof,Ndof);
       T = spdiags(1-bdidx,0,Ndof,Ndof);
       AD = T*A*T + Tbd;
    else
       AD = A;
    end
    end % end of getbdRT0
end


%% Demo of *format_scat*

%% Usage
% [out,meta] = *format_scat*(S,fmt) (see
% <matlab:doc('format_scat') format_scat>).
%
%% Description
% In this demo, we show how format_scat can be used to gather all
% scattering coefficients into one single array, and visualize this array
% using imagesc.
% NB : so as to improve contrast, the colormap only ranges from 0 to 2,
% setting all higher values in white.

N = 65536;
load handel;
y = y(1:N);
T = 4096;
filt_opt = default_filter_options('audio', T);
scat_opt.M = 2;
[Wop, filters] = wavelet_factory_1d(N, filt_opt, scat_opt);
S = scat(y, Wop);
fmt = 'table'; % default format
X = format_scat(S,fmt);

figure;
coefft = (1:size(X,1));
time = (1:size(X,2)) * T/Fs;
imagesc(time,coefft,X);
colormap bone;
caxis([0 2]); % color thresholding improves contrast
colorbar;
xlabel('Time (seconds)');
ylabel('Coefficients');


 function [alpha, beta, ok] = nufft_alpha(N, J, K, alpha, beta)
%function [alpha, beta, ok] = nufft_alpha(N, J, K, alpha, beta)
%|
%| Determine alpha and beta, as associated with the scaling factors
%| for min-max interpolation, from arguments.
%|
%| in
%|	alpha	[L,1]	Fourier series coefficients of scaling factors
%|			or a string (see below)
%|	beta		scale gamma=2pi/K by this in Fourier series
%|			typically is K/N (me) or 0.5 (Liu)
%| out
%|	alpha,beta
%|
%| Copyright 2001-3-30, Jeff Fessler, University of Michigan

if nargin < 3, ir_usage, end

if ~isvar('alpha') || isempty(alpha)
	alpha = [1]; % default Fourier series coefficients of scaling factors
end
if ~isvar('beta') || isempty(beta)
	beta = 0.5; % default is Liu version for now
end

if streq(alpha, 'uniform')
	alpha = [1];
	beta = 0.5;
return
end

% see if 'best' alpha is desired
if ischar(alpha)
	if streq(alpha, 'best')
		L = 0;
	elseif streq(alpha, 'best,L=1')
		L = 1;
	elseif streq(alpha, 'best,L=2')
		L = 2;
	else
		fail 'unknown alpha argument'
	end

	[alpha, beta, ok] = nufft_best_alpha(J, L, K/N);
	if ~ok
		warn('optimal alpha unknown for J=%d, K/N=%g, L=%d', J, K/N, L)
	end
end


function [ft2] = ha2ft2(ha)
% Convert area from hectares to square feet.
% Chad A. Greene 2012
ft2 = ha*107639.1041671;


function  FRIEDEL= Tpm_FR(P,X,G,DH,ERH)
% TPM_FR  Friedel two-phase multiplier
% TPM_FR(P,X,G,DH,ERH) Returns the Friedel two-phase
% multipier for a steam-water system
%  Called function: h2o_rhof(P), h2o_rhog(P), h2o_muf(P),
%                   h2o_mug(P), h2o_sigma(P), h2o_rhotp(P,X),
%                   ffcw(RE,DH,ERH),
%  Required Inputs are: P  - pressure (kPa)
%                       X  - quality (fraction)
%                       G  - mass flux (kg/m^2s)
%                       DH - hydraulic diameter (m)
%                       ERH - equivalent roughness height (m)
% ---------------------------------------------------------------
% The MATLAB function was created by Tibor Balint, December 1998
% TBoreal Research Corporation, Toronto, Ont. Canada
% (tibor@netcom.ca) and also, University of Warwick, UK
% ---------------------------------------------------------------

format long g;  % set the format of the calculations

% set the density and viscosity properties
RF=h2o_rhof(P); %sat. fluid density
RG=h2o_rhog(P); %sat. steam density
MUF=h2o_muf(P); %dynamic viscosity of sat. fluid
MUG=h2o_mug(P); %dynamic viscosity of sat. steam
SIGMA=h2o_sigma(P); %surface tension
VFG=(1/RG)-(1/RF); %diff. between steam and fluid spec.volumes
VF=1/RF; %saturated fluid specific volume

% the two-phase specific density
RHOTP=h2o_rhotp(P,X);

% the two-phase specific volume
VTP=1/RHOTP;

% the Froude number
FR=(G^2)*(VTP^2)/(9.81*DH);

% the Weber number
WE=(G^2)*DH*VTP/SIGMA;

% the Reynolds number FOR LIQUID
REF=G*DH/MUF;

% the Reynolds number FOR STEAM
REG=G*DH/MUG;

% the Colebrook-White friction factor FOR LIQUID
FCWF=ffcw(REF,DH,ERH);

% the Colebrook-White friction factor FOR STEAM
FCWG=ffcw(REG,DH,ERH);

% Calculate the Friedel correlation
% the first part of the Friedel correlation
A=((1-X)^2)+(X^2)*(RF*FCWG)/(RG*FCWF);

%  THE FRIEDEL TWO-PHASE FRICTION MULTIPLIER
FRIEDEL=A+3.21*(X^0.78)*((1-X)^0.224)*((RF/RG)^0.91)*((MUG/MUF)^0.19)*...
       ((1-(MUG/MUF))^0.7)/((FR^0.0454)*(WE^0.035));

return


function [AF,BF]=uwfbtbounds(wt,varargin)
%UWFBTBOUNDS Frame bounds of Undecimated WFBT
%   Usage: fcond=uwfbtbounds(wt,L);
%          [A,B]=uwfbtbounds(wt,L);
%          [...]=uwfbtbounds(wt);
%
%   `uwfbtbounds(wt,L)` calculates the ratio $B/A$ of the frame bounds
%   of the undecimated filterbank specified by *wt* for a system of length
%   *L*. The ratio is a measure of the stability of the system.
%
%   `uwfbtbounds({w,J,'dwt'},L)` calculates the ratio $B/A$ of the frame
%   bounds of the undecimated DWT (|UFWT|) filterbank specified by *w* and
%   *J* for a system of length *L*.
%
%   `uwfbtbounds(wt)` does the same thing, but *L* is the length of the
%   longest filter in the identical filterbank.
%
%   `[A,B]=uwfbtbounds(...)` returns the lower and upper frame bounds
%   explicitly.
%
%   See |wfbt| for explanation of parameter *wt* and |fwt| for explanation
%   of parameters *w* and *J*.
%
%   The function supports the following flags:
%
%   `'sqrt'`(default),`'noscale'`,`'scale'`
%       The filters in the filterbank tree are scaled to reflect the
%       behavior of |uwfbt| and |iuwfbt| with the same flags.
%
%   See also: uwfbt, filterbankbounds

warning('UWFBTBOUNDS is deprecated. Please use WFBTBOUNDS with a appropriate flag.');
complainif_notenoughargs(nargin,1,'UWFBTBOUNDS');

definput.keyvals.L = [];
definput.import = {'uwfbtcommon'};
[flags,~,L]=ltfatarghelper({'L'},definput,varargin);

if nargout<2
   AF = wfbtbounds(wt,L,flags.scaling);
elseif nargout == 2
   [AF,BF] = wfbtbounds(wt,L,flags.scaling);
end


function [A,b] = pwamodel(F,x)

[dummy,aux,s,model] = export(F,[]);

A = -model.F_struc(:,2:end);
b = model.F_struc(:,1);

keep_these = find(ismember(aux.used_variables,getvariables(x)));

A = [A(:,keep_these) A(:,setdiff(1:size(A,2),keep_these))];
[A,b] = fourier_motzkin(A,b,length(keep_these));

function [A,b] = fourier_motzkin(A,b,m)

while size(A,2)>m
    [A,b] = fourier_motzkin_1(A,b,m);
    [aux,i] = unique([A b],'rows');
    A = A(i,:);
    b = b(i);
end

function [Aout,bout] = fourier_motzkin_1(A,b,m)

for i = m+1:size(A,2)
    less = find(A(:,i)>0);
    larger = find(A(:,i)<0);
    t(i-m) =length(less)*length(larger);
end

[minn,remove] = min(t);
remove = remove+m;
keep = setdiff(1:size(A,2),remove);

less = find(A(:,remove)>0);
larger = find(A(:,remove)<0);
notinvolved = find(A(:,remove)==0);

Aout = A(notinvolved,keep);
bout = b(notinvolved);

for i = 1:length(less)
    for j = 1:length(larger)
        Aout = [Aout;A(less(i),keep)/abs(A(less(i),remove)) + A(larger(j),keep)/abs(A(larger(j),remove))];
        bout = [bout;b(less(i))+b(larger(j))];
    end
end


%
%
%
%  Test the data density plot
%
%
x = randn(2048, 1);
y = randn(2048, 1);
x(1:512) = x(1:512) + 2.75;
x(1537:2048) = x(1537:2048) + 2.75;
y(1025:2048) = y(1025:2048) + 2.75;

% On scatter plot you probably can't see the data density
scatter(x, y);
% On data density plot the structure should be visible
DataDensityPlot(x, y, 32);


function bnet = mk_asia_bnet(CPD_type, p, arity)
% MK_ASIA_BNET Make the 'Asia' bayes net.
%
% BNET = MK_ASIA_BNET uses the parameters specified on p21 of Cowell et al,
% "Probabilistic networks and expert systems", Springer Verlag 1999.
%
% BNET = MK_ASIA_BNET('cpt', p) uses random parameters drawn from a Dirichlet(p,p,...)
% distribution. If p << 1, this is nearly deterministic; if p >> 1, this is nearly uniform.
%
% BNET = MK_ASIA_BNET('bool') makes each CPT a random boolean function.
%
% BNET = MK_ASIA_BNET('gauss') makes each CPT a random linear Gaussian distribution.
%
% BNET = MK_ASIA_BNET('orig') is the same as MK_ASIA_BNET.
%
% BNET = MK_ASIA_BNET('cpt', p, arity) can specify non-binary nodes.

if nargin == 0, CPD_type = 'orig'; end
if nargin < 3, arity = 2; end

Smoking = 1;
Bronchitis = 2;
LungCancer = 3;
VisitToAsia = 4;
TB = 5;
TBorCancer = 6;
Dys = 7;
Xray = 8;

n = 8;
dag = zeros(n);
dag(Smoking, [Bronchitis LungCancer]) = 1;
dag(Bronchitis, Dys) = 1;
dag(LungCancer, TBorCancer) = 1;
dag(VisitToAsia, TB) = 1;
dag(TB, TBorCancer) = 1;
dag(TBorCancer, [Dys Xray]) = 1;

ns = arity*ones(1,n);
if strcmp(CPD_type, 'gauss')
    dnodes = [];
else
    dnodes = 1:n;
end
bnet = mk_bnet(dag, ns, 'discrete', dnodes);

switch CPD_type
    case 'orig'
        % true is 2, false is 1
        bnet.CPD{VisitToAsia} = tabular_CPD(bnet, VisitToAsia, [0.99   0.01]);
        bnet.CPD{Bronchitis} = tabular_CPD(bnet, Bronchitis, [0.7 0.4   0.3 0.6]);
        % minka: bug fix
        bnet.CPD{Dys} = tabular_CPD(bnet, Dys, [0.9 0.2 0.3 0.1   0.1 0.8 0.7 0.9]);
        bnet.CPD{TBorCancer} = tabular_CPD(bnet, TBorCancer, [1 0 0 0   0 1 1 1]);
        % minka: bug fix
        bnet.CPD{LungCancer} = tabular_CPD(bnet, LungCancer, [0.99 0.9  0.01 0.1]);
        bnet.CPD{Smoking} = tabular_CPD(bnet, Smoking, [0.5 0.5]);
        bnet.CPD{TB} = tabular_CPD(bnet, TB, [0.99 0.95  0.01 0.05]);
        bnet.CPD{Xray} = tabular_CPD(bnet, Xray, [0.95 0.02  0.05 0.98]);
    case 'bool'
        for i=1:n
            bnet.CPD{i} = boolean_CPD(bnet, i, 'rnd');
        end
    case 'gauss'
        for i=1:n
            bnet.CPD{i} = gaussian_CPD(bnet, i, 'cov', 1*eye(ns(i)));
        end
    case 'cpt'
        for i=1:n
            bnet.CPD{i} = tabular_CPD(bnet, i, p);
        end
end


function [corr,t,p, fdrsig, fdrthresh] = correlation(meth,x,varargin)
% Multiple types of correlations, including Spearman's rho
% (nonparametric) and phi (dichotomous)
%
% :Usage:
% ::
%
%     [corr,t,p,fdrp, fdrthresh] = correlation(method,x,[y],['matrix'])
%
%     IN PROGRESS : Warning : Use at your own risk.
%     Some methods are not adequately tested yet.
%     Spearman's rho does not correct for ties
%
% :Inputs:
%
%   **Methods:**
%        String indicating the method for computing the correlation
%        coefficient
%        - Pearson's r.          Enter: {'r','pearson',[]}
%        - IRLS                  Enter: {'irls','robust'}
%        - Phi                   Enter: {'phi'}
%        - Spearman's rho        Enter: {'rho','spearman'}
%        - Kendall's Tau (a)     Enter: {'taua','kendalla'}
%        - Tau (b)               Enter: {'tau','kendall','taub','kendallb'}
%        - Gamma                 Enter: {'gamma','kruskal'}
%
%   **x:**
%        Matrix of observations (n instances by p varianbles)
%
% :Optional Inputs:
%
%   **varargin:**
%        To be documented
%
% :Outputs:
%
%   **OUT:**
%        Output stats structure
%
% :Examples:
% ::
%
%    % Corelation between two variables, Pearson's
%    x = rand(10,1); y = rand(10,1);
%    [corr,t,p] = correlation('r',x,y);
%
%    % Correlation matrix of 10 variables, phi correlation:
%    studybyroi = magic(10);
%    [corr,t,p] = correlation('phi',studybyroi);
%
% :See Also: correlation_fast_series.m
%
% ..
%    tor wager, november 2006, Jan 2007
% ..

corr = []; t = []; p = [];

% get y data, if entered
% --------------------------------
for i = 1:length(varargin)
    if ~ischar(varargin{i}) && ~any(size(varargin{i}) - size(x))
        y = varargin{i};
    end
end

% get flag for whether to compute correls among all possible pairs
% --------------------------------
matrixFormFlag = 0;
if any(strcmp(varargin,'matrix')) || ~exist('y','var')
    matrixFormFlag = 1;
end

[n,nvars] = size(x);

% Get indices
% --------------------------------
if matrixFormFlag
    % input is matrix
    [rows,cols,npairs] = corrcoef_indices(nvars);

else
    % input is columns of consecutive pairs to correlate
    npairs = size(x,2); % number of pairs of correlations to compute
end

doverbose = 0;
if npairs > 1000, doverbose = 1; fprintf('%03d%%', 0); end

% Compute correlations
% --------------------------------
for i = 1:npairs

    if doverbose, fprintf('\b\b\b\b%03d%%', round(i*100 ./ npairs)), end

    % get data
    if matrixFormFlag
        x1 = x(:,rows(i)); x2 = x(:,cols(i));
    else
        x1 = x(:,i); x2 = y(:,i);
    end

    if nargout > 1
        [c,tt,pp] = compute_single_correl(meth,x1,x2,n);
    else
        c = compute_single_correl(meth,x1,x2,n);
    end

    corr(i,1) = c;

    if nargout > 1
        if ~isempty(tt), t(i,1) = tt; end
        if ~isempty(pp), p(i,1) = pp; end
    end
end

% Reconstruct into matrix, if needed
% --------------------------------
if matrixFormFlag
    corr = reconstruct(corr,nvars,npairs,rows,cols);

    corr = corr + eye(nvars);

    if ~isempty(t), t = reconstruct(t,nvars,npairs,rows,cols); end

    if ~isempty(p), p = reconstruct(p,nvars,npairs,rows,cols); end

    % FDR correction, if requested
    % only works for matrices, otherwise error
    if nargout > 3
        [fdrthresh,fdrsig] = fdr_correct_pvals(p,corr);
    end

elseif nargout > 3
    error('FDR output is only allowed for matrix form output.  Try requesting fewer outputs')
end

return

% sub-functions

function [est,t,p] = compute_single_correl(meth,x,y,n)

est = [];
t = [];
p = [];

[wasnan, x, y] = nanremove(x, y);

switch lower(meth)

    case {'irls','robust'}
        [b,stats]=robustfit(x,y,'bisquare'); %,[],'off');
        est = weighted_corrcoef([x y], stats.w);
        est = est(1,2);

        t = stats.t(2);
        p = stats.p(2);

    case {'r','pearson',[]}

        if islogical(x)
            warning('Logical vectors not appropriate for Pearson''s r.');
            x = double(x);
            y = double(y);
        end

        [est,p] = corrcoef([x y]);
        est = est(1,2);
        p = p(1,2);

    case 'phi'
        % Phi is for dichotomous (2-level) variables
        % formula from Robert Yaffee, NYU, online.

        tab = make_crosstabs(x,y);
        num = det(tab);                 % same as: num = tab(1,1)*tab(2,2) - tab(1,2)*tab(2,1);
        den = ( prod(sum(tab,2)) .* prod(sum(tab,1)) ).^.5;
        est = num ./ den;

        % F = varexp/dfexp / varunexp/dferror; t = sqrt(F)
        if nargout > 1 % for speed
            t = est .* sqrt((n - 2) ./ (1 - est.^2));
            p = 2 .* (1 - tcdf(abs(t),n-2));        % two-tailed p-value
        end
        %wts = [];
        %nonpar = 0;
        % this works,but is unsigned
        %[chi2,df,p,sig] = chi2test([x y],'obs'); %,wts,nonpar);
        %est = (chi2 ./ n) .^ .5;

    case {'rho','spearman'}

        % This method uses midrank method to handle ties; needs checking
        % vs. SPSS
        D = rankdata(x) - rankdata(y);
        est = 1 - (6*(D'*D)) ./ (n * (n^2-1));

        % same as : corrcoef(rankdata(x),rankdata(y));
        % but faster
        % tested against SPSS 11.04
        % problem with large n?

        % % n = 1000;
        % % tic, for i = 1:100, x = rand(n,1); y = x + rand(n,1);
        % % corrcoef(rankdata(x),rankdata(y));
        % % end, toc
        % % tic, for i = 1:100, x = rand(n,1); y = x + rand(n,1);
        % %     n = size(x,1);
        % % D = rankdata(x) - rankdata(y);
        % % 1 - (6*(D'*D)) ./ (n * ((n^2)-1));
        % % end, toc

    case {'taua','kendalla'}

        % checked 1/13/07 against http://www.wessa.net/rwasp_kendall.wasp
        % should probably be checked against SPSS

        [r,i] = sort(x);
        y = y(i);               % get ordered y; don't really need to rank

        % count number of ranks above each successive value of y
        for i = 1:(n - 1)
            P(i) = sum( y(i+1:end) > y(i) );
        end
        est = 4 * sum(P) ./ (n * (n - 1)) - 1;

        if nargout > 1 % for speed
            % actually a z-score
            t = 3 * est * (n * (n - 1)) .^.5 ./ (2 * (2 * n + 5)) .^.5;
            p = 1 - normcdf(abs(t));

            if p == 0, p = 10*eps; end
        end

    case {'tau','kendall','taub','kendallb'}

        % checked 1/13/07 against http://www.wessa.net/rwasp_kendall.wasp
        % should probably be checked against SPSS

        [r,i] = sort(x);
        y = y(i);               % get ordered y

        % count number of ranks above each successive value of y
        for i = 1:(n - 1)
            wh = r > r(i);  % find pts with x value greater than r(i); handle x ties
            P(i) = sum( y(wh) > y(i) ); % concordances
            N(i) = sum( y(wh) < y(i) ); % discordances
        end

        %% *** maybe ties have to include all values that are tied"??
        % http://www.statsdirect.com/help/nonparametric_methods/kend.htm
        xties = get_ties(x);
        yties = get_ties(y);

        num = sum(P) - sum(N);

        n1 = n * (n - 1) ./ 2;

        % From http://www.unesco.org/webworld/idams/advguide/Chapt4_2.htm
        % and http://www.statsdirect.com/help/nonparametric_methods/kend.htm
        den = sqrt(  (n1 - sum(xties)) * (n1 - sum(yties))  );

        % Tau b : from http://www.unesco.org/webworld/idams/advguide/Chapt4_2.htm
        %den = sqrt((sum(P) + sum(N) + (n - sum(xties))) * (sum(P) + sum(N) + (n - sum(yties))));

        est = num ./ den;

        if nargout > 1 % for speed
            % actually a z-score
            t = 3 * est * (n * (n - 1)) .^.5 ./ (2 * (2 * n + 5)) .^.5;
            p = 1 - normcdf(abs(t));
        end

    case {'gamma','kruskal'}

        [r,i] = sort(x);
        y = y(i);               % get ranks of y

        % count number of ranks above each successive value of y
        for i = 1:(n - 1)
            wh = r > r(i);  % find pts with x value greater than r(i); handle x ties
            P(i) = sum( y(wh) > y(i) ); % concordances
            N(i) = sum( y(wh) < y(i) ); % discordances
        end

        num = sum(P) - sum(N);
        den = sum(P) + sum(N);
        est = num ./ den;

    otherwise
        error('Unknown correlation option');
end

return

function tab = make_crosstabs(x,y)
% make table (crosstabs)
u1 = unique(x);
u2 = unique(y);
len1 = length(u1);
len2 = length(u2);
tab = zeros(len1,len2);
w = 1;                  % weights

for i = 1:length(u1)                   % rows are 0 then 1 on the first var, "Nos" then "Yesses"
    for j = 1:length(u2)               % for each column
        tab(i,j) = sum( (x == u1(i) & y == u2(j)) .* w );
    end
end

return

function ties = get_ties(x)
r = rankdata(x, 'nomidrank');
for i = 1:length(unique(r))
    ties(i) = sum(r == i);
end
ties = sum(ties .* (ties - 1) ./ 2);
return

function [rows,cols,npairs] = corrcoef_indices(nvars)

    if nvars > 1000
        fprintf('Setting up indices of matrix.');
        % added to deal with large datasets
        tmp = triu(true(nvars));

        for i = 1:nvars
            tmp(i, i) = 0;
        end

%         % create logical identity matrix of large size
%         t2 = eye(1000);
%         t2 = logical(t2);
%         eyemtx = t2;
%         while size(eyemtx, 2) < nvars
%             eyemtx = blkdiag(eyemtx, t2);
%         end
%         eyemtx = eyemtx(1:nvars, 1:nvars);
%
%         tmp = tmp - eyemtx;

        fprintf(1,'Done.\n');

    else
        % upper triangle only
        tmp = triu(ones(nvars));
        tmp = tmp - eye(nvars);
    end

    [rows,cols] = find(tmp);
    npairs = length(rows);

    return

function valmat = reconstruct(vals,nvars,npairs,rows,cols)

valmat = zeros(nvars);
for i = 1:npairs
    valmat(rows(i),cols(i)) = vals(i);
end
valmat = valmat + valmat';

return

function [pthr,sig] = fdr_correct_pvals(p,r)

    psq = p; psq(find(eye(size(p,1)))) = 0;
    psq = squareform(psq);
    pthr = FDR(p,.05);
    if isempty(pthr), pthr = 0; end

    sig = sign(r) .* (p < pthr);

    return


function [ml] = l2ml(l)
% Convert volume from liters to milliliters.
% Chad Greene 2012
ml = l*1000;


function [pvec, pstruct] = tapas_ehgf_transp(r, ptrans)
% --------------------------------------------------------------------------------------------------
% Copyright (C) 2012-2020 Christoph Mathys, TNU, UZH & ETHZ
%
% This file is part of the HGF toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

pvec    = NaN(1,length(ptrans));
pstruct = struct;

l = r.c_prc.n_levels;

pvec(1:l)         = ptrans(1:l);                           % mu_0
pstruct.mu_0      = pvec(1:l);
pvec(l+1:2*l)     = exp(ptrans(l+1:2*l));                  % sa_0
pstruct.sa_0      = pvec(l+1:2*l);
pvec(2*l+1:3*l)   = ptrans(2*l+1:3*l);                     % rho
pstruct.rho       = pvec(2*l+1:3*l);
pvec(3*l+1:4*l-1) = exp(ptrans(3*l+1:4*l-1));              % ka
pstruct.ka        = pvec(3*l+1:4*l-1);
pvec(4*l:5*l-1)   = ptrans(4*l:5*l-1);                     % om
pstruct.om        = pvec(4*l:5*l-1);
pvec(5*l)         = exp(ptrans(5*l));                      % pi_u
pstruct.pi_u      = pvec(5*l);

end


% IndexToAssignment Convert index to variable assignment.
%
%   A = IndexToAssignment(I, D) converts an index, I, into the .val vector
%   into an assignment over variables with cardinality D. If I is a vector,
%   then the function produces a matrix of assignments, one assignment
%   per row.
%
%   See also AssignmentToIndex.m and FactorTutorial.m

function A = IndexToAssignment(I, D)

D = D(:)'; % ensure that D is a row vector
A = mod(floor(repmat(I(:) - 1, 1, length(D)) ./ repmat(cumprod([1, D(1:end - 1)]), length(I), 1)), ...
        repmat(D, length(I), 1)) + 1;

end


function EMfc
%This is an implementation of the EM algorithm for Clustering via Gaussian
%mixture models, using graphical on-line representation.

%Panagiotis Braimakis (s6990029)

%load simulated gaussian data.
clear;clc
%for p=1:1000
load data
%load M5    %uncomment only if you want to take results from k-means
            %algorithm

%if i load the M5 matrix then i get as starting values tha ones given via
%the kmeans algorithm, which as he saw detects only spherical clusters
%(which does not always hold)
%So lets give initial random id's to the observations.

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%OPTIONAL SUB-SAMPLING%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5%%%%%%
 %sample from X
 t=10000;
%  Y=randperm(t);
%  X=X(Y,:);

cidx=unidrnd(5,t,1);
%in order to give a SEED for the Z matrix ,which classifies
%each row of data to it's cluster, we use the results of another clustering method
tic;
Z=zeros(t,5);   %Setting up the storing matrix.
for i=1:t
for j=1:5
if (cidx(i)==j)     %cidx was the (t*1) id-matrix of each record (from 1 to 5)
Z(i,j)=1;           %The new (t*5) Z matrix has only ones, where needed
end %if
end %for
end %for

%Since we have the seed we can now implement the M-step of the algorithm &
%get the loop started between the "Maximization" & "Expectation" steps.

    w=0;    %for the graphs.
    c=2;    %starting counter.
    ll(1)=-88888888;  %starting values just to set the first difference between the log-likelihood's
                %in the first step (remember l(-1) & l(0) does not exist!!!)
    ll(2)=-77777777;
while ll(c)-ll(c-1) > 10^(-10);

    c=c+1;
    g=c-2   %iteration number.
    %all these are the estimates for the parameters of mixture models with
    %normal components.(Geoffrey J. Mclachlan &Kaye E. Basford)

    %nk row matrix is an estimate of the number of "points" on each
    %cluster.
    nk=sum(Z,1);

    %just for the plots

    for i=1:t
max(i)=Z(i,1);
k=1;
for j=2:5
if  (Z(i,j)>max(i))
max(i)=Z(i,j);
P(i,k)=0;
k=j;
else
P(i,j)=0;
end
end
P(i,k)=1;
end

    n=sum(P,1);

        %Now the tk row-matrix estimates each time the probabilities of belonging
    %to the jth cluster (j=1:5)
    tk=nk./t;
    %%Now comes the mean's matrix if we suppose that i element of X belongs to the k-th
    %%cluster (that is done via the Z matrix each time).
    sumclusterX=X'*Z;
    diagnk=diag(nk);
    diag1nk=inv(diagnk);
    mean=sumclusterX*diag1nk;

    %Next one is the estimated intra-cluster VAriance-COvariance MAtrix of
    %the data.

 covma=cell(5,1);

    for j=1:5

    Q1=X-ones(t,1)*mean(:,j)';  %x's-means
    Q2=Q1';
A=cell(t,1);
    for i=1:t
        A(i)={Q1(i,:)};
    end
B=cell(t,1);
    for i=1:t
        B(i)={Q2(:,i)};
    end
        T=[Z(:,j) Z(:,j)];

C=cell(1,1);
    for e=1:t
       C{e}=(T(e,:)'.*B{e})*A{e};
    end

    nom=[0 0;0 0];
    for k = 1:length(C)
    nom=C{k}+nom;
    end %for

    covma{j}=nom./nk(j);
    end %for

  %PLOTS the 95% confidence ellipses & the (X,Y) pairs of each cluster in each iteration.

%   w=w+1;
%   subplot(2,2,w);
%   hold on,
%
%
  plot(X(:,1),X(:,2),'m.');
  confreg(mean(:,1),covma{1},n(1),0.05);
  confreg(mean(:,2),covma{2},n(2),0.05);
  confreg(mean(:,3),covma{3},n(3),0.05);
  confreg(mean(:,4),covma{4},n(4),0.05);
  confreg(mean(:,5),covma{5},n(5),0.05);
  axis equal;
  zoom out;
  xlabel(g);
  title('Progress Graph');
  ylabel('Data vs Clusters');
  grid on;
  hold off
pause(0.1);

  if w==4    %tests' whether your initial graph counter is 4 in order to reset him and subplot to
    w=0;    %the correct position.
  else
    w=w;
  end %if

   %f(xi|theta-hat) matrix (n*k) -which is for every xi and every
    %mean,var-cov matrix.

 for k=1:5
     for i=1:t
 Q11=X(i,:)-mean(:,k)';  %xi-mean
 Q22=Q11';
   f(i,k)=(((2*pi)^-1)*(det(covma{k}))^(-1/2))*exp(-(1/2)*(Q11*(covma{k}^-1))*Q22);
 %The l(i,k) matrix is only computed in these two for's in order to avoid extra aggravation
 %of our program.

 l(i,k)=tk(k)*f(i,k);

    end %for
 end %for

%the log-likelihood of our data given the iteration c is equal to:
ll(c)=sum(log(sum(l,2)));

%  E-step (posterior expected value)

for i=1:t
    for k=1:5

        Z(i,k)=(tk(k)*f(i,k))/sum(tk'.*f(i,:)');
    end
end
save sampleresults1 Z mean covma n P ll ;

 end %while

% disp('Time to Find Clusters: ');
% Q(p)=toc
% LL{p}=ll;
% MEANS{p}=mean;
% COVS{p}=covma;
% save MEANS&COVS100 MEANS COVS Q LL;
% p
%end %for p
disp('Have a nice morning')


%% Copyright (C) 2016 Lagu
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy 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.
%%
%% 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
%% @defmethod @@sym invhilb (@var{n})
%% Return the symbolic inverse of the Hilbert matrix.
%%
%% Example:
%% @example
%% @group
%% invhilb (sym(2))
%%   @result{} ans = (sym 2×2 matrix)
%%       ⎡4   -6⎤
%%       ⎢      ⎥
%%       ⎣-6  12⎦
%% @end group
%% @end example
%%
%% @seealso{@@sym/hilb}
%% @end defmethod

function y = invhilb(x)
  if (nargin ~= 1)
    print_usage ();
  end

  y = inv(hilb(x));

end

%!test
%! A = invhilb(sym(3));
%! B = sym([9 -36 30;-36 192 -180;30 -180 180]);
%! assert( isequal( A, B))


function tests = test_spaces
  tests = functiontests(localfunctions);
end

function test_chol_update1(testCase)
    n = 5;
    A  = gallery('moler', n);
    L = sqrt(A(1,1));
    for c = 2:n
        % pick c elements from c-th column
        atom = A(1:c, c);
        L = spx.la.chol.chol_update(L, atom);
        estimate = L * L';
        verifyEqual(testCase, A(1:c, 1:c), estimate, 'AbsTol', 1e-6);
    end
end

function test_chol_update2(testCase)
    n = 10;
    D  = randn(n, n);
    A = D'*D;
    L = [];
    for c = 1:n
        % pick c elements from c-th column
        atom = A(1:c, c);
        L = spx.la.chol.chol_update(L, atom);
        estimate = L * L';
        verifyEqual(testCase, A(1:c, 1:c), estimate, 'AbsTol', 1e-6);
    end
end


function asa063_test01 ( )

%*****************************************************************************80
%
%% ASA063_TEST01 demonstrates the use of BETAIN.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 January 2008
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ASA063_TEST01:\n' );
  fprintf ( 1, '  BETAIN computes the incomplete beta function.\n' );
  fprintf ( 1, '  Compare to tabulated values.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '      A       B       X       ' );
  fprintf ( 1, 'FX                       FX2\n' );
  fprintf ( 1, '                              ' );
  fprintf ( 1, '(Tabulated)              (BETAIN)                DIFF\n' );
  fprintf ( 1, '\n' );

  n_data = 0;

  while ( 1 )

    [ n_data, a, b, x, fx ] = beta_inc_values ( n_data );

    if ( n_data == 0 )
      break
    end

    beta_log = gammaln ( a ) ...
             + gammaln ( b ) ...
             - gammaln ( a + b );

    [ fx2, ifault ] = betain ( x, a, b, beta_log );

    fprintf ( 1, '  %6.2f  %6.2f  %6.2f  %24.16e  %24.16e  %10.4e\n', ...
    a, b, x, fx, fx2, abs ( fx - fx2 ) );

  end

  return
end


function y = daxpy ( n, sa, x, incx, y, incy )

%*****************************************************************************80
%
%% DAXPY adds a constant times one vector to another.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  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.
%    ISBN 0-89871-172-X
%
%    Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh,
%    Basic Linear Algebra Subprograms for Fortran Usage,
%    Algorithm 539,
%    ACM Transactions on Mathematical Software,
%    Volume 5, Number 3, September 1979, pages 308-323.
%
%  Parameters:
%
%    Input, integer N, the number of entries in the vector.
%
%    Input, real SA, the multiplier.
%
%    Input, real X(*), the vector to be scaled and added to Y.
%
%    Input, integer INCX, the increment between successive entries of X.
%
%    Input/output, real Y(*), the vector to which a
%    multiple of X is to be added.
%
%    Input, integer INCY, the increment between successive entries of Y.
%
  y(1:incy:1+(n-1)*incy) = y(1:incy:1+(n-1)*incy) + sa * x(1:incx:1+(n-1)*incx);

  return
end


function im = HOGpicture(w, bs)
% Make picture of positive HOG weights.
%   im = HOGpicture(w, bs)

% AUTORIGHTS
% -------------------------------------------------------
% Copyright (C) 2011-2012 Ross Girshick
% Copyright (C) 2008, 2009, 2010 Pedro Felzenszwalb, Ross Girshick
% Copyright (C) 2007 Pedro Felzenszwalb, Deva Ramanan
%
% This file is part of the voc-releaseX code
% (http://people.cs.uchicago.edu/~rbg/latent/)
% and is available under the terms of an MIT-like license
% provided in COPYING. Please retain this notice and
% COPYING if you use this file (or a portion of it) in
% your project.
% -------------------------------------------------------

% construct a "glyph" for each orientaion
bim1 = zeros(bs, bs);
bim1(:,round(bs/2):round(bs/2)+1) = 1;
bim = zeros([size(bim1) 9]);
bim(:,:,1) = bim1;
for i = 2:9,
  bim(:,:,i) = imrotate(bim1, -(i-1)*20, 'crop');
end

% make pictures of positive weights bs adding up weighted glyphs
s = size(w);
w(w < 0) = 0;
im = zeros(bs*s(1), bs*s(2));
for i = 1:s(1),
  iis = (i-1)*bs+1:i*bs;
  for j = 1:s(2),
    jjs = (j-1)*bs+1:j*bs;
    for k = 1:9,
      im(iis,jjs) = im(iis,jjs) + bim(:,:,k) * w(i,j,k);
    end
  end
end


function tests = TwistTest
  tests = functiontests(localfunctions);

  clc
end

function twist2d_test(tc)
    %%2D twists

    % check basics work
    s = [1 2 3];
    tw = Twist(s);
    verifyEqual(tc, tw.S, s', 'absTol', 1e-6);
    verifyEqual(tc, tw.v', s(1:2), 'absTol', 1e-6);
    verifyEqual(tc, tw.w, s(3), 'absTol', 1e-6);
    verifyEqual(tc, tw.se, [skew(s(3)) [s(1:2)]'; 0 0 0], 'absTol', 1e-6);
end

function operator2d_test(tc)
    % check overloaded *

    tw = Twist([1 2 3]);
    tw2 = Twist([4 6 5]);

    both = tw * tw2;

    Tboth = tw.T * tw2.T;
    verifyEqual(tc, both.T, Tboth, 'absTol', 1e-6);

    % check rotational twist
    tw = Twist('R', [1 2]);
    verifyEqual(tc, tw.S, [2 -1 1]', 'absTol', 1e-6);

    % check prismatic twist
    tw = Twist('P', [2 3]);
    verifyEqual(tc, tw.S, [unit([2 3]) 0]', 'absTol', 1e-6);
    tw = Twist('T', [2 3]);
    verifyEqual(tc, tw.S, [unit([2 3]) 0]', 'absTol', 1e-6);

    % check twist from SE(2)
    tw = Twist( trot2(0) );
    verifyEqual(tc, tw.S, [0 0 0]', 'absTol', 1e-6);
    tw = Twist( trot2(pi/2) );
    verifyEqual(tc, tw.S, [0 0 pi/2]', 'absTol', 1e-6);
    tw = Twist( SE2(1,2,0) );
    verifyEqual(tc, tw.S, [1 2 0]', 'absTol', 1e-6);
    tw = Twist( SE2(1,2,pi/2) );
    verifyEqual(tc, tw.S, [3*pi/4 pi/4 pi/2]', 'absTol', 1e-6);

    % test expm and T
    verifyEqual(tc, tw.T, trexp2(tw.S), 'absTol', 1e-6);
    verifyEqual(tc, tw.exp.double, trexp2(tw.S), 'absTol', 1e-6);

    tw = Twist('R', [1 2]);
    verifyEqual(tc, tw.T(pi/2), [0 -1 3; 1 0 1; 0 0 1], 'absTol', 1e-6);
end

function operator3d_test(tc)
    %% 3D twists

    % check basics work
    s = [1 2 3 4 5 6];
    tw = Twist(s);
    verifyEqual(tc, tw.S, s', 'absTol', 1e-6);
    verifyEqual(tc, tw.v', s(1:3), 'absTol', 1e-6);
    verifyEqual(tc, tw.w', s(4:6), 'absTol', 1e-6);
    verifyEqual(tc, tw.se, [skew(s(4:6)) [s(1:3)]'; 0 0 0 0], 'absTol', 1e-6);

    % check overloaded *
    s2 = [4 6 5 7 9 8];
    tw2 = Twist(s2);

    both = tw * tw2;

    Tboth = tw.T * tw2.T;
    verifyEqual(tc, double(both.T), double(Tboth), 'absTol', 1e-6);

    % check rotational twist
    tw = Twist('R', [1 2 3], [0 0 0]);
    verifyEqual(tc, tw.S, [0 0 0 unit([1 2 3])]', 'absTol', 1e-6);

    % check prismatic twist
    tw = Twist('P', [1 2 3]);
    verifyEqual(tc, tw.S, [unit([1 2 3]) 0 0 0 ]', 'absTol', 1e-6);
    tw2 = Twist('T', [1 2 3]);
    verifyEqual(tc, tw.S, tw2.S, 'absTol', 1e-6);

    % check twist from SE(3)
    tw = Twist( trotx(0) );
    verifyEqual(tc, tw.S, [0 0 0  0 0 0]', 'absTol', 1e-6);
    tw = Twist( trotx(pi/2) );
    verifyEqual(tc, tw.S, [0 0 0  pi/2 0 0]', 'absTol', 1e-6);
    tw = Twist( troty(pi/2) );
    verifyEqual(tc, tw.S, [0 0 0  0 pi/2 0]', 'absTol', 1e-6);
    tw = Twist( trotz(pi/2) );
    verifyEqual(tc, tw.S, [0 0 0  0 0 pi/2]', 'absTol', 1e-6);

    tw = Twist( transl([1 2 3]) );
    verifyEqual(tc, tw.S, [1 2 3  0 0 0]', 'absTol', 1e-6);
    tw = Twist( transl([1 2 3])*troty(pi/2) );
    verifyEqual(tc, tw.S, [-pi/2 2 pi  0 pi/2 0]', 'absTol', 1e-6);

    % test expm and T
    verifyEqual(tc, tw.T, SE3.exp(tw.S).T);
    verifyEqual(tc, tw.exp, SE3.exp(tw.S));

    tw = Twist('R', [1 0 0], [0 0 0]);
    verifyEqual(tc, tw.T(pi/2), SE3.Rx(pi/2).T, 'absTol', 1e-6);
    tw = Twist('R', [0 1 0], [0 0 0]);
    verifyEqual(tc, tw.T(pi/2), SE3.Ry(pi/2).T, 'absTol', 1e-6);
    tw = Twist('R', [0 0 1], [0 0 0]);
    verifyEqual(tc, tw.T(pi/2), SE3.Rz(pi/2).T, 'absTol', 1e-6);
end

function char_test(tc)
    % 2d

    tw = Twist([1 2 3]);

    s = char(tw);
    tc.verifyClass(s, 'char');
    tc.verifyEqual(size(s,1), 1);
    s = char([tw tw tw]);
    tc.verifyClass(s, 'char');
    tc.verifyEqual(size(s,1), 3);
    s = char([tw tw tw]');
    tc.verifyClass(s, 'char');
    tc.verifyEqual(size(s,1), 3);

    % 3d
    tw = Twist([4 6 5 7 9 8]);
    s = char(tw);
    tc.verifyClass(s, 'char');
    tc.verifyEqual(size(s,1), 1);
    s = char([tw tw tw]);
    tc.verifyClass(s, 'char');
    tc.verifyEqual(size(s,1), 3);
    s = char([tw tw tw]');
    tc.verifyClass(s, 'char');
    tc.verifyEqual(size(s,1), 3);
end


function bd=dfun(t,b);
bd=zeros(3,1);
bd(1)=-b(1)+b(2)+b(3)+b(1)*((b(1)^2)+(b(2)^2)+(b(3)^2));
bd(2)=-b(1)-b(2)+b(3)+b(2)*((b(1)^2)+(b(2)^2)+(b(3)^2));
bd(3)=-b(1)-b(2)-b(3)+b(3)*((b(1)^2)+(b(2)^2)+(b(3)^2));


% interpmethod is either 'linear' or 'spline'
function [z,Hu] = htls(k,y,interpmethod)
% "Algorithm for time-domain NMR data fitting based on total least squares"
% Vanhuffel, S., Chen, H., Decanniere, C. and Vanhecke, P., (1994)
if nargin < 3; interpmethod = 'linear'; end

y = complete_signal(y,interpmethod);
n = length(y);
y = reshape(y,[n,1]);
l = ceil(n/2);
Hy = hankel(y(1:l),y(l:n));
[U,~,~] = svd(Hy,'econ');
Ur = U(:,1:k);
Ur1 = Ur(2:end,:);
Ur2 = Ur(1:end-1,:);
[~,~,V] = svd([Ur2 Ur1]);
I = 1:k;
V12 = V(I,k+I);
V22 = V(k+I,k+I);
Q = -V12/V22;
e = eig(Q);
A = (e.^(0:n-1)).';
c = A \ y;
u = A*c;
Hu = hankel(u(1:k+1),u(k+1:n));
[U,~,~] = svd(Hu,'econ');
z = U(:,end);

function y = complete_signal(y,interpmethod)
I = isnan(y);
if ~any(I); return; end
t = 1:length(y);
y(I) = interp1(t(~I),y(~I),t(I),interpmethod);


% 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 pathS = MC_NIGGOU(S0,r,d,T,alpha,beta,delta,lambda,a,b,NTime,NSim,NBatches)
% discretization of Normal Inverse Gaussian process with
% Gamma Ornstein-Uhlenbeck clock

intNt = 10;                 % steps in between orginial grid points
allsteps = intNt * NTime;   % All Nts that have to be simulated
dT = T / NTime;        % Delta for time discretization
time = 0 : dT : T;    % dummy for martingale correction

pathS = zeros(NSim,NTime+1,NBatches); % output
lnS = zeros(NSim,NTime+1);            % used in batch
lnS(:,1) = log(S0*exp(-d*T));         % set S(0) dividend adjusted

% precompute constants
y0 = 1;
psiNIG = (-1i)*(-delta)*(sqrt(alpha^2-(beta+1)^2) ...
    -sqrt(alpha^2-beta^2));                       % char exp
phiGOU = 1i*psiNIG*y0/lambda*(1-exp(-lambda*time)) ...
         + lambda*a./(1i*psiNIG-lambda*b) ...
         .*(b*log(b./(b-1i*psiNIG/lambda ...
         *(1-exp(-lambda*time))))-1i*psiNIG*time);% char func
omegaT = -phiGOU;           % martingale correction
omegaT(1) = 0;              % martingale correction in 0

for l = 1 : NBatches        % batch loop
    yy = ones(NSim,allsteps+1);             % spot clock
    Np = poissrnd(a*lambda/allsteps*T,[NSim,allsteps]);   % Poissonians

    for k = 1 : NSim
        for j = 1 : allsteps                  % generating OU process
            if Np(k,j) > 0
                Ex = -log(rand(Np(k,j),1))/b; % RVs with exponential law
                U = exp(-lambda * T / allsteps * rand(Np(k,j),1));          % Uniforms
                yy(k,j+1) = (1-lambda*T/allsteps)*yy(k,j) + sum(Ex .* U);
         else
                yy(k,j+1) = (1-lambda*T/allsteps)*yy(k,j);
            end
        end
    end

    ZZ = T*cumsum(yy,2)/allsteps;       % integrated Gamma O-U process
    Y = zeros(NSim,NTime+1);            % intergrated time
    % compute the integrated time at discretization steps
    for m=2:NTime+1
        Y(:,m) = ZZ(:,(m-1)*intNt);
    end

    for m=2:NTime+1     % time loop
        a_par = Y(:,m)-Y(:,m-1);             % IG param
        b_par = delta*sqrt(alpha^2-beta^2);  % IG param
        theta = a_par/b_par;
        chi = a_par.^2;
        %Yvec = ones(NSim,1);
        %for n = 1:NSim
        %    Yvec(n) = randraw('ig', [theta(n), chi(n)], 1 );
        %end
        chisq1 = randn(NSim,1).^2;
        Yvec = theta + 0.5*theta./chi .* ( theta.*chisq1 - ...
            sqrt(4*theta.*chi.*chisq1 + theta.^2.*chisq1.^2) );
        Ind = find(rand(NSim,1) >= theta./(theta+Yvec));
        Yvec(Ind) = theta(Ind).^2./Yvec(Ind);   % subordinator

        Zvec = randn(NSim,1);       % Gaussian
        lnS(:,m) = lnS(:,m-1) + (r-d)*dT + omegaT(m)-omegaT(m-1) ...
                     + beta*delta^2*Yvec + delta*sqrt(Yvec).*Zvec;
    end
    pathS(:,:,l) = exp(lnS);   % spot paths
end


function [mu, B] = clg_Mstep_simple(w, Y, YY, YTY, X, XX, XY)
% CLG_MSTEP_SIMPLE Same as CLG_MSTEP, but doesn;t estimate Sigma,  so is slightly faster
% function [mu, B] = clg_Mstep_simple(w, Y, YY, YTY, X, XX, XY)
%
% See clg_Mstep for details.
% Unlike clg_Mstep, there are no optional arguments, which are slow to process
% if this function is inside a tight loop.

[Ysz Q] = size(Y);

if isempty(X) % no regression
  %B = [];
  B2 = zeros(Ysz, 1, Q);
  for i=1:Q
    B(:,:,i) = B2(:,1:0,i); % make an empty array of size Ysz x 0 x Q
  end
  [mu, Sigma] = mixgauss_Mstep(w, Y, YY, YTY);
  return;
end

N = sum(w);
%YY = YY + cov_prior; % regularize the scatter matrix

% Set any zero weights to one before dividing
% This is valid because w(i)=0 => Y(:,i)=0, etc
w = w + (w==0);

Xsz = size(X,1);
% Append 1 to X to get Z
ZZ = zeros(Xsz+1, Xsz+1, Q);
ZY = zeros(Xsz+1, Ysz, Q);
for i=1:Q
  ZZ(:,:,i) = [XX(:,:,i)  X(:,i);
	       X(:,i)'    w(i)];
  ZY(:,:,i) = [XY(:,:,i);
	       Y(:,i)'];
end

mu = zeros(Ysz, Q);
B = zeros(Ysz, Xsz, Q);
for i=1:Q
  % eqn 9
  if rcond(ZZ(:,:,i)) < 1e-10
    sprintf('clg_Mstep warning: ZZ(:,:,%d) is ill-conditioned', i);
    %probably because there are too few cases for a high-dimensional input
    ZZ(:,:,i) = ZZ(:,:,i) + 1e-5*eye(Xsz+1);
  end
  %A = ZY(:,:,i)' * inv(ZZ(:,:,i));
  A = (ZZ(:,:,i) \ ZY(:,:,i))';
  B(:,:,i) = A(:, 1:Xsz);
  mu(:,i) = A(:, Xsz+1);
end


function psi = psiEval(l, C, LR, N, dim, nVars)
%PSIEVAL   Evaluate a psi-function.
%   PSI = PSIEVAL(L, C, LR, N, DIM, NVARS) evaluates the psi-function of index L
%   and coefficient C with the contour LR, N grid points, in dimension DIM and
%   with NVARS variables.
%
% See also EXPINTEG/PHIEVAL, EXPINTEG/PHIFUN.

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

% Get a function handle to the phi-function of index L:
phi = expinteg.phiFun(l);

% Evaluate the psi-function with a contour integral:
psi = mean(C^l*feval(phi, C*LR), 2);

% Reshape it when nVars>1 or/and dim>1:
psi = reshape(psi, nVars*N, N^(dim>1), N^(dim>2));

end


function re =maxMed(img, sz)
img = double(img);
cx = (sz + 1)/2;
cy = (sz + 1)/2;
op1 = zeros(sz);
op2 = zeros(sz);
op1(:, cx) = 1;
op2(cy, :) = 1;
op3 = diag( ones(1, sz));
op4 = fliplr(op3);
re1 = ordfilt2(img, (sz +1)/2, op1, 'symmetric');
re2 = ordfilt2(img, (sz +1)/2, op2, 'symmetric');
re3 = ordfilt2(img, (sz +1)/2, op3, 'symmetric');
re4 = ordfilt2(img, (sz +1)/2, op4, 'symmetric');
back = max( cat(3, re1, re2, re3, re4), [], 3);
re = img - back;
end


function desc = calHsi(rgb_im, seg, numRegion)

    hsi = rgb2hsi_refine(rgb_im);

    ind={};
    for iReg=1:numRegion
        ind{iReg} = seg(:)==iReg;
    end

    desc = zeros([numRegion 3]);

    for ch=1:3
        for iReg = 1:numRegion
            feature = hsi(:,:,ch);
            feature = feature(ind{iReg});
            desc(iReg, ch) = sum(feature) / sum(ind{iReg});
        end
    end

end


function [ y, m, d ] = day_carry_gregorian ( y, m, d )

%*****************************************************************************80
%
%% DAY_CARRY_GREGORIAN carries days to months in a Gregorian date.
%
%  Discussion:
%
%    While ( number of days in M ) < D:
%      decrease the day D by the number of days in the month M;
%      increase M by 1;
%      if necessary, adjust Y.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 December 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, integer M, integer D, the YMD date.
%
%    Output, integer Y, integer M, integer D, the YMD date.
%    On output, D is between 1 and the number of days in M.
%
  days = month_length_gregorian ( y, m );

  while ( days < d )

    d = d - days;
    m = m + 1;
    days = month_length_gregorian ( y, m );
%
%  Make sure the month isn't too big.
%
    [ y, m ] = month_carry_gregorian ( y, m );

  end

  return
end


% function [datapeaks datavalleys] = findpeak(plotswitch,datain)
% This program finds peaks
% Arguments:
%   ploswitch: 0 or 1 : disable or enable plots (for debugging)
%   datain: 1D variable
% Dependencies:
%
% Copyright (c) 2011, Arun Ramakrishnan
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in the
%       documentation and/or other materials provided with the distribution.
%     * Neither the name of the <organization> nor the
%       names of its contributors may be used to endorse or promote products
%       derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
% DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
% DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
% ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

function [datapeaks datavalleys] = findinflections(plotswitch,datain)
% datain = gconv;
datad1=[diff(datain)];
mp = find(datad1>0);
mn = find(datad1<=0);

datapeaks = [];
for pindex = 1:length(mp)
    [maxvalue, maxindex] = max(datain(mp(pindex):mn(min(find(mn>mp(pindex))))));
    if ~isempty(maxindex)
        datapeaks = cat(1,datapeaks, floor(mean(maxindex))+mp(pindex)-1);
    end
end
datapeaks= unique(datapeaks);

datavalleys = [];
for pindex = 1:length(mn)
    [minvalue, minindex] = min(datain(mn(pindex):mp(min(find(mp>mn(pindex))))));
    if ~isempty(minindex)
        datavalleys = cat(1,datavalleys, floor(mean(minindex))+mn(pindex)-1);
    end
end
datavalleys= unique(datavalleys);

if (plotswitch)
    plot(1:length(datain),datain,'k-',mp,datain(mp),'b.',mn,datain(mn),'r.',datapeaks,datain(datapeaks),'g.',datavalleys,datain(datavalleys),'c.');
end


function varargout = mcint(h, n, opt)

%MCINT Monte Carlo integrator for multiple functions
%
% Satisfy your wildest integration fantasies!
%
%
%
% written by Lee Ferchoff, 2006
% Do not modify this file in any way unless for your own personal
% use. Do not re-release any part of the code contained in this file.
% Do not attach your own name to any part of the code contained in this
% file. Please reference me and e-mail to inform me if you use any part
% of this code, or original ideas from the algorithm. Thanks! Hope you find
% it helpful.
% E-mail: umferch1 at cc DOT umanitoba DOT ca
%
%
%
%
% A real-valued integral is calculated in arbitrary n-dimensional
% coordinates by averaging the value of a
% function over a large number of randomly selected points within the
% hypervolume to be integrated. Multiple functions can be integrated
% simultaneously over the same domain. The hypervolume can be of
% arbitrary shape, as long as it can be expressed as a series of
% logical conditions on the coordinates.
%
% Examples of the usage of mcint can be found in learnmcint.m
%
% Throughout, x(i,j) contains the matrix of "darts", or random
% points used to evaluate the function to be integrated.
% The rows i, refer to the ith coordinate of a
% point, where each column j, is a separate point. In standard
% notation, the coordinate vectors of all points 'n' are given by:
%
%       1-coordinate vector is     x(1,:)
%       2-coordinate vector is     x(2,:)
%       3-coordinate vector is     x(3,:)
%       ...
%       mth-coordinate is   x(m,:)
%
% In Cartesian coordinates, you might define the 1-dimension to be x,
% the 2-dimension to be y, or if you are using spherical coordinates,
% you could define the 1-dimension to be r, the 2-dimension to be
% theta, and the 3-dimension to be phi.
%
% This is the format that must be used when passing functions
% of coordinates to mcint. Operations on these coordinates must
% be written as vector operations (i.e. .* and .^, not * and ^).
%
% To integrate in a non-Cartesian coordinate system, in your
% function definition, multiply by the Jacobian from
% the Cartesian to 'system' transformation, for whatever coordinate
% system you are using. Jacobians for common coordinate systems
% can be obtained from jacobian.m. For example, to integrate
% f(r,theta,phi) in spherical coordinates, on paper you would write
%
%   triple integral ( f(r,theta,phi) * r^2 * sin(theta) dr d(theta) d(phi) )
%
% So the integrand should be defined as:
%
%   "f(x)" .* x(1,:).^2 + sin(x(2,:))
%       or making use of jacobian.m;
%   "f(x)" .* jacobian(x,'spherical')
%
% You can write your own Jacobian in, if you choose not to call jacobian.m.
% This flexibility allows you to mix coordinate systems. For example, you
% can do a 6-dimensional integral where three of the dimensions are in
% spherical coordinates and the other three are in elliptical. Furthermore,
% you can choose whatever order you want for the coordinate
% defintions, as long as you write the Jacobian accordingly. For example,
% x(1,:) could be theta, x(2,:) r, x(3,:) the angular variable in the
% elliptic coordinates, and so on.
%
%
%INPUT
%
% h -- data structure defining a hypervolume integration problem
%
%   h.b(i,j) -- bounding parallepiped of the hypervolume to be
%       integrated.
%       size(b) = [dim 2] where dim is the number of dimensions
%       of the hypervolume. (i,1) is the minimum bounding coordinate
%       in the ith dimension and (i,2) is the maximum bounding coordinate
%       in the ith dimension.
%
%       Example: To integrate x from -1 to 1, and y from 0 to Inf,
%                b(:,1) = [-1; 0]
%                b(:,2) = [1; Inf]
%
%   h.cond{1,j} (OPTIONAL) -- cell array which contains the functions
%       expressing additional logical conditional statements that define
%       a hypervolume within its bounding box. These conditional
%       statements, indexed by j, are functions.
%       h.cond may be empty, if one wishes to integrate
%       over a rectangular parallepiped and doesn't
%       require any further logical conditions on the
%       hypervolume.
%
%       Example: cond = {@outCircle @aboveLine}
%                where the functions are defined as:
%
%                function tf = outcircle(x, par)
%                   tf = x(1,:).^2 + x(2,:).^2 >= 1;
%
%                function tf = aboveLine(x, par)
%                   tf = x(2,:) > x(1,:);
%
%                In this example, our hypervolume of integration
%                is restricted to the region outside of circle of
%                radius 1 at the origin, and to the upper left
%                of the line y=x.
%
%       All h.cond function definitions should take a structure par as
%       their second input, even if no parameters from 'par' are used in
%       the funciton.
%
%   h.funcs{1,j} -- cell array which contains the functions to be
%       integrated. When the jth function is evaluated, it returns
%       the evaluation of the jth integrand. The usual usage is
%       to enter a function that returns an row vector for the integrand
%       f(1,k), where the kth column is the integrand evaluated at the
%       kth dart point. mcint tests the conditions in the order you enter
%       them in the cell array, therefore it is most efficient to list
%       them from most likely to fail to least likely to fail.
%
%       Example: function f = simpleExample(x, par)
%                   f = x(1,:).^2 .* 2*exp(-x(2,:));
%
%       In this case, the integral returned will be a scalar, I(1,1)
%       containing the value of the integral.
%
%       If h.funcs contains several functions, I(1,m) will be the
%       value of the integral for the mth function in h.funs.
%
%       Example: function f = simpleExample(x, par)
%                   f = x(1,:).^2 .* 2*exp(-x(2,:));
%                function f = Id(x)
%                   f = ones( 1, size(x,2));
%
%       In this example, I(1,1) will be the integral of @simpleExample
%       and I(1,2) will be the integral of @Id. Note that @Id is the
%       identity function; to obtain the hypervolume itself, simply
%       integrate this identity function.
%
%       To allow greater flexibility, a function handle may contain
%       more than one function. If h.funcs contains one function handle
%       which returns a function with m rows, then I(m,1) will be
%       the integral for the integrand defined by the mth row returned
%       by the function.
%
%       Example: function f = energy(x, par)
%                   p = calculatePsi(x);
%                   H = getHamiltonian(x);
%                   f(1,:) = conj(p).*H.*p;
%                   f(2,:) = conj(p).*p;
%
%       This example shows you how you might calculate the expectation
%       value of energy for a quantum system. Here we've calculated
%       p (the wavefunction psi) and H (the Hamiltonian) on the random
%       dart matrix (x). Row one of the function will be the
%       evaluation of the integrand for the expectation value of the
%       Hamiltonian, and row two will be the probability density.
%       mcint will give I(1,1) which is the expectation value of the
%       Hamiltonian, and I(2,1) which is the total probability. Then
%       the user can simply find the expectation value of energy as
%       I(1,1)/I(2,1).
%
%       This method of putting multiple integrands in one function
%       handle is preferable when they are calculated with the same
%       ingredients. It would be more time consuming to make a separate
%       function handle for both expectation values calculated above
%       since the wavefunction psi would have to be calculated in
%       BOTH of the function handles with a call to @calculatePsi:
%                   p = calculatePsi(x);
%
%       This inefficiency can thus be avoided. In Quantum Energy Solver
%       (Lee Ferchoff), I use this method to calculate the expectation
%       value of the Hamiltonian, and the identity operator for ALL of
%       the individuals in the population at at once under one function
%       handle.
%
%       NOTE: As of now, if multiple function handles are used, each one
%             must contain the same number of rows. Support will be added
%             for varying numbers of rows in a future version.
%
%       In general, if h.funcs contains j function handles, then mcint
%       returns I, where I(i,j) is the integral of the function in the ith
%       row of the jth function handle.
%
%       All h.funcs function definitions should take a structure 'par' as
%       their second input, even if no parameters from 'par' are used in
%       the funciton.
%
%
% n -- the number of randomly chosen sampling points
%
%
% opt (OPTIONAL) -- integration options
%
%   opt.maxArray -- adjustable max array size parameter. mcint has
%       built-in memory management. This is the largest number
%       of elements that will be stored in memory for
%       use by mcint at any given time.
%
%       NOTE: The default max array size of 1e4 has been tested
%       extensively, this gives the shortest run time for a fixed amount
%       of points. This has been tested for integrals of dimensions 1 and
%       3 and n of 1e5 and 5e6, and it was found that run time increased
%       if the max array size was either increased or decreased from 1e4
%       in all cases.
%       If it is decreased from 1e4, the run time sharply increases. This
%       is because we lose most of the vectorization of the code,
%       since the function evaluations are broken up into vectorized
%       groups of the maximum array size. If the max array size is
%       increased from 1e4, the run time gradually increases by about
%       25% until memory management is not being used and the whole
%       integration is done in one shot. I suppose this is because
%       doing stuff with really large matricies is unwieldy and in
%       this case breaking up a bit of the vectorization at the benefit
%       of using smaller matricies seems to be a good thing.
%
%       1e-4 is optimum for the linux boxes in Room 523.
%       Anything above 1e-3 seems to be handled equally well by
%       hactar.
%   opt.noerror -- if true, statistical errors are not calculated and
%       only the integral value is returned. Note that this mode cannot
%       be used when a tolerance is requested with opt.tol.
%   opt.tol -- TOLERANCE STOPPING CONDITION
%       absolute tolerance requested (integration will stop
%       when reached)
%       opt.tol(i,j) is the absolute tolerance
%         for the ith row of the jth function in h.funcs. If a tolerance
%         is set to zero, then it is taken to mean that no tolerance is
%         requested for that particular integral.
%   opt.time -- TIME STOPPING CONDITION
%       maximum time allowed in seconds. Integration
%       will end normally after this time.
%   opt.warnOff -- if true, turn off printed warnings, such as not meeting a
%       requested tolerance
%   opt.mcintPar -- a struture containing parameters that is passed to the
%       functions in h.funcs, which can be used in function evaluation
%
%OUTPUT
%
% varargout(1) is
% I(i,j,k) -- integral (with optional error)
%     I(i,j,1) -- value of the integral for the integrand defined
%     in the ith row of the jth function handle in h.funcs.
%     I(i,j,2) -- value of the statistical error of the integral
%     for the integrand defined in the ith row of the jth function
%     handle in h.funcs. The error is calculated from random fluctations
%     of the integrand about its mean value.
%
%     Errors are calculated by default, so k=1:2 by default.
%     If user passes opt.noerror=1 to mcint, then no errors are
%     calculated, and so k=1 only.
%
% varargout(2) is
% info (OPTIONAL) -- technical data about the integration. The data
%     can be used for error checking.
%
%     info.maxArray -- maximum array size used
%     info.memoryManaged -- if true, the requested number of points
%         n was large enough, that the integration had to be
%         performed with chunks of size maxArray
%     info.noerror -- if true, no statistical error calculated
%     info.extraParameters -- if true, extra parameters were passed
%         to the functions to be integrated in opt.mcintPar
%
%     info.dim -- number of dimensions
%     info.n -- number of random points requested
%     info.points -- number of random points used
%     info.pointdiff -- info.n-info.points
%
%     info.tolReq(i,j) -- tolerance requested by user. The abs tolerance
%         for the ith row of the jth function in h.funcs. If a tolerance
%         is set to zero, then it is taken to mean that no tolerance is
%         requested for that particular integral. This is what the user
%         entered in opt.tol.
%     info.someTolReq -- if true, at least one integral tolerance has
%         been requested
%     info.tolMet(i,j) -- true in the indicies for integrals which
%         have had their requested tolerance met. (i,j) labels the ith
%         row of the jth function in h.funcs
%         info.tolMet=-1 in the indicies representing integrals for which
%         a specific tolerance was not requested. If no tolerance was
%         required for any integral, info.tolMet is a scalar -1.
%     info.allTolMet -- if true, the requested tolerance for every
%         tolerance was met
%     info.timeReq -- max time requested by the user. info.timeReq=-1
%         if a specific time limit was not requested
%     info.timeMet -- if true, the integration was within the requested
%         time. info.timeMet=-1 if a specific time limit was not
%         requested
%     info.totalTime -- total time required for integration
%
%
%FEATURES TO BE ADDED IN THE NEXT VERSION:
%
% - relative tolerance stopping condition
% - differening amounts of rows in the functions in h.funcs
% - protection against overflow from a chance hit near a singularity
%
%Lee Ferchoff

t0 = clock; % record initial time

if ~isfield(h,'cond')
    h.cond = {};
end

% ===========================
% SET OPTIONS
% ===========================

% --------------------------------------
% mcint is memory managed, and will not
% use an array that has more elements
% than the number maxArray
p.info.maxArray = 1e4; % default max array size
% will be changed if opt.maxArray is a field
% --------------------------------------

% -1 means no request
p.info.tolReq = -1;
p.info.someTolReq = -1;
p.info.tolMet = -1;
p.info.allTolMet = -1;
p.info.timeReq = -1;
p.info.timeMet = -1;

p.info.noerror = 0; % if true, statistical errors are not calculated
p.info.extraParameters = 0; % if true, the user has provided opt.mcintPar

warnOff = 0; % if true, no warnings will be printed to screen
p.par = [];

if nargin==3 % optional parameter structure opt has been provided
    if isfield(opt,'maxArray')
        p.info.maxArray = opt.maxArray;
    end
    if isfield(opt,'noerror')
        p.info.noerror = opt.noerror;
    end
    if isfield(opt,'mcintPar') % user has provided extra parameters
        p.info.extraParameters = 1;
        p.par = opt.mcintPar;
    end
    if isfield(opt,'tol') % user requested tolerances
        p.info.tolReq = abs(opt.tol);
        p.info.someTolReq = 1;
        p.info.tolMet = 0;
        p.info.allTolMet = 0;
    end
    if isfield(opt,'time') % user requested max integration time
        p.info.timeReq = opt.time;
        p.info.timeMet = 0;
    end
    if isfield(opt,'warnOff')
        warnOff = opt.warnOff;
    end
end
% error: can't not calculate error and still request an error tolerance
if p.info.noerror==1 && p.info.someTolReq==1
    if warnOff==0
        disp('WARNING: IF a tolerance is requested, error must be calculated.');
        disp('Integration will continue WITH error calculation.');
    end
    p.info.noerror = 0;
end

% ===========================
% SETUP INTEGRATION PROBLEM
% ===========================

p.dim = size(h.b, 1);
p.nf = length(h.funcs); % # functions
points = n; % running counter that keeps track of how many of the n darts have been thrown

% Transform any improper integral bounds:

% true in rows of b having at least one improper integral limit
p.infBound = sum(isinf(h.b),2) ~= 0;
% perform inverse tangent coordinate transformation on affected rows.
% This will allow us to calculate the improper integral in the old
% coordinate system as a proper integral in the new coordinate system.
h.b(p.infBound,:) = atan(h.b(p.infBound,:));
% p.infDims isthe numbers of the dimensions with improper limits
p.infDims = find(p.infBound==1);
p.improperProblem = ~isempty(p.infDims);  % if true, at least one infinite dim
V = prod(h.b(:,2) - h.b(:,1)); % bounding volume (after transformation)

% ===========================
% INTEGRATE
% ===========================

if p.dim*n <= p.info.maxArray

    p.info.memoryManaged = 0;

    p.cols = n;
    p.xMin=repmat(h.b(:,1),1,p.cols);
    p.xMax=repmat(h.b(:,2),1,p.cols);
    s = updateSums(h,p);

else % memory management needed

    p.info.memoryManaged = 1;

    p.cols = floor(p.info.maxArray/p.dim);
    p.xMin=repmat(h.b(:,1),1,p.cols);
    p.xMax=repmat(h.b(:,2),1,p.cols);

    % # of runs which use the full maxArray size
    fullruns = ceil(p.dim*n/p.info.maxArray)-1;
    for j=1:fullruns
        newS = updateSums(h,p);
        if ~exist('s') % first run through loop; initialize s, s2
            s = zeros(size(newS));
        end
        s = s + newS;
        points = j*p.cols;

        % Check for stopping conditions
        if (p.info.timeReq~=-1 && etime(clock,t0)>p.info.timeReq)
            % executes if max time has elapsed
            p.info.timeMet = 1;
            break;
        elseif p.info.someTolReq==1
            % checks if all tolerances have been met
            E = getError(s,points,V);
            tolMatrix = zeros(size(E));
            tolMatrix(:) = Inf;
            tolMatrix = p.info.tolReq(find(p.info.tolReq~=0));
            p.info.tolMet = E < tolMatrix;
            p.info.allTolMet = prod(+p.info.tolMet(:));
            if p.info.allTolMet==1
                break;
            end
        end
    end

    % if integration wasn't stopped by some condition, finish the leftover
    % points
    if ~(p.info.timeMet==1 || p.info.allTolMet==1)
        % The last update covers the leftover points on the exact
        % number of points the user requested

        p.cols = n - points;
        p.xMin=repmat(h.b(:,1),1,p.cols);
        p.xMax=repmat(h.b(:,2),1,p.cols);

        newS = updateSums(h,p);
        s = s + newS;

        points = points + p.cols;
    end

end

% ===========================
% REPORT RESULT
% ===========================

% return integral and possibly error
I(:,:,1) = V/points * s(:,:,1); % integral
if p.info.noerror==0
    I(:,:,2) = getError(s,points,V); % error
end
varargout(1) = {I};

% some tolerance was requested and wasn't met
if p.info.allTolMet==0 && warnOff==0
    disp('***');
    disp('Max number of requested darts thrown.');
    disp('Requested tolerance was not achieved.');
    disp('***');
end

 % build info structure to pass to user
if nargout==2
    p.info.dim = p.dim;
    p.info.n = n;
    p.info.points = points;
    p.info.pointdiff = n - points;
    p.info.totalTime = etime(clock,t0);

    varargout(2) = {p.info};
end

function E = getError(s,points,V)
%GETERROR Find the current statistical error of the integral
%
%INPUT
%   s -- s(:,:,1) function sums
%     -- s(:,:,2) function squared sums
%   points -- number of points in sum
%   V -- hypervolume
%
%OUTPUT
%
%   E(i,j) -- the current error of the ith row and jth column using the
%             function sums in s

E = V/points * sqrt(s(:,:,2) - s(:,:,1).*s(:,:,1)/points);

function s = updateSums(h, p)

%UPDATESUMS Calculate function sums for mcint
%
%INPUT
%   h -- data structure defining the hypervolume integration problem
%   p -- data structure containing the current parameters of the
%        integration
%
%OUTPUT
%   s(i,j,k)  -- k=1, sum of the functions over all darts
%                k=2, sum of the functions squared over all darts
%                   for the ith row of the jth function handle in h.funcs
%
%   if p.info.noerror=1, then the k=2 matrix is not returned

% p.xMin, p.xMax passed into function rather than being calculated
% in it so that p.xMin, p.xMax only need to be calculated once
% for many memory blocks of size info.maxArray

% ===========================
% GENERATE RANDOM DARTS
% ===========================

% x(i,j) is the ith Cartesian coordinate of the jth random point
x = p.xMin + (p.xMax-p.xMin) .* rand(p.dim,p.cols); % random dart matrix

% ===========================
% COORDINATE TRANSFORMATIONS
% ===========================

% perform coordinate transformations if there is at least one improper
% integral. Transform only the infinite dimensions, since the
% transformation costs time and is not needed for the finite dimensions
if p.improperProblem
    x(p.infDims,:) = tan( x(p.infDims,:) );
end

% remove all points from x which aren't in hypervolume
% by using the extra restrictions given on the hypervolume
for i=1:length(h.cond)
    x = x( :, feval(h.cond{i},x));
end

% we calculate the Jacobian of the arctan transformation AFTER removing
% the points that aren't in the hypervolume so we don't waste time
% calculating the Jacobian for points that aren't in the integration
if p.improperProblem
    jacobian = prod( x(p.infDims,:).^2 + 1, 1 );
end

% ===========================
% INTEGRAND EVALUATION
% ===========================

for i = p.nf: -1: 1
    f = feval(h.funcs{i}, x, p.par);
    if p.improperProblem % multiply by the Jacobian of the arctan transform
        jacobian = repmat(jacobian(1,:), [size(f,1) 1]);
        f = f .* jacobian;
    end
    s(:,i,1) = sum(f,2);
    if p.info.noerror==0
        s(:,i,2) = sum(f.*f,2);
    end
end


% book : Signals and Systems Laboratory with MATLAB
% authors : Alex Palamides & Anastasia Veloni
%
%
%
%  deconvolution

%vectors y and x and the time step are defined in the m-file c422.m

hh=deconv(y,x)*(1/step);

plot(t,hh)
ylim([-.1 1.1]);
legend('impulse response h(t)')


function [index, window] = FineMeyerWindow(dyadic_points,deg);
% FineMeyerWindow: Evaluates a highpass Meyer window
%  Usage:
%    [index, window] = FineMeyerWindow(L,deg);
%  Inputs:
%    dyadic-points   Pair of the form 2^j, 2^(j+1)
%    deg    Degree of the polynomial
%  Outputs:
%    index  location of the window on the time axis; contains [2^j 2^(j+1)]
%    window highpass Meyer window

pio2 = pi/2;

eps    = floor(dyadic_points(1)/3);
epsp   = dyadic_points(1) - eps - 1;
farlftind = [ 1 : dyadic_points(1)-eps];
lftind     = [ dyadic_points(1)-eps+1 : dyadic_points(1)];
lmidind    = [ dyadic_points(1)+1 : dyadic_points(1)+eps+1];
rmidind    = [ dyadic_points(2)-epsp+1 : dyadic_points(2) ];

farlft = zeros(1,length(farlftind));
lft  = sin(pio2*WindowMeyer(3*((lftind-1)/dyadic_points(2))-1,deg));
lmid = sin(pio2*WindowMeyer(3*((lmidind-1)/dyadic_points(2))-1,deg));
rmid = ones(1,length(rmidind));

index = [farlftind lftind lmidind rmidind];
window = [farlft lft lmid rmid];


function BER = get_ber(V_equal, W_equal)

global Ns Nsym Nr Vn H hMod hDemod;
%one channel realization for Nsym times data streams transmission
% 2 is for real and imaginary
data = randi([0 1],Nsym*Ns*2,1);

%QPSK modulation generate all original signals s in Nsym times
s = reshape(step(hMod,data),Ns, Nsym);

%generate noise vector u
u = sqrt(Vn/2).*(randn(Nr,Nsym)+1i*randn(Nr,Nsym));

%get the receive vector
%colloct Nsym receive vector in the r matrix, where nth column is a
%receive vector at n time
r = W_equal' * H * V_equal * s + W_equal' * u;

%QPSK demodulation
de_data = step(hDemod, r(:));
%get the number of error bits
ber = biterr(data,de_data);
BER = ber/length(data);


function [mm2] = yd22mm2(yd2)
% Convert area from square yards to square millimeters.
% Chad A. Greene 2012
mm2 = yd2*836127.36;


function [cost]=costf2(x)
global impvol; global strike; global T; global F0; global r;

for i=1:length(T)
%mok(i)=max(blsimpv(F0, strike(i), r,T(i),HestonCall(F0,strike(i),r,T(i),x(1),x(2),x(3),x(4),x(5),0), 3),0);
%cost(i)=impvol(i)-mok(i);
cost(i)=blsprice(F0,strike(i),r,T(i),impvol(i))-HestonCall(F0,strike(i),r,T(i),x(1),x(2),x(3),x(4),x(5),0);
end


function sparse_grid_composite_test06 ( dim_num, level_max )

%*****************************************************************************80
%
%% SPARSE_GRID_COMPOSITE_TEST06 creates a sparse composite grid and writes it to a file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 August 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer LEVEL_MAX, the level.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPARSE_GRID_COMPOSITE_TEST06:\n' );
  fprintf ( 1, '  SPARSE_GRID_COMPOSITE makes a sparse composite grid.\n' );
  fprintf ( 1, '  Write the data to a set of quadrature files.\n' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  LEVEL_MAX = %d\n', level_max );
  fprintf ( 1, '  Spatial dimension DIM_NUM = %d\n', dim_num );
%
%  Determine the number of points.
%
  point_num = sparse_grid_composite_size ( dim_num, level_max );

  r(1:dim_num,1) = -1.0;
  r(1:dim_num,2) = +1.0;
%
%  Compute the weights and points.
%
  [ w, x ] = sparse_grid_composite ( dim_num, level_max, point_num );
%
%  Write the data out.
%
  r_filename = sprintf ( 'composite_d%d_level%d_r.txt', dim_num, level_max );
  w_filename = sprintf ( 'composite_d%d_level%d_w.txt', dim_num, level_max );
  x_filename = sprintf ( 'composite_d%d_level%d_x.txt', dim_num, level_max );

  r8mat_write ( r_filename, dim_num, 2,         r );
  r8mat_write ( w_filename, 1,       point_num, w );
  r8mat_write ( x_filename, dim_num, point_num, x );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  R data written to "%s".\n', r_filename );
  fprintf ( 1, '  W data written to "%s".\n', w_filename );
  fprintf ( 1, '  X data written to "%s",\n', x_filename );

  return
end


%CORNERMINEIGENVAL  Calculates the minimal eigenvalue of gradient matrices for corner detection
%
%     dst = cv.cornerMinEigenVal(src)
%     dst = cv.cornerMinEigenVal(src, 'OptionName', optionValue, ...)
%
% ## Input
% * __src__ Input single-channel 8-bit or floating-point image.
%
% ## Output
% * __dst__ Image to store the minimal eigenvalues. It has the same size as
%   `src` and the `single` type (single-channel).
%
% ## Options
% * __BlockSize__ Neighborhood size (see the details on
%   cv.cornerEigenValsAndVecs). default 5.
% * __KSize__ Aperture parameter for the cv.Sobel operator. default 3.
% * __BorderType__ Pixel extrapolation method. See cv.copyMakeBorder.
%   default 'Default'
%
% The function is similar to cv.cornerEigenValsAndVecs but it calculates and
% stores only the minimal eigenvalue of the covariance matrix of derivatives,
% that is, `min(lambda_1,lambda_2)` in terms of the formulae in the
% cv.cornerEigenValsAndVecs description.
%
% See also: cv.cornerEigenValsAndVecs, detectMinEigenFeatures, cornerPoints
%


function [p, dp] = pne_pfcn_pseudo_arc_len(x, xp, step, zp)
%PNE_PFCN_PSEUDO_ARC_LEN  Pseudo arc length parameterization function for PNE
%   [P, DP] = PNE_PFCN_PSEUDO_ARC_LEN(X, XP, STEP, ZP)
%
%   Inputs:
%       X    : solution vector x (last element is parameter lambda)
%       XP   : previous solution vector
%       STEP : continuation parameter step size
%       ZP   : normalized tangent vector at XP
%
%   This function defines a pseudo arc length parameterization for a PNE,
%   where the current point on the solution curve is constrained to lie in
%   the hyperplane running through the predicted solution orthogonal to the
%   tangent line from the previous corrected solution.
%
%   Outputs:
%       P : value of parameterization function
%       DP : Jacobian of paramerization function (transpose of gradient)
%
%   See also PNE_PFCN_NATURAL, PNE_PFCN_ARC_LEN.

%   MP-Opt-Model
%   Copyright (c) 2013-2021, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%   and Shrirang Abhyankar, Argonne National Laboratory
%
%   This file is part of MP-Opt-Model.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://github.com/MATPOWER/mp-opt-model for more info.

dp = zp';                   %% derivative
p = dp * (x - xp) - step;   %% function