% Kernel Affine Projection (KAP) algorithm with coherence criterion
%
% C. Richard, J.C.M. Bermudez, and P. Honeine, "Online Prediction of Time
% Series Data With Kernels," IEEE Transactions on Signal Processing,
% vol. 57, no. 3, pp. 1058-1067, March 2009,
% http://dx.doi.org/10.1109/TSP.2008.2009895
%
% Remark: memories are initialized empty in this implementation
%
% This file is part of the Kernel Adaptive Filtering Toolbox for Matlab.
% https://github.com/steven2358/kafbox/

classdef kap < kernel_adaptive_filter

    properties (GetAccess = 'public', SetAccess = 'private')
        mu0 = .95; % coherence criterion threshold
        eta = .5; % step size
        eps = 1E-2; % regularization
        p = 20; % memory length
        kerneltype = 'gauss'; % kernel type
        kernelpar = 1; % kernel parameter
    end

    properties (GetAccess = 'public', SetAccess = 'private')
        memx = []; % input memory
        memy = []; % output memory
        dict = []; % dictionary
        modict = []; % modulus of the dictionary elements
        alpha = []; % expansion coefficients
    end

    methods
        function kaf = kap(parameters) % constructor
            if (nargin > 0) % copy valid parameters
                for fn = fieldnames(parameters)'
                    if ismember(fn,fieldnames(kaf))
                        kaf.(fn{1}) = parameters.(fn{1});
                    end
                end
            end
        end

        function y_est = evaluate(kaf,x) % evaluate the algorithm
            if size(kaf.dict,1)>0
                k = kernel(kaf.dict,x,kaf.kerneltype,kaf.kernelpar);
                y_est = k'*kaf.alpha;
            else
                y_est = zeros(size(x,1),1);
            end
        end

        function train(kaf,x,y) % train the algorithm
            if (length(kaf.memy) < kaf.p)
                kaf.memx = [kaf.memx; x]; % grow the memory
                kaf.memy = [kaf.memy; y]; % grow the memory
            else
                kaf.memx = [kaf.memx(2:end,:); x]; % sliding memory
                kaf.memy = [kaf.memy(2:end); y]; % sliding memory
            end

            if size(kaf.dict,2)==0 % initialize
                k = kernel(x,x,kaf.kerneltype,kaf.kernelpar);
                kaf.dict = x;
                kaf.modict = sqrt(k);
                kaf.alpha = 0;
            else
                k = kernel(kaf.dict,x,kaf.kerneltype,kaf.kernelpar);
                kx = kernel(x,x,kaf.kerneltype,kaf.kernelpar);
                C = k./(sqrt(kx)*kaf.modict); % coherence
                if (max(C) <= kaf.mu0) % coherence criterion
                    kaf.dict = [kaf.dict; x]; % order increase
                    kaf.alpha = [kaf.alpha; 0]; % order increase
                end
            end

            H = kernel(kaf.memx,kaf.dict,kaf.kerneltype,kaf.kernelpar);
            kaf.alpha = kaf.alpha + ...
                kaf.eta*H'/...
                (kaf.eps*eye(size(H,1)) + H*H')*...
                (kaf.memy - H*kaf.alpha);
        end
    end
end


function [ o, x, w ] = cn_leg_01_1 ( n )

%*****************************************************************************80
%
%% CN_LEG_01_1 implements the midpoint rule for region CN_LEG.
%
%  Discussion:
%
%    The rule has order O = 1.
%
%    The rule has precision P = 1.
%
%    CN_LEG is the cube [-1,+1]^N with the Legendre weight function
%
%      w(x) = 1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the spatial dimension.
%
%    Input, integer O, the order.
%
%    Output, real X(N,O), the abscissas.
%
%    Output, real W(O), the weights.
%
  o = 1;

  expon = 0;
  value1 = c1_leg_monomial_integral ( expon );
  volume = value1 ^ n;

  x = zeros ( n, o );
  w = zeros ( o, 1 );

  k = 0;
%
%  1 point.
%
  k = k + 1;
  w(k) = volume;

  return
end


function [] =  TestKShortestPath(case_number)
% Tests the function kShortestPath(case_number) for one of the 3 basic test cases
% specified by case_number. Then it displays the reults.
%==============================================================
% Meral Shirazipour
% DATE :           December 9 decembre 2009
% Last Updated:    April 2 2010 ; August 2 2011
%==============================================================
switch case_number
    case 1
        netCostMatrix = [inf 1 inf 1 ; 1 inf 1 1 ;inf 1 inf inf ;inf inf inf inf ];
        source=3;
        destination=4;
        k = 5;
    case 2
        netCostMatrix = [inf 5 10 15 20 inf; 5 inf 10 inf inf 5;10 10 inf 15 inf 10; 15 inf 15 inf 20 15;20 inf inf 20 inf 20; inf 5 10 15 20 inf];
        source=1;
        destination=6;
        k = 20;
    case 3
        netCostMatrix = [inf 10 50 15 inf; 10 inf 10 inf 10; 50 10 inf 5 5; 15 inf 5 inf 15; inf 10 5 15 inf];
        source=1;
        destination=5;
        k = 20;
    otherwise
        error('The only case options available are 1, 2 or 3');
end

%------Show case selected:------:
fprintf('You selected case #%d, a %dx%d network:\n',case_number,size(netCostMatrix,1),size(netCostMatrix,1));
disp(netCostMatrix);
fprintf('The path request is from source node %d to destination node %d, with K = %d \n',source,destination, k);

%------Call kShortestPath------:
[shortestPaths, totalCosts] = kShortestPath(netCostMatrix, source, destination, k);

%------Display results------:
fprintf('\nResult of Function call: kShortestPath(netCostMatrix, source, destination, k)  = \n\n');

if isempty(shortestPaths)
    fprintf('No path available between these nodes\n\n');
else
    for i = 1: length(shortestPaths)
        fprintf('Path # %d:\n',i);
        disp(shortestPaths{i})
        fprintf('Cost of path %d is %5.2f\n\n',i,totalCosts(i));
    end
end

end


function  [Erange,eta,Eshort,fs] = erange(CIJ)
%ERANGE     Shortcuts
%
%   [Erange,eta,Eshort,fs] = erange(CIJ);
%
%   Shorcuts are central edges which significantly reduce the
%   characteristic path length in the network.
%
%   Input:      CIJ,        binary directed connection matrix
%
%   Outputs:    Erange,     range for each edge, i.e. the length of the
%                           shortest path from i to j for edge c(i,j) AFTER
%                           the edge has been removed from the graph.
%               eta         average range for entire graph.
%               Eshort      entries are ones for shortcut edges.
%               fs          fraction of shortcuts in the graph.
%
%   Follows the treatment of 'shortcuts' by Duncan Watts
%
%
%   Olaf Sporns, Indiana University, 2002/2007/2008

N = size(CIJ,1);
K = length(nonzeros(CIJ));
Erange = zeros(N,N);
[i,j] = find(CIJ==1);

for c=1:length(i)
   CIJcut = CIJ;
   CIJcut(i(c),j(c)) = 0;
   [R,D] = reachdist(CIJcut);                   %#ok<ASGLU>
   Erange(i(c),j(c)) = D(i(c),j(c));
end;

% average range (ignore Inf)
eta = sum(Erange((Erange>0)&(Erange<Inf)))/length(Erange((Erange>0)&(Erange<Inf)));

% Original entries of D are ones, thus entries of Erange
% must be two or greater.
% If Erange(i,j) > 2, then the edge is a shortcut.
% 'fshort' is the fraction of shortcuts over the entire graph.

Eshort = Erange>2;
fs = length(nonzeros(Eshort))/K;


function Bc = brownian_bridge(P,K,a,b,sigma)

t = linspace(0,1,P)';
% generate a bunch of bridges
B = (randn(P-1,K)+1i*randn(P-1,K))/sqrt(P);
B = [zeros(1,K); cumsum(B)];
B = B - t * B(end,:);
B = B*sigma;
Bc = B + repmat(1-t,[1 K])*a + repmat(t,[1 K])*b;

end


function [ c, seed ] = i4_uniform_ab ( a, b, seed )

%*****************************************************************************80
%
%% I4_UNIFORM_AB returns a scaled pseudorandom I4.
%
%  Discussion:
%
%    The pseudorandom number will be scaled to be uniformly distributed
%    between A and B.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 November 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Paul Bratley, Bennett Fox, Linus Schrage,
%    A Guide to Simulation,
%    Springer Verlag, pages 201-202, 1983.
%
%    Pierre L'Ecuyer,
%    Random Number Generation,
%    in Handbook of Simulation,
%    edited by Jerry Banks,
%    Wiley Interscience, page 95, 1998.
%
%    Bennett Fox,
%    Algorithm 647:
%    Implementation and Relative Efficiency of Quasirandom
%    Sequence Generators,
%    ACM Transactions on Mathematical Software,
%    Volume 12, Number 4, pages 362-376, 1986.
%
%    Peter Lewis, Allen Goodman, James Miller
%    A Pseudo-Random Number Generator for the System/360,
%    IBM Systems Journal,
%    Volume 8, pages 136-143, 1969.
%
%  Parameters:
%
%    Input, integer A, B, the minimum and maximum acceptable values.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, integer C, the randomly chosen integer.
%
%    Output, integer SEED, the updated seed.
%
  i4_huge = 2147483647;

  if ( seed == 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'I4_UNIFORM_AB - Fatal error!\n' );
    fprintf ( 1, '  Input SEED = 0!\n' );
    error ( 'I4_UNIFORM_AB - Fatal error!' );
  end

  seed = floor ( seed );
  a = round ( a );
  b = round ( b );

  seed = mod ( seed, i4_huge );

  if ( seed < 0 )
    seed = seed + i4_huge;
  end

  k = floor ( seed / 127773 );

  seed = 16807 * ( seed - k * 127773 ) - k * 2836;

  if ( seed < 0 )
    seed = seed + i4_huge;
  end

  r = seed * 4.656612875E-10;
%
%  Scale R to lie between A-0.5 and B+0.5.
%
  r = ( 1.0 - r ) * ( min ( a, b ) - 0.5 ) ...
    +         r   * ( max ( a, b ) + 0.5 );
%
%  Use rounding to convert R to an integer between A and B.
%
  value = round ( r );

  value = max ( value, min ( a, b ) );
  value = min ( value, max ( a, b ) );

  c = value;

  return
end


function [ w, x ] = lyness_rule ( rule, order )

%*****************************************************************************80
%
%% LYNESS_RULE returns the points and weights of a Lyness quadrature rule.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 October 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    James Lyness, Dennis Jespersen,
%    Moderate Degree Symmetric Quadrature Rules for the Triangle,
%    Journal of the Institute of Mathematics and its Applications,
%    Volume 15, Number 1, February 1975, pages 19-32.
%
%  Parameters:
%
%    Input, integer RULE, the index of the rule.
%
%    Input, integer ORDER, the order of the rule.
%
%    Output, real W(ORDER), the weights.
%
%    Output, real X(2,ORDER), the points.
%

%
%  Get the suborder information.
%
  suborder_num = lyness_suborder_num ( rule );

  suborder = lyness_suborder ( rule, suborder_num );

  [ sub_xyz, sub_w ] = lyness_subrule ( rule, suborder_num );
%
%  Expand the suborder information to a full order rule.
%
  x = zeros ( 2, order );
  w = zeros ( 1, order );

  o = 0;

  for s = 1 : suborder_num

    if ( suborder(s) == 1 )

      o = o + 1;
      x(1:2,o) = sub_xyz(1:2,s);
      w(o) = sub_w(s);

    elseif ( suborder(s) == 3 )

      for k = 1 : 3
        o = o + 1;
        x(1,o) = sub_xyz ( i4_wrap(k,  1,3), s );
        x(2,o) = sub_xyz ( i4_wrap(k+1,1,3), s );
        w(o) = sub_w(s) / 3.0;
      end

    elseif ( suborder(s) == 6 )

      for k = 1 : 3
        o = o + 1;
        x(1,o) = sub_xyz ( i4_wrap(k,  1,3), s );
        x(2,o) = sub_xyz ( i4_wrap(k+1,1,3), s );
        w(o) = sub_w(s) / 6.0;
      end

      for k = 1 : 3
        o = o + 1;
        x(1,o) = sub_xyz ( i4_wrap(k+1,1,3), s );
        x(2,o) = sub_xyz ( i4_wrap(k,  1,3), s );
        w(o) = sub_w(s) / 6.0;
      end

    else

      fprintf ( 1, '\n' );
      fprintf ( 1, 'LYNESS_RULE - Fatal error!\n' );
      fprintf ( 1, '  Illegal SUBORDER(%d) = %d\n', s, suborder(s) );
      error ( 'LYNESS_RULE - Fatal error!' );

    end

  end

  return
end


%
% testing the gaver-stehfest module
function y=testgs(L)
% L is the number of coefficients
% (examples: L=8, 10, 12, 14, 16, so on..)
sum=0.0;
for l=1:20
    t(l)=l * 0.1;
    calcv(l)=gavsteh('fun1',t(l),L);
    exactv(l)=t(l);
    sum=sum+(1- exactv/calcv)^2;
end
result1=[exactv' calcv' calcv'-exactv']
relerr=sqrt(sum)

%another example
sum=0.0;
for l=1:20
    t(l)=l * 0.1;
    calcv(l)=gavsteh('fun2',t(l),L);
    exactv(l)=sin(t(l));
    sum=sum+(1- exactv/calcv)^2;
end
result2=[exactv' calcv' calcv'-exactv']
relerr=sqrt(sum)


% Function to derive the Linear Prediction residual signal
%
% Octave compatible
%
% Description
%  Function to derive the Linear Prediction residual signal
%
% Inputs
%  x               : [samples] [Nx1] Input signal
%  L               : [samples] [1x1] window length (e.g., 25ms =>  25/1000*fs)
%  shift           : [samples] [1x1] window shift (e.g., 5ms => 5/1000*fs)
%  order           : [samples] [1x1] Order of Linear Prediction
%
% Outputs
%  res             : [samples] [Mx1] Linear Prediction residual
%  LPCcoeff        : [samples] [order+1xM] Linear Prediction coefficients
%
% Example
%  [res,LPCcoeff] = lpcresidual(x,L,shift,order);
%
% Copyright (c) 2011 University of Mons, FNRS
%
% License
%  This code is a part of the GLOAT toolbox with the following
%  licence:
%  This program is free software: you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation, either version 3 of the License, or
%  (at your option) any later version.
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Author
%  Thomas Drugman, TCTS Lab.
%
% $Id <info set by the versioning system> $

function [res,LPCcoeff] = lpcresidual(x,L,shift,order)

%% Initial settings
x=x(:);
shift = round(shift);
order = round(order);

start=1;
L = round(L);
stop=start+L;

% Allocate space
res=zeros(1,length(x));
LPCcoeff=zeros(order+1,round(length(x)/shift));

%% Do processing
n=1;
win = hanning(stop-start+1);
while stop<length(x)
     segment=x(start:stop);
     segment=segment.*win;

     A=lpc(segment,order);
     LPCcoeff(:,n)=A(:);

     inv=filter(A,1,segment);

     inv=inv*sqrt(sum(segment.^2)/sum(inv.^2));

     res(start:stop)=res(start:stop)+inv'; % Overlap and add

     % Increment
     start=start+shift;
     stop=stop+shift;
     n=n+1;
end

res=res/max(abs(res)); % Normalise amplitude


function vUnique=uniqueVec(v)
%%UNIQUEVEC This function takes an mXn matrix of n m-dimensional vectors
%           and returns only the vectors that are unique. This is currently
%           suited for a small to moderate  numbers of vectors, because a
%           brute-force comparison algorithm is used (rather than a
%           sorting-based approach that might lessen the number of
%           comparisons).
%
%INPUTS: v An mXn matrix of n vectors.
%
%OUTPUTS: vUnique An mXnumUnique matrix of the unique vectors in v.
%
%EXAMPLE:
% v=[1, 1, 1, 1, 1, 12;
%    1, 2, 1, 2, 2, 24;
%    1, 3, 1, 4, 3, 36]
% uniqueVec(v)
%
%February 2022 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(isempty(v))
    vUnique=v;
    return;
end

numRows=size(v,1);
numCols=size(v,2);

vUnique=zeros(numRows,numCols);

vUnique(:,1)=v(:,1);
numUnique=1;
for k=2:numCols
    isUnique=true;
    for kPrev=1:numUnique
        if(all(v(:,k)==vUnique(:,kPrev)))
            isUnique=false;
            break;
        end
    end

    if(isUnique)
        numUnique=numUnique+1;
        vUnique(:,numUnique)=v(:,k);
    end
end

%Size to fit
vUnique=vUnique(:,1:numUnique);

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 net = net_init_cifar_cnn(opts)
% CNN_MNIST_LENET Initialize a CNN similar for MNIST

rng('default');
rng(0) ;

f=1/100 ;
net.layers = {} ;
% Block 1
net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(5,5,3,32, 'single'), zeros(1, 32, 'single') }}, ...
                           'stride', 1, ...
                           'pad', 2) ;
net.layers{end+1} = struct('type', 'relu') ;

net.layers{end+1} = struct('type', 'pool','pool', 3, 'stride', 2,'pad', [1,1,1,1]) ;
% Block 2

net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(5,5,32,32, 'single'), zeros(1,32, 'single')}}, ...
                           'stride', 1, ...
                           'pad', 2) ;
net.layers{end+1} = struct('type', 'relu') ;

net.layers{end+1} = struct('type', 'pool','pool', 3, 'stride', 2,'pad', [1,1,1,1]) ;

% Block 3

net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(5,5,32,64, 'single'), zeros(1,64, 'single')}}, ...
                           'stride', 1, ...
                           'pad', 2) ;
net.layers{end+1} = struct('type', 'relu') ;

net.layers{end+1} = struct('type', 'pool','pool', 3, 'stride', 2,'pad', [1,1,1,1]) ;

% Block 4
net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(4,4,64,64, 'single'), zeros(1,64, 'single')}}, ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;

% Block 5

net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(1,1,64,10, 'single'), zeros(1, 10, 'single')}}, ...
                           'stride', 1, ...
                           'pad', 0) ;

net.layers{end+1} = struct('type', 'softmaxloss') ;


function r8lib_test121 ( )

%*****************************************************************************80
%
%% R8LIB_TEST121 tests R8VEC_FRAC.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 April 2009
%
%  Author:
%
%    John Burkardt
%
  n = 10;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8LIB_TEST121\n' );
  fprintf ( 1, '  R8VEC_FRAC: K-th smallest DVEC entry;\n' );

  seed = 123456789;

  [ a, seed ] = r8vec_uniform_01 ( n, seed );

  r8vec_print ( n, a, '  Array to search:' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Fractile  Value\n' );
  fprintf ( 1, '\n' );

  for k = 1 : floor ( n / 2 ) : n

    afrac = r8vec_frac ( n, a, k );

    fprintf ( 1, '  %8d  %14f\n', k, afrac );

  end

  return
end


function [ vO ] = ConvolutionOverlapSave( vS, vK, convShape )
% ----------------------------------------------------------------------------------------------- %
% [ vO ] = ConvolutionDft( vS, vK, convShape )
% Applying 1D Linear Convolution using the Overlap and Save approach. The
% function calculates the optimal DFT Window.
% Input:
%   - vS                -   Input 1D Convolution Signal.
%                           Structure: Vector (signalLength, 1).
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - vK                -   Input 1D Convolution Kernel.
%                           Structure: Vector (kernelLength, 1).
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - convShape         -   Convolution Shape.
%                           The shape of the convolution which the output
%                           convolution matrix should represent. The
%                           options should match MATLAB's conv() function
%                           - Full / Same / Valid.
%                           Structure: Scalar.
%                           Type: 'Single' / 'Double'.
%                           Range: {1, 2, 3}.
% Output:
%   - vS                -   Input 1D Convolution Output Vector.
%                           Structure: Vector (outputLength, 1).
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
% References:
%   1.  MATLAB's 'conv()' - https://www.mathworks.com/help/matlab/ref/conv.html.
%   2.  Overlap and Save Method (Wikipedia) - https://en.wikipedia.org/wiki/Overlap%E2%80%93save_method.
% Remarks:
%   1.  The signals must be columns signals.
%   2.  It is assumed that the input signal is not shorter than the kernel.
% TODO:
%   1.  C
%   Release Notes:
%   -   1.0.000     27/04/2020  Royi Avital
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

CONVOLUTION_SHAPE_FULL         = 1;
CONVOLUTION_SHAPE_SAME         = 2;
CONVOLUTION_SHAPE_VALID        = 3;

signalLength    = size(vS, 1); %<! K
kernelLength    = size(vK, 1); %<! M
dftLength       = CalcOptimalDftLength(signalLength, kernelLength); %<! N
convWinLength   = dftLength - kernelLength + 1; %<! L

paddSignalLength = ceil((signalLength + kernelLength - 1) / convWinLength) * dftLength;

vSS = [zeros(kernelLength - 1, 1); vS; zeros(paddSignalLength - kernelLength - 1 + signalLength, 1)];

numSteps    = ceil((signalLength + kernelLength - 1) / convWinLength);
vKD         = fft(vK, dftLength);
vO          = zeros(numSteps * convWinLength, 1);
vOO         = zeros(dftLength, 1);
idxPos      = 0;
for ii = 1:numSteps
    firstIdx = idxPos + 1;
    lastIdx = idxPos + dftLength;
    vOO(:) = ifft(fft(vSS(firstIdx:lastIdx)) .* vKD, 'symmetric');
    lastIdx = idxPos + convWinLength;
    vO(firstIdx:lastIdx) = vOO(kernelLength:dftLength);
    idxPos = idxPos + convWinLength;
end

switch(convShape)
    case(CONVOLUTION_SHAPE_FULL)
        idxFirst    = 1;
        idxLast     = signalLength + kernelLength - 1;
    case(CONVOLUTION_SHAPE_SAME)
        idxFirst    = 1 + floor(kernelLength / 2);
        idxLast     = idxFirst + signalLength - 1;
    case(CONVOLUTION_SHAPE_VALID)
        idxFirst    = kernelLength;
        idxLast     = (signalLength + kernelLength - 1) - kernelLength + 1;
end

vO          = vO(idxFirst:idxLast);

end

function [ dftLength ] = CalcOptimalDftLength( signelLength, kernelLength )

oConvOs = @(dftLength) (dftLength * log2(dftLength) + dftLength) / (dftLength - kernelLength + 1);

outputLength = signelLength + kernelLength;

firstPow2   = ceil(log2(kernelLength));
lastPow2    = ceil(log2(outputLength));

pow2 = firstPow2;
optNumOps = oConvOs(2 ^ pow2);

for pow2 = (firstPow2 + 1):lastPow2
    currNumOps = oConvOs(2 ^ pow2);
    if(currNumOps > optNumOps)
        break;
    end
    optNumOps = currNumOps;
end

dftLength = 2 ^ pow2;

end


function [Y,I] = minnz(X)
  % MINNZ  find minimum nonzero entry in columns of X
  %
  % [Y,I] = minnz(X)
  %
  % Inputs:
  %   X  m by n sparse matrix
  % Outputs
  %   Y  n list of minimum non zero entries in each column of X
  %   I  n list of row indices to minimum non-zero entries in each column of X
  %
  % See also: min, max, maxnz
  %
  %

  % rebuild using 1/element
  [XI,XJ,XV] = find(X);
  X_i = sparse(XI,XJ,XV.^-1,size(X,1),size(X,2));
  [infX_i,infI_i] = max(X==inf);
  [maxX_i,maxI_i] = max(X_i);
  maxX_i(maxX_i==0) = inf;
  maxX_i(infX_i) = 0;
  maxI_i(infX_i) = infI_i(infX_i);
  [minX,minI] = min(X);
  minX(minX==0) = inf;
  Y = [maxX_i.^-1;minX];
  [Y,J] = min(Y);
  I = [maxI_i;minI];
  I = I(sub2ind(size(I),J,1:size(I,2)));

end


%  Figure 7.53      Feedback Control of Dynamic Systems, 5e
%                        Franklin, Powell, Emami
%
% script to generate Fig. 7.53
%
clf;
dp=[1 1 0];
np=[1];
nc=conv([1 1.001],[8.32 0.8]);
dc=conv([1 4.08],[1 0.0196]);
num=conv(np,nc);
den=conv(dp,dc);
dcl=[0 0 num]+den; % closed-loop denominator
t=0:.1:5;
y=step(num,dcl,t);
plot(t,y);
xlabel('Time (sec)');
ylabel('y(t)');
nicegrid;
title('Fig.7.53: Step response for lag compensation design')


%  udc Undetermined coefficients solution algorithm for DSGE models.
%  The procedure can find all possible solutions for a constant-parameter
%  DSGE model or a regime-switching DSGE model with diagonal transition
%  matrix.
%
%  ::
%
%    [Tz_pb,eigvals,retcode]=udc(A,B,C,Q,T0,TolFun,maxiter)
%
%  Args:
%
%     - **A** [n x n] : Coefficient matrix on lead variables
%
%      - **B** [n x n] : Coefficient matrix on current variables
%
%      - **C** [n x n] : Coefficient matrix on lagged variables
%
%      - **slvOpts.allSols** [true|{false}] : flag for finding all solutions
%
%      - **slvOpts.msvOnly** [{true}|false] : return only MSV solutions
%
%      - **slvOpts.debug** [true|{false}] : slvOpts.debug or not
%
%  Returns:
%     :
%
%      - **Tz_pb** [n x n x h x k array] : Solution set (k solutions)
%
%      - **eigvals** [empty] : Eigenvalues (Not computed)
%
%      - **retcode** [numeric] : 0 if there is no problem
%
%  See also :  groebner
%


%QUADRC Trainable quadratic classifier
%
%   W = QUADRC(A,R,S)
%   W = A*QUADRC([],R,S)
%   W = A*QUADRC(R,S)
%
% INPUT
% 	A 		Dataset
%   R,S		0 <= R,S <= 1, regularization parameters (default: R = 0, S = 0)
%
% OUTPUT
% 	W     Quadratic Discriminant Classifier mapping
%
% DESCRIPTION
% Computation of the quadratic classifier between the classes of the dataset
% A based on different class covariances. R and S are regularization
% parameters used for finding the covariance matrix as
%
%		G = (1-R-S)*G + R*diag(diag(G)) + S*mean(diag(G))*eye(size(G,1))
%
% NOTE
% This routine differs from QDC; instead of using the densities, it is based
% on the class covariances. The multi-class problem is solved by multiple
% two-class quadratic discriminants. It is, thereby, a quadratic equivalent
% of FISHERC.
%
% SEE ALSO (PRTools Guide)
% MAPPINGS, DATASETS, FISHERC, NMC, NMSC, LDC, UDC, QDC

% Copyright: R.P.W. Duin, duin@ph.tn.tudelft.nl
% Faculty of Applied Sciences, Delft University of Technology
% P.O. Box 5046, 2600 GA Delft, The Netherlands

% $Id: quadrc.m,v 1.5 2010/02/08 15:29:48 duin Exp $

function w = quadrc(varargin)

  mapname = 'Quadr';
  argin = shiftargin(varargin,'scalar');
  argin = setdefaults(argin,[],0,0);

  if mapping_task(argin,'definition')

   w = define_mapping(argin,'untrained',mapname);

	elseif mapping_task(argin,'training')			% Train a mapping.

    [a,arg2,s] = deal(argin{:});
    [m,k,c] = getsize(a);

		islabtype(a,'crisp');
		isvaldfile(a,2,2); % at least 2 objects per class, 2 classes
		a = testdatasize(a,'features');
		a = setprior(a,getprior(a));
		r = arg2;

		if (min(classsizes(a)) < 2)
			error('Classes should contain more than one vector.')
		end

		if (c == 2)

			% 2-class case: calculate quadratic discriminant parameters.

			%p = getprior(a); pa = p(1); pb = p(2);

			JA = findnlab(a,1); JB = findnlab(a,2);

			ma = mean(a(JA,:)); mb = mean(a(JB,:));

			GA = covm(a(JA,:)); GB = covm(a(JB,:));
			GA = (1-r-s) * GA + r * diag(diag(GA)) + ...
															s * mean(diag(GA))*eye(size(GA,1));
			GB = (1-r-s) * GB + r * diag(diag(GB)) + ...
															s*mean(diag(GB))*eye(size(GB,1));
			DGA = det(GA); DGB = det(GB);

			GA = prinv(GA);
			GB = prinv(GB);

			par1 = 2*ma*GA-2*mb*GB; par2 = GB - GA;

			% If either covariance matrix is nearly singular, substitute FISHERC.
			% Otherwise construct the mapping.

			if (DGA <= 0) | (DGB <= 0)
				prwarning(1,'Covariance matrix nearly singular, regularization needed; using FISHERC instead')
				w = fisherc(a);
			else
				%par0 = (mb*GB*mb'-ma*GA*ma') + 2*log(pa/pb) + log(DGB) -log(DGA);
				par0 = (mb*GB*mb'-ma*GA*ma') + log(DGB) -log(DGA);
				w = prmapping(mfilename,'trained',{par0,par1',par2},getlablist(a),k,2);
				w = cnormc(w,a);
				w = setname(w,mapname);
				w = setcost(w,a);
			end

		else

			% For C > 2 classes, recursively call this function, using MCLASSC.

			pars = feval(mfilename,[],r,s);
			w = mclassc(a,pars);

		end

	else % Evaluation

		% Second argument is a trained mapping: test. Note that we can only
		% have a 2-class case here. W's output will be [D, -D], as the distance
		% of a sample to a class is the negative distance to the other class.

    [a,v] = deal(argin{1:2});
    [m,k] = size(a);
		pars = getdata(v);
		d = +sum((a*pars{3}).*a,2) + a*pars{2} + ones(m,1)*pars{1};
		w = setdat(a,[d, -d],v);

	end

return

function p = logdet(cova,covb)
%
% Numerically feasible computation of log(det(cova)/det(covb)))
% (seems not to help)

k = size(cova,1);

sa = mean(diag(cova));
sb = mean(diag(covb));

deta = det(cova./sa)
detb = det(covb./sb)

p = k*log(sa) - k*log(sb) + log(deta) - log(detb);


function [pca_dim, k_var, U, S, V] = PCA_MP_fit(M, pvar, flag_plot)
% assume M is already preprocessed
if ~exist('flag_plot', 'var')
    flag_plot = 1;
end
if ~exist('pvar', 'var')
    pvar = 0.9;
end

[U, S, V] = svd(M, 'econ');
s = diag(S).^2;

ep = 1e-4;
splot = s(abs(s)>ep);
ns = length(splot);

gap = 1; % only for the moment estimator
pout = 0.2;
niter = 10;
nx_target = 3.2;
[lb_e, sigma_e, tfconv] = estimate_MP2(splot, pout, gap, niter, nx_target, 'L2');
lb1_e = (1 + sqrt(lb_e))^2 * sigma_e^2;
ns_bulk_e = sum(splot < lb1_e);
pca_dim = sum(splot > lb1_e);
s_out = splot(splot > lb1_e);
if isempty(s_out)
    s_out = max(splot);
    pca_dim = 1;
    k_var = 1;
else
    s_out = sort(s_out, 'descend');
    var_sum = cumsum(s_out);
    k_var = find(var_sum >= pvar * var_sum(end), 1);
end

if flag_plot ==1
    figure;
    set(gcf,'position', [88, 571, 656, 534]);
    dbin = adaptBinWidth2(splot, 4);
    nbins_all = round(max(splot)/dbin);
    ht = histogram(splot, nbins_all, 'Normalization', 'pdf');
    ns_plot = ns;
    % histogram(splot, 40000);
    % h=histogram(splot(splot< 2*lb1), 80, 'Normalization', 'pdf');
    % xlim([0,15])
    hold on;
    x0 = linspace(0, 2*lb1_e, 1000);
    y0 = MPdistr(x0, lb_e, sigma_e);
    y0 = y0 / ns_plot * ns_bulk_e;
    plot(x0, y0, 'r')
    xlim([0, 5*lb1_e])
    hold off;
    title(['Estimated signal dimension = ', num2str(pca_dim)])
    length(splot)
    % display('Dim  lb  sigma  flag_conv')
    pca_dim, lb_e, sigma_e, tfconv

    figure;
    set(gcf,'position', [88, 571, 656, 534]);
    plot(var_sum / var_sum(end),'bo-');
    title('Explained variance');
    legend([num2str(pvar*100),'% = ', num2str(k_var)])
end

end


function z=mergeSortedArrays(x,y)
%MERGESORTEDARRAYS Given two arrays that are each sorted in ascending
%                  order, merge them into one large array that is in
%                  ascending order.
%
%INPUTS: x An xDimX1 or 1XxDim array that has been sorted in ascending
%          order.
%        y A yDimX1 or 1XyDim array that has been sorted in ascending
%          order.
%
%OUTPUTS: z An (xDim+yDim)X1 array containing all of the elements of x and
%           y, in ascending order.
%
%The algorthm is taken from Chapter 5.2.4 of [1].
%
%REFERENCES:
%[1] D. Knuth, The Art of Computer Programming: Sorting and Searching, 2nd
%    ed. Reading, MA: Addison-Wesley, 1998, vol. 3.
%
%December 2014 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

m=length(x);
n=length(y);
zLen=n+m;
z=zeros(zLen,1);

%Initialize
i=1;
j=1;
k=1;

%Find smaller
while(1)
    if(x(i)<=y(j))
        z(k)=x(i);
        k=k+1;
        i=i+1;
        if(i<=m)
            continue;
        else
            z(k:zLen)=y(j:n);
            break;
        end
    else
        z(k)=y(j);
        k=k+1;
        j=j+1;

        if(j<=n)
            continue;
        else
           z(k:zLen)=x(i:m);
           break;
        end
    end
end
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 J=JacobPolarCoordTurn2D(T,x,turnType,discPoint,tauTurn,tauLinAccel)
%%JACOBCOORDTURN2D Evaluate the Jacobian (matrix of partial derivatives
%              with respect to the state elements) of a discrete-time state
%              transition function for a two-dimensional coordinated turn
%              model where the velocity is specified in terms of a heading
%              and a speed. The turn rate can be specified in terms of a
%              turn rate in radians per second, or in terms of a
%              transversal acceleration. Additionally, a linear
%              acceleration can be given. The turn rate and linear
%              acceleration can optionally have time constants associated
%              with them, like in the Singer model, modelling a tendancy to
%              eventually want to return to non-accelerating, straight-line
%              motion. This Jacobian is associated with the continuous-time
%              model fTransPolarCoordTurn2D.
%
%INPUTS: T The time-duration of the propagation interval in seconds.
%        x The  target state for 2D motion where the velocity is given in
%          terms of heading and speed components. If there is no linear
%          acceleration (acceleration along the direction of motion),
%          then x can either be x=[x;y;h;v;omega], where h is the heading
%          in terms of radians counterclockwise from the x-axis, v is the
%          speed, and omega is the turn rate (the derivative of h with
%          respect to time) or  x=[x;y;h;v;at] where at is the
%          transversal acceleration, which is orthogonal to the velocity
%          and is defined such that positive values of at map to positive
%          values of omega. If there is a linear acceleration, then the
%          target state is either x=[x;y;h;v;omega;al] where omega is the
%          turn rate and al is the linear acceleration or the target
%          state is x=[x;y;h;v;at;al] if the turn is expressed in terms
%          of a transversal acceleration. The dimensionality of the state
%          is used to determine whether a linear acceleration component
%          is present. The linear acceleration component changes the
%          speed. That means that it is the derivative of the speed.
% turnType A string specifying whether the turn is given in terms of a
%          turn rate in radians per second or a transversal acceleration
%          in m/s^2. Possible values are
%          'TurnRate'   The turn is specified in terms of a turn rate
%                       (The default if this parameter is omitted).
%          'TransAccel' The turn is specified in terms of a transversal
%                       acceleration.
% discPoint This optional parameter specified what value of the turn rate
%           is used for the discretized state prediction. The thre
%           possible values were suggested in Li's paper cited
%           below. Possible values are
%           0 (The default if omitted) use omega=x(5), or the equivalent
%             value when specifying the turn rate using a transverse
%             acceleration, from the non-predicted target state for
%             building the state transition matrix. \omega_k
%           1 Use the average value of the predicted omega (or the average
%             value of the transverse acceleration) over the interval T
%             for building the state transition matrix. \bar{\omega}
%           2 Use the approximate average value of the predicted omega
%             over the interval T for building the state transition
%             matrix. \bar{\omega} This is the suggestion of using half
%             the prior and prediction, as was given in Li's paper. When
%             given a transverse acceleration instead of a turn rate, half
%             of the prior and predicted accelerations is used.
%           3 Use the forward-predicted omega (or transverse acceleration)
%             for building the state transition matrix. \omega_{k+1}
%   tauTurn The correlation time constant for the turn rate in seconds.
%           tau must be positive but does not have to be finite. If this
%           parameter is omitted, then tauTurn is set to infinity.
% tauLinAccel The correlation time constant for the linear acceleration (if
%            present) in seconds. This parameter is not needed if there is
%            no linear acceleration. If a linear acceleration is present
%            and this parameter is omitted, then tauLinAccel is set to
%            infinity.
%
%OUTPUTS: J The 5X5 or 6X6 Jacobian matrix of the function
%           fTransPolarCoordTurn2D, where the partial derivatives are
%           ordered [df/dx(1), df/dx(2),...,df/dx(xDim)]. That is, column i
%           consists of partial derivatives with respect to element i of
%           the x vector.
%
%More information on the discrete-time turning model is given in the
%comments to the function fTransPolarCoordTurn2D.
%
%April 2015 David Karnick, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

%The time constant for the linear acceleration.
if(nargin<6||isempty(tauLinAccel))
    tauLinAccel=Inf;
end

%The time constant for the turn.
if(nargin<5||isempty(tauTurn))
   tauTurn=Inf;
end

if(nargin<4||isempty(discPoint))
    discPoint=0;
end

if(nargin<3||isempty(turnType))
    turnType='TurnRate';
end

xDim=size(x,1);

beta=exp(-T/tauTurn);
switch(discPoint)
    case 0%Use the prior value of at/omega for the linearization.
        turnVal=x(5);
    case 1
        %Use the average value of at.omega over the prediction
        %interval for the linearization.
        turnVal0=x(5);
        turnVal=(tauTurn-beta*tauTurn+T*turnVal0)/T;

        %Assume tau=Inf or T=0 was used, in which case the
        %asymptotic average value of at/omega should be used.
        turnVal(~isfinite(tauTurn)||~isfinite(turnVal))=turnVal0(~isfinite(tauTurn)||~isfinite(turnVal));
    case 2%Use the simple mean of at/omega for the linearization.
        turnVal=(beta+1)*x(5)/T;
    case 3%Use the predicted value of at/omega for the linearization.
        turnVal=beta*x(5);
    otherwise
        error('Invalid value entered for discPoint');
end

v=x(4);%The speed

switch(turnType)
    case 'TransAccel'%The turn is expressed in terms of a transverse
        %acceleration.
        omega=turnVal./v;
        omega(~isfinite(omega))=0;%Deal with zero velocity
    case 'TurnRate'%The turn is expressed in terms of a turn rate.
        omega=turnVal;
    otherwise
        error('Unknown turn type specified.');
end
%We now have the omega term for the turn.

theta=x(3);%The heading (counterclockwise from the x axis).

sinHead=sin(theta);
cosHead=cos(theta);

sinVal=sin(omega*T);
cosVal=cos(omega*T);

sinRat=sinVal./omega;
sinRat(~isfinite(sinRat))=T;%The limit as omega goes to zero.
cosRat=(1-cosVal)/omega;
cosRat(~isfinite(cosRat))=0;%The limit as omega goes to zero.

switch(turnType)
    case 'TransAccel'
        at=x(5);
        J=[1,0,-v*(sinHead*sinRat+cosHead*cosRat),2*(cosHead*sinRat-sinHead*cosRat)-T*(cosHead*cosVal-sinHead*sinVal),cosHead*(T*cosVal/omega-sinRat/omega)-sinHead*(T*sinRat-cosRat/omega);
           0,1,v*(cosHead*sinRat-sinHead*cosRat), 2*(sinHead*sinRat+cosHead*cosRat)-T*(sinHead*cosVal+cosHead*sinVal),sinHead*(T*cosVal/omega-sinRat/omega)+cosHead*(T*sinRat-cosRat/omega);
           0,0,1,                                 -T*at/v^2,                                                          T/v;
           0,0,0,                                 1,                                                                  0;
           0,0,0,                                 0,                                                                  beta];
    case 'TurnRate'
        J=[1,0,-v*(sinHead*sinRat+cosHead*cosRat),cosHead*sinRat-sinHead*cosRat,v*(cosHead*(T*cosVal/omega-sinRat/omega)-sinHead*(T*sinRat-cosRat/omega));
           0,1,v*(cosHead*sinRat-sinHead*cosRat), sinHead*sinRat+cosHead*cosRat,v*(sinHead*(T*cosVal/omega-sinRat/omega)+cosHead*(T*sinRat-cosRat/omega));
           0,0,1,                                 0,                            T;
           0,0,0,                                 1,                            0;
           0,0,0,                                 0,                            beta];
end
if xDim==6
    betaLinAccel=exp(-T/tauLinAccel);
    J(4,6)=T;
    J(6,6)=betaLinAccel;
end

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 q = project2FR_ref(q,qCS,q_ref)
% projects quaternions to a fundamental region
%
% Syntax
%   project2FundamentalRegion(q,CS,q_ref) % to FR around reference rotation
%
% Input
%  q        - @quaternion
%  CS1, CS2 - crystal @symmetry
%  q_ref    - reference @quaternion single or size(q) == size(q_ref)
%
% Output
%  q     - @quaternion
%  omega - rotational angle to reference quaternion
%

qCS = qCS.rot;

s = size(q);
q.a = q.a(:); q.b = q.b(:); q.c = q.c(:); q.d = q.d(:);
try q.i = q.i(:); end %#ok<TRYNC>

% compute distance to reference orientation
if ~isempty(q_ref)
  q_ref.a = q_ref.a(:); q_ref.b = q_ref.b(:);
  q_ref.c = q_ref.c(:); q_ref.d = q_ref.d(:);

  co2 = abs(quat_dot(q,q_ref));

else

  co2 = abs(q.a);

end

% may be we can skip something
minAngle = reshape(abs(qCS.angle),[],1);
minAngle = min([inf;minAngle(minAngle > 1e-3)]);
notInside = co2 < cos(minAngle/4);

% maybe we can skip everything
if any(notInside) && length(qCS) > 1

  % restrict to quaternion which are not yet it FR
  if length(q) == numel(notInside)
    q_sub = q.subSet(notInside);
  else
    q_sub = q;
  end

  % compute all distances to the fundamental regions
  if ~isempty(q_ref)

    % if q_ref was a list of reference rotations
    if length(q_ref) == numel(notInside)
      omegaSym  = abs(quat_dot_outer(inv(q_ref.subSet(notInside)).*q_sub,qCS));
    else
      omegaSym  = abs(quat_dot_outer(inv(q_ref).*q_sub,qCS));
    end

  else
    omegaSym  = abs(quat_dot_outer(q_sub,qCS));
  end

  % find symmetry elements with minimum distance
  [~,nx] = max(omegaSym,[],2);

  % project to fundamental region
  qn = times(q_sub, reshape(inv(qCS.subSet(nx)),size(q_sub)),0);

  % replace projected quaternions
  q.a(notInside) = qn.a;
  q.b(notInside) = qn.b;
  q.c(notInside) = qn.c;
  q.d(notInside) = qn.d;
end

% ensure correct sign
if isempty(q_ref)
  changeSign = q.a < 0;
else
  changeSign = q.a .* q_ref.a + q.b .* q_ref.b + q.c .* q_ref.c + q.d .* q_ref.d < 0;
end
q.a(changeSign) = -q.a(changeSign);
q.b(changeSign) = -q.b(changeSign);
q.c(changeSign) = -q.c(changeSign);
q.d(changeSign) = -q.d(changeSign);

q = reshape(q,s);

% some testing code
% cs = crystalSymmetry('432')
% q = quaternion.rand(100,1);
% q_ref = quaternion.rand(100,1);
% q_proj = project2FR_ref(q,quaternion(cs),q_ref);
% hist(angle(q_proj,q_ref)/degree)


%%*******************************************************
%% fapproblem:
%%
%% (primal prob.) min  Tr C*X
%%                s.t. diag(X) = e
%%                    -Eij * X = 2/(k-1)  if (i,j) in  U
%%                    -Eij * X <= 2/(k-1) if (i,j) in GU
%%  where Eij = ei*ej' + ej*ei'
%%  b = [e; 2/(k-1)*ones(mU+mGU,1)]
%%  C = (1/2)*Diag(We) - (k-1)/(2k) *L(G)
%%-------------------------------------------------------
%% [blk,Avec,C,b] = fapproblme(fname);
%%
%% SDPT3: version 3.0
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last modified: 2 Feb 01
%%*******************************************************

 function [blk,Avec,C,b,kparm] = fapread(fname)

%%
%% read fap data
%%
   if exist(fname)
      fid = fopen(fname,'r');
   elseif exist([fname,'.dat']);
      fid = fopen([fname,'.dat'],'r');
   else
      fprintf('** Problem not found. \n');
      blk = []; Avec = []; C = []; b = []; kparm = [];
      return;
   end
   [tmpr,count] = fscanf(fid,'%c');
   datavec = sscanf(tmpr,'%f'); clear tmpr;
   n = datavec(1);
   numedges = datavec(2);
   kparm = datavec(3);
   datavec = datavec(4:length(datavec));
   len = length(datavec);
   if (len ~= 3*numedges)
      error(' fapread: numedges and data do not match.');
   end
   I = datavec(1:3:len);
   J = datavec(2:3:len);
   w = datavec(3:3:len);

   idxU = find(w==1000);
   IU = I(idxU); JU = J(idxU); wU = w(idxU);
   U = spconvert([IU JU wU; n n 0]);
   U = U + U';

   idx2 = find(w~=1000);
   I2 = I(idx2); J2 = J(idx2); w2 = w(idx2);
   GU = spconvert([I2 J2 w2; n n 0]);
   GU = GU + GU';

   fclose(fid);
%%
%% blk, Avec, C, b
%%
    n = length(U);
    mU = nnz(triu(U,1));
    mGU = nnz(triu(GU,1));
    m = mGU + mU + n;

    b = [ones(n,1); (2/(kparm-1))*ones(mU+mGU,1)];
    LG = diag(GU*ones(n,1))-GU;
    C{1,1} = 0.5*(diag(GU*ones(n,1))) - ((kparm-1)/(2*kparm))*LG;
    C{2,1} = zeros(mGU,1);

    blk{1,1} = 's';  blk{1,2} = n;
    blk{2,1} = 'l';  blk{2,2} = mGU;
%%
%%
%%
    r2 = sqrt(2);
    I = zeros(m,1); J = zeros(m,1); w = zeros(m,1);
    cnt = 0;
    e = [1:n]';
    I(1:n) = e.*(e+1)/2;
    J(1:n) = e;
    w = ones(n,1);
    cnt = cnt+n;
    for i = 1:n
        idx = find(U(i,i+1:n));
        idx = idx+i;      %% adjust index.
        len = length(idx);
        I(cnt+[1:len]) = i + idx.*(idx-1)/2;
        J(cnt+[1:len]) = cnt+[1:len]';
        w(cnt+[1:len]) = -r2*ones(len,1);
        cnt = cnt + len;
    end
    for i = 1:n
        idx = find(GU(i,i+1:n));
        idx = idx+i;      %% adjust index.
        len = length(idx);
        I(cnt+[1:len]) = i + idx.*(idx-1)/2;
        J(cnt+[1:len]) = cnt+[1:len]';
        w(cnt+[1:len]) = -r2*ones(len,1);
        cnt = cnt + len;
    end
    Avec{1,1} = spconvert([I,J,w; n*(n+1)/2, m, 0]);
%%
    I = [1:mGU]'; J = [m-mGU+1:m]';  w = ones(mGU,1);
    Avec{2,1} = spconvert([I, J, w; mGU, m, 0]);
%%
%%*******************************************************


%--------------------------------------------------------------------------
%   [vpp] = dbm2vpp(dbm,R)
%--------------------------------------------------------------------------
%   功能:
%   dbm 单位转化为电压值
%--------------------------------------------------------------------------
%   输入:
%           dbm                 signal peak to peak volt
%           R                   阻抗匹配(默认为50Ω)
%   输出:
%           vpp
%--------------------------------------------------------------------------
%   例子:
%   dBm2vpp(0)
%   ans = 0.6325
%   dbm2vpp(1,50)
%   ans = 0.7096
%--------------------------------------------------------------------------
function vpp = dbm2vpp(dbm,R)
if nargin==1
    R=50;
end
vpp = 2*10.^((dbm-30+10*log10(2.*R))./20);
end


function [ Y ] = TMAV( X, h )
% TMED  - The fuzzy filter with Triangular function with MEDian center
% x     - input (noisy image)
% y     - output (de-noised image)
% F     - window function, weighting function

if nargin < 2
    h=3;    % local search window size: h=3; h=5; h=7; h=9; h=11;
    f=1;    % padding value for window: f=1; f=2; f=3; f=4; f=5;
else
    f=(h-1)/2;    % padding value for window: f=1; f=2; f=3; f=4; f=5;
end
F = zeros(h*h,1);
Y  = zeros(size(X));

X = double(padarray(X,[f f],'symmetric'));
[m n ~] = size(X);

for i=1+f:1:m-f
   for j=1+f:1:n-f
       x=reshape(X(i-f:i+f, j-f:j+f),[],1);
       xmax = max(x);
       xmin = min(x);
       xmav = mean(x);
       xmv = max(xmax-xmav, xmav-xmin);

       F(:,:) = 0;
       if xmv==0
           F(:,:) = 1;
       else
           F = (abs(x-xmav)/xmv);
       end

       Y(i-f,j-f) = sum(sum(F.*x))/sum(sum(F));
       clear xmax xmin xmed xmm;

   end
end
end


function [features, background] = extractBlackBlobs(im)
% EXTRACTIMAGEBLOBS  Find the dark blobs in the images

f = hessiandet(im) ;
ok = f(3,:) > 0.0006 ;
idx = sub2ind(size(im), round(f(2,ok)), round(f(1,ok))) ;
features = false([size(im,1) size(im,2)]) ;
features(idx) = true ;
background = ~imdilate(features, strel('disk', 5, 0)) ;

b = 5 ;
features([1:b, end-b:end],:) = 0 ;
features(:,[1:b, end-b:end]) = 0 ;
background([1:b, end-b:end],:) = 0 ;
background(:,[1:b, end-b:end]) = 0 ;

function f = hessiandet(im)
% HESSIANDET  Basic Hessian detector
%   F = HESSIANDET(IM) runs a basic implementation of the Hessian
%   detector on the gray-scale image IM.

ims = imsmooth(im,2.5) ;

d2 = [1 -2 1];
d = [-1 0 1]/2 ;
im11 = conv2(1,d2,ims,'same') ;
im22 = conv2(d2,1,ims,'same') ;
im12 = conv2(d,d,ims,'same') ;
score = im11.*im22 - im12.*im12 ;

points = (islocalmax(score,1) .* islocalmax(score,2)) + ...
         (islocalmin(score,1) .* islocalmin(score,2)) ;
points = points .* (abs(score) > 0.0006) ;

scores = score(find(points)) ;
[i,j] = find(points) ;
f = [j(:),i(:),scores(:)]' ;

if 0
  clf ;subplot(1,2,1); imagesc(im) ; hold on ; colormap gray ;
  plot(f(1,:),f(2,:),'r.') ;
  subplot(1,2,2) ; imagesc(abs(score).^.25) ;
  keyboard
end

function m = islocalmax(x,dim)
m  = (circshift(x,1,dim) < x) & (circshift(x,-1,dim) < x) ;

function m = islocalmin(x,dim)
m = (circshift(x,1,dim) > x) & (circshift(x,-1,dim) > x) ;


function cdf = quasigeometric_cdf ( x, a, b )

%*****************************************************************************80
%
%% QUASIGEOMETRIC_CDF evaluates the Quasigeometric CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 January 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer X, the number of trials.
%
%    Input, real A, the probability of 0 successes.
%    0.0 <= A <= 1.0.
%
%    Input, real B, the depreciation constant.
%    0.0 <= B < 1.0.
%
%    Output, real CDF, the value of the CDF.
%
  if ( x < 0 )
    cdf = 0.0;
  elseif ( x == 0 )
    cdf = a;
  elseif ( b == 0.0 )
    cdf = 1.0;
  else
    cdf = a + ( 1.0 - a ) * ( 1.0 - b^x );
  end

  return
end


function desc = calYcbcr(rgb_im, seg, numRegion)
% y cb cr
    im = rgb2ycbcr(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 = im(:,:,ch);
            feature = feature(ind{iReg});
            desc(iReg, ch) = sum(feature) / sum(ind{iReg});
        end
    end

end


function rouderFigure4(nrSets,options)
% Runs the simulations of Rouder et al. 2009 in Figure 4.
% This basically shows the ability to extract Main and Interaction effects
% in a 2-way anova.
if nargin<2
    options = bf.options;
    if nargin <1
        nrSets = 10;
    end
end
rouder2012 = load('rouder2012Data.mat');
effects = [0   0   0
    0.2 0   0
    0.5 0   0
    1   0   0
    0.2 0.4 0
    0.5 0.4 0
    1   0.4 0
    0.2 0.2   0
    0.5 0.5   0
    1   1     0
    0.4 0.4 0.2
    0.4 0.4 0.5];

nrEffects = size(effects,1);
% Create a design matrix from the data, only to simulate fake rt's with
% different effects
X= classreg.regr.modelutils.designmatrix(rouder2012.data,'intercept',false,'responsevar','rt','DummyVarCoding','effects','PredictorVars',{'ori','freq'},'model','interactions');
bfOri = nan(nrSets,nrEffects);
bfFreq= nan(nrSets,nrEffects);
bfInteraction= nan(nrSets,nrEffects);
parfor (j=1:nrEffects,options.nrWorkers)
    rt = X *effects(j,:)';
    for i=1:nrSets
        tmp  =rouder2012.data; %#ok<PFBNS>
        tmp.rt =rt + randn([size(X,1) 1]);
        bfFull = bf.anova(tmp,'rt~ori*freq');
        bfMain = bf.anova(tmp,'rt~ori+freq');
        bfOri(i,j)  = bf.anova(tmp,'rt~ori');
        bfFreq(i,j)  = bf.anova(tmp,'rt~freq');
        bfInteraction(i,j) = bfFull/bfMain;
    end
end

%%
figure(4);clf
effectIx = {1:4,5:7,8:10,11:12};
for i=1:4
    thisPlotEffects  = effectIx{i};
    subplot(1,4,i)
    if i==4
        x = effects(thisPlotEffects,3);
    else
        x = effects(thisPlotEffects,1);
    end
    [meOri]= median(bfOri(:,thisPlotEffects));
    hOri=  plot(x,meOri,'o-','MarkerSize',10,'Color','k','MarkerFaceColor','k');
    hold on
    meFreq = median(bfFreq(:,thisPlotEffects));
    hFreq=  plot(x,meFreq,'o-','MarkerSize',10,'Color','k','MarkerFaceColor',[0.7 0.5 0]);
    meInt = median(bfInteraction(:,thisPlotEffects));

    hInt=  plot(x,meInt,'o-','MarkerSize',10,'Color','k','MarkerFaceColor','w');
    if i==1
        legend([hOri, hFreq,hInt],{'Orientation','Frequency','Interaction'},'Location','NorthWest');
    end
    set(gca,'YScale','Log','YLim',[0.1 1e6],'YTick',[0.1 1 10 100 1000 1e6])
    ylabel 'Median Bayes Factor for Effect'
end
end


function V = coeffs2vals(C)
%VAL2COEFFS   Convert tensor of Chebyshev coefficients to values.
%   V = COEFFS2VALS(C) converts a tensor C of bivariate Chebyshev coefficients
%   to a matrix of samples V corresponding to values of
%                   \sum_i \sum_j C(i,j) T_{i-1}(y) T_{j-1}(x)
%   at a tensor Chebyshev grid of size size(C).
%
% See also chebfun3/vals2coeffs.

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

[m, n, p] = size(C);

%% Step 1:
% Mode-1 unfolding of F to get a matrix of size m x n*p:
C1 = chebfun3.unfold(C, 1);

% Apply 1D "vals2coeffs" in the X direction i.e., the 1st dimension of vals1:
C1 = chebtech2.coeffs2vals(C1);

% Tensorize vals1 back to its original m x n x p size:
C1 = chebfun3.fold(C1, [m, n, p], 1, [2 3]);
% This is simply vals1 = reshape(V1, m, n, p);

%% Step 2:
% Mode-2 unfolding of (the tensorized) vals1 to get a matrix of size m x n*p:
C2 = chebfun3.unfold(C1, 2);

% Apply 1D "vals2coeffs" in the Y direction, i.e. to the 1st direction of
% vals2:
C2 = chebtech2.coeffs2vals(C2);

% Tensorize vals2 back to its original m x n x p size:
C2 = chebfun3.fold(C2, [m, n, p], 2, [1 3]);

%% Step 3:
% Mode-3 unfolding of (the tensorized) vals2 to get a matrix of size p x m*n:
C3 = chebfun3.unfold(C2, 3);

% Now, vals2coeffs is applied in the Z direction.
C3 = chebtech2.coeffs2vals(C3);

% Reshape vals3 back to the original m x n x p size:
V = chebfun3.fold(C3, [m, n, p], 3, [1 2]);

end


function Plots1D(Params, Model, YTM, ShortRates)
% =========================================================================
% Plots yield curve for estimated model. All rates are annualy compounded.
%
% INPUT:
%
%         Params - Estimated parameters
%          Model - 'NS' for Nelson-Siegel model
%                  'Svensson' for Svensson model
%            YTM -
%         Settle -
% USES:
%        NScurve
%
% Kamil Kladivko
% email: kladivko@gmail.com
% December 2010
% Cite as:
% Kladivko Kamil (2010). The Czech Treasury Yield Curve from 1999 to the Present,
% Czech Journal of Economics and Finance, 60(4): 307-335
% =========================================================================

% Figure 1 (Spot, FWD and Par rates)
FontSize = 14;
Mat = 0:0.1:ceil(max(YTM.TimeFraction));
%Mat = 0:0.1:40; % 27.1.2010
[ZeroRates InstFwdRates] = NScurve(Params, Mat, Model);
ZeroRates = exp(ZeroRates) - 1; % Annual compounding
InstFwdRates = exp(InstFwdRates) - 1; % Annual compounding
% Par Rates
MatForPar = 1:1:ceil(max(YTM.TimeFraction));
[ZeroForParRates junk] = NScurve(Params, MatForPar, Model);
ZeroForParRates = exp(ZeroForParRates) - 1;  % Annual compounding
ParRates = zero2par(ZeroForParRates);
% Plot Zero, Observed YTM, Fit YTM, Par, Fwd
figure
plot(Mat, ZeroRates.*100, '-b', 'LineWidth', 2) % Zero
hold on
set(gca, 'FontSize', FontSize, 'FontName', 'Arial');
plot(MatForPar, ParRates.*100, '--b', 'MarkerSize', 8, 'LineWidth', 2) % Par rates
plot(Mat, InstFwdRates.*100, ':b', 'MarkerSize', 8, 'LineWidth', 2) % FWD rates
if ~isempty(ShortRates)
    SRcount = length(ShortRates.IR);
else
    SRcount = 0;
end
plot(YTM.TimeFraction(SRcount+1:end), YTM.Obs(SRcount+1:end).*100, 'ko', 'MarkerSize', 5, 'MarkerFaceColor','k') % YTM of observed bonds
plot(YTM.TimeFraction(SRcount+1:end), YTM.Fit(SRcount+1:end).*100, 'ks', 'MarkerSize', 7) % YTM of fitted bonds
plot(YTM.TimeFraction(1:SRcount), YTM.Obs(1:SRcount).*100, 'k^', 'MarkerSize', 6, 'MarkerFaceColor','k')
% Bonds ID (issue) number
BondsCount = length(YTM.TimeFraction);
minYTM = min(YTM.Obs, YTM.Fit);
j = 1;
for i=SRcount+1:BondsCount
    h(j) = text(YTM.TimeFraction(i), minYTM(i).*100 - 0.15, YTM.Emission{i});
    j = j + 1;
end
set(h, 'FontSize', FontSize, 'FontName', 'Arial');
xlim([0 max(Mat)]);
ymin = min([ZeroRates, ParRates, InstFwdRates]);
ymax = max([ZeroRates, ParRates, InstFwdRates]);
ylim([ymin*100-0.5 ymax*100+0.5]);
% ======================================================
xlabel('Maturity in years')
ylabel('Percents')
grid off
hold off
if SRcount ~= 0
    legend('Spot Rates', 'Par Rates', 'Instantaneous Forward Rates',...
           'Observed Yields to Maturity', 'Fitted Yields to Maturity', 'Short-Rates')
else
    legend('Spot Rates', 'Par Rates', 'Instantaneous Forward Rates',...
           'Observed Yields to Maturity', 'Fitted Yields to Maturity')

end
legend('Location', 'NorthWest')
legend('boxoff')

end


function cc_to_st_test01 ( )

%*****************************************************************************80
%
%% CC_TO_ST_TEST01 tests CC_TO_ST using a 1-based matrix.
%
%  Discussion:
%
%    This test uses a trivial matrix whose full representation is:
%
%          2  3  0  0  0
%          3  0  4  0  6
%      A = 0 -1 -3  2  0
%          0  0  1  0  0
%          0  4  2  0  1
%
%    The 1-based CC representation is
%
%      #  ICC  CCC  ACC
%     --  ---  ---  ---
%      1    1    1    2
%      2    2         3
%
%      3    1    3    3
%      4    3        -1
%      5    5         4
%
%      6    2    6    4
%      7    3        -3
%      8    4         1
%      9    5         2
%
%     10    3   10    2
%
%     11    2   11    6
%     12    5         1
%
%     13    *   13
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 July 2014
%
%  Author:
%
%    John Burkardt
%
  m = 5;
  n = 5;
  ncc = 12;

  acc = [ ...
    2.0,  3.0, ...
    3.0, -1.0,  4.0, ...
    4.0, -3.0,  1.0, 2.0, ...
    2.0, ...
    6.0, 1.0 ];
  ccc = [ ...
    1, 3, 6, 10, 11, 13 ];
  icc = [ ...
    1, 2, ...
    1, 3, 5, ...
    2, 3, 4, 5, ...
    3, ...
    2, 5 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CC_TO_ST_TEST01\n' );
  fprintf ( 1, '  Convert a 1-based CC matrix to ST format.\n' );
%
%  Print the CC matrix.
%
  cc_print ( m, n, ncc, icc, ccc, acc, '  The CC matrix:' );
%
%  Convert it.
%
  [ nst, ist, jst, ast ] = cc_to_st ( m, n, ncc, icc, ccc, acc );
%
%  Print the ST matrix.
%
  st_print ( m, n, nst, ist, jst, ast, '  The ST matrix:' );

  return
end


function pwl_interp_2d_scattered_test01 ( )

%*****************************************************************************80
%
%% PWL_INTERP_2D_TEST01 tests R8TRIS2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 October 2012
%
%  Author:
%
%    John Burkardt
%
  node_num = 9;
  element_order = 3;

  node_xy = [ ...
       0.0, 0.0;
       0.0, 1.0;
       0.2, 0.5;
       0.3, 0.6;
       0.4, 0.5;
       0.6, 0.4;
       0.6, 0.5;
       1.0, 0.0;
       1.0, 1.0 ]';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'PWL_INTERP_2D_TEST01\n' );
  fprintf ( 1, '  R8TRIS2 computes the Delaunay triangulation of\n' );
  fprintf ( 1, '  a set of nodes in 2D.\n' );
%
%  Set up the Delaunay triangulation.
%
  [ element_num, triangle, element_neighbor ] = r8tris2 ( node_num, node_xy );

  triangulation_order3_print ( node_num, element_num, node_xy, ...
    triangle, element_neighbor );

  return
end


function K = correlation_brownian ( s, t )

%*****************************************************************************80
%
%% CORRELATION_BROWNIAN computes the Brownian correlation function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 June 2014
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real S(*), T(*), pairs of argument values.
%
%    Output, real K(*), the correlation function values
%
  K = ones ( size ( s ) );
  i = find ( max ( s, t ) ~= 0.0 );
  K(i) = sqrt ( min ( s(i), t(i) ) ./ max ( s(i), t(i) ) );

  return
end


function [c]=ref_dgt(f,g,a,M)
%REF_DGT  Reference Discrete Gabor transform.
%   Usage:  c=ref_dgt(f,g,a,M);
%
%   Linear algebra version of the algorithm. Create big matrix
%   containing all the basis functions and multiply with the transpose.

g = double(g);
f = double(f);
% Calculate the parameters that was not specified.
L=size(g,1);

b=L/M;
N=L/a;
W=size(f,2);
R=size(g,2);

% Create 2x2 grid matrix..
V=[a,0;
   0,b];

% Create lattice and Gabor matrix.
lat=ref_lattice(V,L);
G=ref_gaboratoms(g,lat);

% Apply matrix to f.
c=G'*f;

% reshape to correct output format.

c=reshape(c,M,N,R*W);


%% cart2im
% Below is a demonstration of the features of the |cart2im| function

%%
clear; close all; clc;

%% Syntax
% |[I,J,K]=cart2im(X,Y,Z,v);|

%% Description
% This function converts the cartesian coordinates X,Y,Z to image
% coordinates I,J,K using the voxel dimension v.
%
% X,Y,Z can be scalars, vectors or matrices.
% v is a vector of length 3 where v(1), v(2) and v(3) correspond to the
% voxel dimensions in the x,y and z direction respectively.

%% Examples

%%
% Plot settings
cMap=gjet(250);
faceAlpha1=0.5;
edgeColor1='none';
edgeColor2='none';
fontSize=15;

%% Example: Using |im2cart| and |cart2im| to convert from image to real world coordinates

% Get a 3D image
load mri;
M=squeeze(D); %example image data set
v=[2 2 5]; %example voxel size, not voxels are ellongated in slice direction

%%
% The voxels to display can be specified as a list (vector) of voxels
% numbers (linear indices) or using a mask (logic array).

%Defining row, column and slice indicices for slice patching
sliceIndexI=round(size(M,1)/2); %(close to) middle row
sliceIndexJ=round(size(M,2)/2); %(close to) middle column
sliceIndexK=round(size(M,3)/2); %(close to) middle slice

%Defining "masks" i.e. logic arrays with ones for voxels of interest
logicSliceI=false(size(M));
logicSliceI(sliceIndexI,:,:)=1;
logicSliceI=logicSliceI & M>0;

logicSliceJ=false(size(M));
logicSliceJ(:,sliceIndexJ,:)=1;
logicSliceJ=logicSliceJ & M>0;

logicSliceK=false(size(M));
logicSliceK(:,:,sliceIndexK)=1;
logicSliceK=logicSliceK & M>0;

% Creating patch data
[Fx,Vx,Cx]=ind2patch(logicSliceJ,M,'sj');
[Fy,Vy,Cy]=ind2patch(logicSliceI,M,'si');
[Fz,Vz,Cz]=ind2patch(logicSliceK,M,'sk');

% Convert image coordinates to cartesian coordinates
[Vx(:,1),Vx(:,2),Vx(:,3)]=im2cart(Vx(:,2),Vx(:,1),Vx(:,3),v);
[Vy(:,1),Vy(:,2),Vy(:,3)]=im2cart(Vy(:,2),Vy(:,1),Vy(:,3),v);
[Vz(:,1),Vz(:,2),Vz(:,3)]=im2cart(Vz(:,2),Vz(:,1),Vz(:,3),v);

h8=cFigure;
title('MRI visualisation, slices and voxels in cartesian coordinates with aid of voxel size');
xlabel('X (mm)');ylabel('Y (mm)'); zlabel('Z (mm)'); hold on;
hp2= patch('Faces',Fx,'Vertices',Vx,'FaceColor','flat','CData',Cx,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha1);
hp3= patch('Faces',Fy,'Vertices',Vy,'FaceColor','flat','CData',Cy,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha1);
hp4= patch('Faces',Fz,'Vertices',Vz,'FaceColor','flat','CData',Cz,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha1);
axis equal; view(3); axis tight; axis vis3d; grid on;
colormap(gray(250)); colorbar;
camlight headlight;
set(gca,'fontSize',fontSize);
drawnow;

%%
% Get example cartesian coordinates to map to image coordinates

vMid=mean(Vz,1);
plotV(vMid,'b.','MarkerSize',50);

%%
% Map to image coordinates using |cart2im|
[i,j,k]=im2cart(vMid(:,2),vMid(:,1),vMid(:,3),v);

%Image coordinates for the point are
disp(num2str([i j k]));

%Which means the indices for the voxel containing the point are
disp(num2str(round([i j k])));
%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function dataOut=prtUtilSpectralOutOfSampleExtension(dataOld,dataNew,eigVectors,eigValues,sigma)

%   dataOut=prtUtilSpectralOutOfSampleExtension(dataOld,dataNew,eigVectors,eigValues,sigma)
%   Performs an out of sample spectral dimensionality reduction.
%
%   Parameters:
%
%   dataOld - Features of in-sample data
%
%   dataNew - Features of out of sample data
%
%   eigVectors - Spectral features of in-sample data
%
%   eigValues - eigen values corresponding to eigen vectors of in-sample data
%
%   sigma - sigma used for radial basis function (RBF)
%
%
%       Example usage:
%       ds=rt(prtPreProcZmuv,prtDataGenMoon);
%       nEigs=2;
%       sigma=.2;
%
%       imagesc(ds)                          %Plot Moon data in feature space
%       title('prtDataGenMoon in Feature Space')
%
%       nPicked=30;
%       picked=randi(size(ds.X,1),[nPicked,1]);
%
%       dsNew=ds.retainObservations(picked);
%       [eigValues, eigVectors] = prtUtilSpectralDimensionalityReduction(ds.X, nEigs,'sigma',sigma);      %transform Data to Spectral Space
%       dsNew.X=prtUtilSpectralOutOfSampleExtension(ds.X,dsNew.X,eigVectors,eigValues,sigma);             %transform out of sample data to spectral space
%
%
%       figure;
%       imagesc(dsNew)                      %Plot Moon data in spectral space
%       title('prtDataGenMoon out of sample in Spectral Space')

%Reference: Bengio, Y., Paiement, J. F., Vincent, P., Delalleau, O., Le Roux, N., & Ouimet, M. (2004).
%           Out-of-sample extensions for lle, isomap, mds, eigenmaps, and spectral clustering.
%           Advances in neural information processing systems, 16, 177-184.

            n=size(dataOld,1);
            k=prtUtilRbfDist(dataNew,dataOld,'sigma',sigma);
            kNorm1=sqrt(mean(prtUtilRbfDist(dataNew,dataOld,'sigma',sigma),2));
            kNorm2=sqrt(mean(prtUtilRbfDist(dataOld,dataOld,'sigma',sigma),2));

            normKern = k./(bsxfun(@times,kNorm1,kNorm2'));

            normKernTransformed=repmat(normKern,[1,1,length(eigValues)]);
            eigTransformed=permute(repmat(eigVectors,[1,1,size(dataNew,1)]),[3,1,2]);

            sumOut=squeeze(sum(normKernTransformed.*eigTransformed,2));

            dataOut=bsxfun(@rdivide,sumOut,(n*eigValues)');

end


function [ cx, cy ] = zdrot ( n, cx, incx, cy, incy, c, s )

%*****************************************************************************80
%
%% ZDROT applies a complex plane rotation.
%
%  Discussion:
%
%    The cosine C and sine S are real and the vectors CX and CY are complex.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 May 2006
%
%  Author:
%
%    MATLAB version by John Burkardt
%
%  Reference:
%
%    Jack Dongarra, Cleve Moler, Jim Bunch, Pete Stewart,
%    LINPACK User's Guide,
%    SIAM, 1979.
%
%    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 vectors.
%
%    Input, complex CX(*), one of the vectors to be rotated.
%
%    Input, integer INCX, the increment between successive entries of CX.
%
%    Input, complex CY(*), one of the vectors to be rotated.
%
%    Input, integer INCY, the increment between successive elements of CY.
%
%    Input, real C, S, parameters (presumably the cosine and sine of
%    some angle) that define a plane rotation.
%
%    Output, complex CX(*), one of the vectors to be rotated.
%
%    Output, complex CY(*), one of the vectors to be rotated.
%
  temp(1:n)               =   c * cx(1:incx:1+(n-1)*incx) ...
                            + s * cy(1:incy:1+(n-1)*incy);

  cy(1:incy:1+(n-1)*incy) = - s * cx(1:incx:1+(n-1)*incx) ...
                            + c * cy(1:incy:1+(n-1)*incy);

  cx(1:incx:1+(n-1)*incx) = temp(1:n);

  return
end


function goldstein_price_test ( )

%*****************************************************************************80
%
%% GOLDSTEIN_PRICE_TEST works with the Goldstein-Price function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Zbigniew Michalewicz,
%    Genetic Algorithms + Data Structures = Evolution Programs,
%    Third Edition,
%    Springer Verlag, 1996,
%    ISBN: 3-540-60676-9,
%    LC: QA76.618.M53.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'GOLDSTEIN_PRICE_TEST:\n' );
  fprintf ( 1, '  Test COORDINATE_SEARCH with the Goldstein-Price function.\n' );
  n = 2;

  x = [ -0.5, 0.25 ];
  r8vec_print ( n, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', goldstein_price ( x ) );

  flag = 0;
  x = coordinate_search ( x, @goldstein_price, flag );
  r8vec_print ( n, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g\n', goldstein_price ( x ) );
%
%  Repeat with more difficult start.
%
  x = [ -4.0, 5.0 ];
  r8vec_print ( n, x, '  Initial point X0:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X0) = %g\n', goldstein_price ( x ) );

  flag = 0;
  x = coordinate_search ( x, @goldstein_price, flag );
  r8vec_print ( n, x, '  Estimated minimizer X1:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X1) = %g\n', goldstein_price ( x ) );
%
%  Demonstrate correct minimizer.
%
  x = [ 0.0, -1.0 ];
  r8vec_print ( n, x, '  Correct minimizer X*:' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  F(X*) = %g\n', goldstein_price ( x ) );

  return
end


function [ o, x, w ] = cn_jac_00_1 ( n, alpha, beta )

%*****************************************************************************80
%
%% CN_JAC_00_1 implements the midpoint rule for region CN_JAC.
%
%  Discussion:
%
%    The rule has order O = 1.
%
%    The rule has precision P = 0.
%
%    CN is the cube [-1,+1]^N with the Jacobi (beta) weight function
%
%      w(alpha,beta;x) = product ( 1 <= i <= n ) (1-x(i))^beta (1+x(i))^alpha.
%
%    with -1 < alpha, -1 < beta.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 January 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the spatial dimension.
%
%    Input, real ALPHA, BETA, the parameters.
%    -1.0 < ALPHA, -1.0 < BETA.
%
%    Output, integer O, the order.
%
%    Output, real X(N,O), the abscissas.
%
%    Output, real W(O), the weights.
%
  if ( alpha <= -1.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CN_JAC_00_1 - Fatal error!\n' );
    fprintf ( 1, '  ALPHA <= -1.0\n' );
    error ( 'CN_JAC_00_1 - Fatal error!\n' );
  end

  if ( beta <= -1.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'CN_JAC_00_1 - Fatal error!\n' );
    fprintf ( 1, '  BETA <= -1.0\n' );
    error ( 'CN_JAC_00_1 - Fatal error!\n' );
  end

  o = 1;

  expon = 0;
  volume = c1_jac_monomial_integral ( alpha, beta, expon );
  volume = volume ^ n;

  x = zeros ( n, o );
  w = zeros ( o, 1 );

  k = 0;
%
%  1 point.
%
  k = k + 1;
  w(k) = volume;

  return
end


function uI = edgeinterpolate2(exactu,node,edge,face,face2edge)
%% EDGEINTERPOLATE2 interpolate to the quadratic (1st type) edge finite element space.
%
% uI = edgeinterpolate(u,node,edge) interpolates a given function
% u into the lowesr order edge finite element spaces. The coefficient
% is given by the line integral int_e u*t ds. Simpson rule is used to
% evaluate this line integral.
%
% The input u could be a funtional handel or an array of length N (linear
% element) or N+NE (quadratic element).
%
% Example
%
%   node = [-1,-1,-1; 1,-1,-1; 1,1,-1; -1,1,-1; -1,-1,1; 1,-1,1; 1,1,1; -1,1,1];
%   elem = [1,2,3,7; 1,6,2,7; 1,5,6,7; 1,8,5,7; 1,4,8,7; 1,3,4,7];
%   maxIt = 3;
%   HcurlErr = zeros(maxIt,1);
%   L2Err = zeros(maxIt,1);
%   N = zeros(maxIt,1);
%   for k = 1:maxIt
%       [node,elem] = uniformbisect3(node,elem);
%       [elem2dof,T] = dof3NE2(elem);
%       pde = Maxwelldata2;
%       uI = edgeinterpolate2(pde.exactu,node,T.edge,T.face,T.face2edge);
%       HcurlErr(k) = getHcurlerror3ND2(node,elem,pde.curlu,uI);
%       L2Err(k) = getL2error3ND2(node,elem,pde.exactu,uI);
%       N(k) = length(uI);
%   end
%   figure(1)
%   r1 = showrate(N,HcurlErr,1,'r-+');
%   hold on
%   r2 = showrate(N,L2Err,1,'b-+');
%   legend('||u-u_I||_{curl}',['N^{' num2str(r1) '}'],...
%          '||u-u_I||',['N^{' num2str(r2) '}'],'LOCATION','Best');
%
% See also edgeinterpolate, edgeinterpolate1
%
% Maxwell doc Section: Dirichlet
% boundary condition
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

%% Evaluate function at vertices and middle points
if isnumeric(exactu)
    uQ = exactu;
else
    mid = (node(edge(:,1),:) + node(edge(:,2),:))/2;
    uQ = exactu([node; mid]);
end

%% Edge dof coefficients
N = size(node,1);	NE = size(edge,1);    NF = size(face,1);
edgeVec = node(edge(:,2),:)-node(edge(:,1),:);
uI = zeros(2*(NE+NF),1);
uI(1:NE,1) = dot(edgeVec,(uQ(edge(:,1),:)+uQ(edge(:,2),:)+4*uQ(N+1:N+NE,:))/6,2);
uI(NE+1:2*NE,1) = dot(edgeVec,0.5*(uQ(edge(:,1),:)-uQ(edge(:,2),:)),2);

%% Face dof coefficients
eik = node(face(:,3),:)-node(face(:,1),:);
eij = node(face(:,2),:)-node(face(:,1),:);
uquadpts = uQ(N+face2edge(:,1),:)+uQ(N+face2edge(:,2),:)+uQ(N+face2edge(:,3),:);
lf = [4*dot(eik,uquadpts,2) ...
      4*dot(eij,uquadpts,2)];
face2edgeDofValue = [uI(face2edge(:,1:3)) uI(face2edge(:,1:3)+NE)];
localMatrix = [4 8 4 -4  0 4; ...
               8 4 -4 0 -4 4]';
lf = lf - face2edgeDofValue*localMatrix;
uI((2*NE+1):end) = [2*lf(:,1) - lf(:,2); ...
                    2*lf(:,2) - lf(:,1)]/3;


function y = vl_nnspnorm(x, param, dzdy)
%VL_NNSPNORM CNN spaital normalization.
%   Y = VL_NNSPNORM(X, PARAM) computes the spatial normalization of
%   the data X with parameters PARAM = [PH PW ALPHA BETA]. Here PH and
%   PW define the size of the spatial neighbourhood used for
%   nomalization.
%
%   For each feature channel, the function computes the sum of squares
%   of X inside each rectangle, N2(i,j). It then divides each element
%   of X as follows:
%
%      Y(i,j) = X(i,j) / (1 + ALPHA * N2(i,j))^BETA.
%
%   DZDX = VL_NNSPNORM(X, PARAM, DZDY) computes the derivative of the
%   block projected onto DZDY. DZDX and DZDY have the same dimensions
%   as X and Y respectively.

% Copyright (C) 2015 Karel Lenc and Andrea Vedaldi.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

pad = floor((param(1:2)-1)/2) ;
pad = [pad ; param(1:2)-1-pad] ;

n2 = vl_nnpool(x.*x, param(1:2), 'method', 'avg', 'pad', pad) ;
f = 1 + param(3) * n2 ;

if nargin <= 2 || isempty(dzdy)
  y = f.^(-param(4)) .* x ;
else
  t = vl_nnpool(x.*x, param(1:2), f.^(-param(4)-1) .* dzdy .* x, 'method', 'avg', 'pad', pad) ;
  y = f.^(-param(4)) .* dzdy - 2 * param(3)*param(4) * x .* t ;
end


classdef SuperEllipseParamsRelator < handle

   methods (Access = public, Static)

       function mx = mx(xi,rho,q)
            c = SuperEllipseParamsRelator.c();
            n = (1-rho).*tan(xi);
            d = c(q);
            mx = sqrt(n./d);
       end

       function my = my(xi,rho,q)
            c = SuperEllipseParamsRelator.c();
            n = (1-rho);
            d = c(q).*tan(xi);
            my = sqrt(n./d);
       end

       function rho = rho(mx,my,q)
            c = SuperEllipseParamsRelator.c();
            rho =  1 - c(q).*mx.*my;
       end

       function xi = xi(mx,my)
           xi = atan(mx./my);
       end

       function c = c()
          c = @(q) gamma(1 + 1./q).^2./gamma(1 + 2./q);
       end

       function my = myFromMxAndTxi(mx,xi)
          my = mx./tan(xi);
       end

       function mx = mxFromMyAndTxi(my,xi)
          mx = my.*tan(xi);
       end

       function rho = rhoFromMxAndTxi(mx,xi,q)
           sE  = SuperEllipseParamsRelator();
           my  = sE.myFromMxAndTxi(mx,xi);
           rho = sE.rho(mx,my,q);
       end

       function rho = rhoFromMyAndTxi(my,xi,q)
           sE  = SuperEllipseParamsRelator();
           mx  = sE.mxFromMyAndTxi(my,xi);
           rho = sE.rho(mx,my,q);
       end

       function xi = xiFromMxAndRho(mx,rho,q)
           sE  = SuperEllipseParamsRelator();
           c  = sE.c();
           xi = atan(c(q).*mx.^2./(1-rho));
       end

       function xi = xiFromMyAndRho(my,rho,q)
           sE  = SuperEllipseParamsRelator();
           c  = sE.c();
           xi = atan((1-rho)./(c(q).*my.^2));
       end

       function xiUB = xiUB(rho)
           sE  = SuperEllipseParamsRelator();
           qMax = 32;
           qMin = 2;
           mxUB = 0.99;
           myLB = 0.01;
           xi1 = sE.xiFromMxAndRho(mxUB,rho,qMax);
           xi2 = sE.xiFromMyAndRho(myLB,rho,qMin);
           xiUB = min(xi1,xi2);
       end

       function xiLB = xiLB(rho)
           sE  = SuperEllipseParamsRelator();
           qMax = 32;
           qMin = 2;
           mxLB = 0.01;
           myUB = 0.99;
           xi1 = sE.xiFromMxAndRho(mxLB,rho,qMin);
           xi2 = sE.xiFromMyAndRho(myUB,rho,qMax);
           xiLB = min(xi1,xi2);
       end

       function [mXb,mYb] = updateMxMyWithOtherQ(mXa,mYa,q,qNew)
            sE   = SuperEllipseParamsRelator;
            rho  = sE.rho(mXa,mYa,q);
            xi   = sE.xi(mXa,mYa);
            mXb  = sE.mx(xi,rho,qNew);
            mYb  = sE.my(xi,rho,qNew);
       end

   end

end


function f = ackleysfcn(x)
% Ackley's Function.

if strcmp(x,'init')
    f.PopInitRange = [-32.768; 32.768] ;
    f.KnownMin = [0,0] ; % For plotting only
else
    x = reshape(x,1,[]) ;
    a = 20 ;
    b = 0.2 ;
    n = size(x,2) ;
    c = 2*pi ;
    f = -a*exp(-b*sqrt(1/n*(x*x'))) - exp(1/n*(cos(c*x)*cos(c*x'))) + ...
        a + exp(1) ;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rls.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% function [x,act]=rls(A,b,fac);
% function [x,act]=rls(A,b,x0,r);
% minimizes ||Ax-b||_2^2  s.t. |x-x0|<=r
% act=(is some constraint active?)
%
% if nargin<4, x0=0 and r(k)=fac*||b||/||A(:,k)||
% (default: fac=1000);
%
function [x,act]=rls(A,b,x0,r);

% set defaults
if     nargin<3, fac=1000;x0=zeros(size(A,2),1);
elseif nargin<4, fac=x0;x0=zeros(size(A,2),1);
else             b=b-A*x0;
end;

x=x0;
aa=diag(A'*A);

% handle zero columns directly
ind=find(aa>0);
n=length(ind);
if n==0, act=1; return; end;

A=A(:,ind);
gamma=b'*b;
if gamma==0, act=1; return; end;
if nargin<4, r=fac*sqrt(gamma./aa(ind));
else         r=r(ind);
end;

% now we need to minimize ||Az-b||^2  s.t. |z|<=r
prt=0;
[z,fct,ier]=minq(0,-A'*b,A'*A,-r,r,prt);
act=max(abs(z)./r);
x(ind)=x(ind)+z;


function R = apprRot(Ra)
%R = apprRot(Ra)

i1 = 0.5; i2 = 0.5;
U = Ra(1,:);
V = Ra(2,:);
un = norm(U);
vn = norm(V);
Un = U/un;
Vn = V/vn;

vp = Un*Vn';
up = Vn*Un';

Vc = Vn-vp*Un;  Vc = Vc/norm(Vc);
Uc = Un-up*Vn;  Uc = Uc/norm(Uc);

Ua = i1*Un+i2*Uc; Ua = Ua/norm(Ua);
Va = i1*Vn+i2*Vc; Va = Va/norm(Va);

R = [Ua;Va;cross(Ua,Va)];
if det(R)<0, R(3,:) = -R(3,:); end;


siz = 512;
rad = 36;

% Find the maximum

imm = im;
imt = imm;
fil = zeros( siz, siz );

[val ind] = max( imt(:) );

while (val > 0)

x = floor( (ind-1) / siz ) + 1;
y = mod  ( (ind-1),  siz ) + 1;

fil = fil + mkCircMask( rad, [siz siz], [x y] ) .* val;

imt = imm - fil;
imt = imt.*(imt > 0);

[val ind] = max( imt(:) );

end

fmax = fil;

% Find the minimum

imm = max(max(im)) - im;
imt = imm;
fil = zeros( siz, siz );

[val ind] = max( imt(:) );

while (val > 0)

x = floor( (ind-1) / siz ) + 1;
y = mod  ( (ind-1),  siz ) + 1;

fil = fil + mkCircMask( rad, [siz siz], [x y] ) .* val;

imt = imm - fil;
imt = imt.*(imt > 0);

[val ind] = max( imt(:) );

end

fmin = max(max(im)) - fil;


function w=weight2(n,m) % n-length of weighting vector, m - is alpha
% quadratic linguistic quantifier: Q(r)=(1/(1-alpha*(r)^0.5))
re=[];
for h=1:n
    re=[re ((1-m*(h/n)^0.5)^-1 - (1-m*((h-1)/n)^0.5)^-1)];
end
reT=sum(re);
w=re/reT;
end


function p = paris(grains)
% Percentile Average Relative Indented Surface
%
% the paris (Percentile Average Relative Indented Surface) is shape
% parameter that measures the convexity of a grain
%
% Syntax
%   p = paris(grains)
%
% Input
%  grains - @grain2d
%
% Output
%  p - double
%
%

% store this in local variables for speed reasons
p = zeros(size(grains));

X = grains.V(:,1);
Y = grains.V(:,2);

poly = grains.poly;
% remove inclusions
incl = grains.inclusionId;
for i = find(incl>0).'
  poly{i} = poly{i}(1:end-incl(i));
end

% compute convex hull perimeters
for id = 1:length(grains)

  % for small grains there is no difference
  if length(poly{id}) <= 7, continue; end

  % extract coordinates
  xGrain = X(poly{id});
  yGrain = Y(poly{id});

  % compute perimeter
  perimeterGrain = sum(sqrt(...
    (xGrain(1:end-1) - xGrain(2:end)).^2 + ...
    (yGrain(1:end-1) - yGrain(2:end)).^2));

  % compute convex hull
  ixy = convhull(xGrain,yGrain);

  % compute perimenter
  perimeterHull = sum(sqrt(...
    (xGrain(ixy(1:end-1)) - xGrain(ixy(2:end))).^2 + ...
    (yGrain(ixy(1:end-1)) - yGrain(ixy(2:end))).^2));

  % paris is the relative difference between convex hull perimenter and true
  % perimeter
  p(id) = 200*(perimeterGrain - perimeterHull)./perimeterHull;

end


function [h,T,perm] = polardendrogram(Z,varargin)
%POLARDENDROGRAM plots a polar dendrogram plot, taking same options as
%dendrogram and giving same outputs.
% Example:
% X= rand(100,2);
% Y= pdist(X,'cityblock');
% Z= linkage(Y,'average');
% [H,T] = polardendrogram(Z,'colorthreshold','default');

%Plot a normal dendrogram
[h,T,perm] = dendrogram(Z,varargin{:});

%Get x and y ranges
xlim = get(gca,'XLim');
ylim = get(gca,'YLim');
minx = xlim(1);
maxx = xlim(2);
miny = ylim(1);
maxy = ylim(2);
xrange = maxx-minx;
yrange = maxy-miny;

%Reshape into a polar plot
for i=1:size(h)
    xdata = get(h(i),'XData');
    ydata = get(h(i),'YData');
    %Rescale xdata to go from pi/12 to 2pi - pi/12
    xdata = (((xdata-minx)/xrange)*(pi*11/6))+(pi/12);
    %Rescale ydata to go from 1 to 0, cutting off lines
    %which drop below the axis limit
    ydata = max(ydata,miny);
    ydata = 1-((ydata-miny)/yrange);
    %To make horizontal lines look more circular,
    %insert ten points into the middle of the line before
    %polar transform
    newxdata = [xdata(1), linspace(xdata(2),xdata(3),10), xdata(4)];
    newydata = [ydata(1), repmat(ydata(2),1,10), ydata(4)];
    %Transform to polar coordinates
    [xdata,ydata]=pol2cart(newxdata,newydata);
    %Reset line positions to new polar positions
    set(h(i),'XData',xdata);
    set(h(i),'YData',ydata);
end

%Relabel leaves
for i=minx+1:maxx-1
    [x,y]=pol2cart((((i-minx)/xrange)*(pi*11/6))+(pi*1/12),1.1);
    text(x,y,num2str(perm(i)));
end

%Add and label gridlines
hold on
lineh(1) = polar([0,0],[0,1],'-');
lineh(2) = polar(linspace(0,2*pi,50),ones(1,50),':');
lineh(3) = polar(linspace(0,2*pi,50),ones(1,50)*0.75,':');
lineh(4) = polar(linspace(0,2*pi,50),ones(1,50)*0.5,':');
lineh(5) = polar(linspace(0,2*pi,50),ones(1,50)*0.25,':');
set(lineh,'Color',[0.5,0.5,0.5]);
for i=1:4
    [x,y]=pol2cart(0,i/4);
    str = sprintf('%2.1f',((maxy-miny)*(4-i)/4)+miny);
    text(x,y,str,'VerticalAlignment','bottom');
end

%Prettier
set(gca,'XLim',[-1.5,1.5],'YLim',[-1.5,1.5],'Visible','off');
view(3)
axis fill
daspect([1,1,100]);
zoom(2.8);


function [ n_data, sigma, x, fx ] = rayleigh_cdf_values ( n_data )

%*****************************************************************************80
%
%% RAYLEIGH_CDF_VALUES returns some values of the Rayleigh CDF.
%
%  Discussion:
%
%    In Mathematica, the function can be evaluated by:
%
%      Needs["Statistics`ContinuousDistributions`"]
%      dist = RayleighDistribution [ sigma ]
%      CDF [ dist, x ]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Wolfram Media / Cambridge University Press, 1999.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0 before the
%    first call.  On each call, the routine increments N_DATA by 1, and
%    returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real SIGMA, the shape parameter of the distribution.
%
%    Output, real X, the argument of the function.
%
%    Output, real FX, the value of the function.
%
  n_max = 9;

  fx_vec = [ ...
     0.8646647167633873E+00, ...
     0.9996645373720975E+00, ...
     0.9999999847700203E+00, ...
     0.999999999999987E+00, ...
     0.8646647167633873E+00, ...
     0.3934693402873666E+00, ...
     0.1992625970831920E+00, ...
     0.1175030974154046E+00, ...
     0.7688365361336422E-01 ];

  sigma_vec = [ ...
     0.5000000000000000E+00, ...
     0.5000000000000000E+00, ...
     0.5000000000000000E+00, ...
     0.5000000000000000E+00, ...
     0.1000000000000000E+01, ...
     0.2000000000000000E+01, ...
     0.3000000000000000E+01, ...
     0.4000000000000000E+01, ...
     0.5000000000000000E+01 ];

  x_vec = [ ...
     0.1000000000000000E+01, ...
     0.2000000000000000E+01, ...
     0.3000000000000000E+01, ...
     0.4000000000000000E+01, ...
     0.2000000000000000E+01, ...
     0.2000000000000000E+01, ...
     0.2000000000000000E+01, ...
     0.2000000000000000E+01, ...
     0.2000000000000000E+01 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    sigma = 0.0;
    x = 0.0;
    fx = 0.0;
  else
    sigma = sigma_vec(n_data);
    x = x_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end


function net = cnn_mnist_init(varargin)
% CNN_MNIST_LENET Initialize a CNN similar for MNIST
opts.batchNormalization = true ;
opts.networkType = 'simplenn' ;
opts = vl_argparse(opts, varargin) ;

rng('default');
rng(0) ;

f=1/100 ;
net.layers = {} ;
net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(5,5,1,20, 'single'), zeros(1, 20, 'single')}}, ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(5,5,20,50, 'single'),zeros(1,50,'single')}}, ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(4,4,50,500, 'single'),  zeros(1,500,'single')}}, ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'conv', ...
                           'weights', {{f*randn(1,1,500,10, 'single'), zeros(1,10,'single')}}, ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'softmaxloss') ;

% optionally switch to batch normalization
if opts.batchNormalization
  net = insertBnorm(net, 1) ;
  net = insertBnorm(net, 4) ;
  net = insertBnorm(net, 7) ;
end

% Meta parameters
net.meta.inputSize = [27 27 1] ;
net.meta.trainOpts.learningRate = 0.001 ;
net.meta.trainOpts.numEpochs = 20 ;
net.meta.trainOpts.batchSize = 100 ;

% Fill in defaul values
net = vl_simplenn_tidy(net) ;

% Switch to DagNN if requested
switch lower(opts.networkType)
  case 'simplenn'
    % done
  case 'dagnn'
    net = dagnn.DagNN.fromSimpleNN(net, 'canonicalNames', true) ;
    net.addLayer('error', dagnn.Loss('loss', 'classerror'), ...
             {'prediction','label'}, 'error') ;
  otherwise
    assert(false) ;
end

% --------------------------------------------------------------------
function net = insertBnorm(net, l)
% --------------------------------------------------------------------
assert(isfield(net.layers{l}, 'weights'));
ndim = size(net.layers{l}.weights{1}, 4);
layer = struct('type', 'bnorm', ...
               'weights', {{ones(ndim, 1, 'single'), zeros(ndim, 1, 'single')}}, ...
               'learningRate', [1 1 0.05], ...
               'weightDecay', [0 0]) ;
net.layers{l}.biases = [] ;
net.layers = horzcat(net.layers(1:l), layer, net.layers(l+1:end)) ;


% The OxyGEN proyect by Profoty.xyz
% Together against the Covid-19
% V4.0 rev.17/03/2020
%
% Website/blog: oxygen.protofy.xyz
% Contact: oxygen@protofy.xyz

%GEOMETRICAL PARAMETERS

clear;

%Length from the bearing to the hinge
l0 = 27.5;

%Length of the vertical wall that supports the hinge
h0 = 6.5;

%Lenght of the vertical support of the bearing
hb = 4.0;

%Bearing radius
br = 1.1;

%Array of different max and min positions of the bearing
h1a = [9, 10, 11];
h2a = [20, 20, 20];

%Number of cycles per cam turn (1 to 3).
nc = 1;

%Minimum radius of the camshaft
rmin = 5.5;

%BREATHING CYCLE PARAMETERS

%Duration of the inhale cycle / duration of the whole cycle
lambda1 = 0.500;
lambda2 = 0.060;

%Soft transition between inhale and exhale cycles
dpsi21 = 0.12;
dpsi12 = 0.15;

%Adjust parameters of the inhale curve
ga1 = pi;
gb1 = 1.2;
ff1 = 20;
sp1 = 1;

%Adjust parametes of the exhale curve
ga2 = 9;
gb2 = .5;
ff2 = 20;

%GENERATION OF THE CURVES AND THE CAMSHAFT

%Generation of the geometry

l = sqrt(l0^2+hb^2);

for i = 1:numel(h1a);

    ymin(i) = h1a(i);
    ymax(i) = h2a(i);

    alphamin(i) = acos((h0 - h1a(i)) / l);
    alphamax(i) = acos((h0 - h2a(i)) / l);

    xmin(i) = l*sin(alphamin(i));
    xmax(i) = l*sin(alphamax(i));

    d(i) = sqrt((xmin(i)-xmax(i))^2 + (ymin(i)-ymax(i))^2);

    alphatan(i) = (alphamin(i) + alphamax(i)) / 2;

    xtan(i) = l*sin(alphatan(i));
    ytan(i) = h0 - l*cos(alphatan(i));

    xsup(i) = xtan(i) + (d(i)/2)*cos(alphatan(i));
    xinf(i) = xtan(i) - (d(i)/2)*cos(alphatan(i));

    ysup(i) = ytan(i) + (d(i)/2)*sin(alphatan(i));
    yinf(i) = ytan(i) - (d(i)/2)*sin(alphatan(i));

    xcam(i) = xtan(i) + (d(i)/2 + rmin + br)*cos(alphatan(i));
    ycam(i) = ytan(i) + (d(i)/2 + rmin + br)*sin(alphatan(i));

end;

%Time increment
dt = 0.01;

%time coordinate during the whole cycle
theta = 0:dt:2*pi;

%Generation of the soft transition between inhale and exhale curves
psi1 = [];
psi2 = [];

for i = 1:numel(theta);

    if theta(i) < (lambda2-dpsi21/2)*2*pi;
        psi1(i) = 0;

    elseif theta(i) < (lambda2+dpsi21/2)*2*pi;
        psi1(i) = 0.5 + 0.5*cos((theta(i)-(lambda2+dpsi21/2)*2*pi)/(2*dpsi21));

    else theta(i) < (lambda1-dpsi12/2)*2*pi;
        psi1(i) = 1;

    end;

    psi2(i) = 1 - psi1(i);

end;

%Generation of the complete breathing cycle rho(theta)

rho = [];
rho1 = [];
rho2 = [];
rho2next = [];

rhomin = 1000;
rhomax = 0;

for i = 1:numel(theta);

    %Inhale curve
    rho1(i) = ff1*normpdf(sp1*theta(i), ga1, gb1);
    rho1next(i) = ff1*normpdf(sp1*theta(i)+sp1*2*pi, ga1, gb1);

    %Exhale curve
    rho2(i) = ff2*gampdf(theta(i), ga2, gb2);
    rho2next(i) = ff2*gampdf(theta(i)+2*pi, ga2, gb2);

    rho(i) = rho1(i);

    %Capturing min and max in order to generate the normalized curve
    if rho(i) > rhomax
        rhomax = rho(i);
    end;

    if rho(i) < rhomin
        rhomin = rho(i);
    end;

end;

%Generation of a normalised curve and camshaft

rhonorm = [];
rhocam = [];

for i = 1:numel(theta);

    rhonorm(i) = (rho(i)-rhomin)/(rhomax-rhomin);

    for n = 1:numel(d)

        rhocam(n,i) = rmin + rhonorm(i)*d(n);

    end;

end;

%Generation of the first derivate of the camshaft geometry to analize and
%validate the design

drho = [];
drhonorm = [];
drhocam = [];

a = rmin;
b = 1/dt;

for i = 1 : numel(rho)-1;

    drho(i) = b*(rho(i+1)-rho(i));
    drhonorm(i) = b*(rhonorm(i+1)-rhonorm(i));
    drhocam(i) = b*(rhocam(i+1)-rhocam(i)) + a;

end;

drho(numel(rho)) = b*(rho(1)-rho(numel(rho)));
drhonorm(numel(rhonorm)) = b*(rhonorm(1)-rhonorm(numel(rhonorm)));
drhocam(numel(rhocam)) = b*(rhocam(1)-rhocam(numel(rhocam))) + a;

%X and Y coordinates during two cycles (for 2-cycle camshaft plot)

theta2 = [theta/2, (2*pi+theta)/2];

rhocam2 = [rhocam, rhocam];
drhocam2 = [drho, drho];

%X and Y coordinates during three cycles (for 3-cycle camshaft plot)

theta3 = [theta/3, (2*pi+theta)/3, (4*pi+theta)/3];

rhocam3 = [rhocam, rhocam, rhocam];
drhocam3 = [drho, drho, drho];

%GENERATION OF THE PLOTS

%Trying to print it out in real size (FAIL)
%set(gcf,'PaperUnits','centimeters');
%set(gcf,'PaperSize',[42 29.7]);

fpos = figure('Name', 'Dimensions', 'Units', 'centimeters', 'NumberTitle', 'off');
set(gcf,'PaperUnits','centimeters', 'PaperSize', [42/2 27.9/2]);
set(gcf, 'units', 'centimeters', 'position', [0, 0, 28, 20]);
fpos = gcf;
hold on

xlim([-5 35]);
ylim([0 30]);

for i = 1:numel(xmin)

    plot([0, xmin(i)], [h0, ymin(i)], '-x')
    plot([0, xmax(i)], [h0, ymax(i)], '-x')

    plot([0, xtan(i)], [h0, ytan(i)], '--xb')

    plot([xsup(i), xinf(i)], [ysup(i), yinf(i)], '--xr')
    scatter(xcam(i), ycam(i))

end;

hold off

%Plot of the breathing cycle interpolation by curves

fcycle = figure('Name', 'Breath Cycle curves', 'Units', 'centimeters', 'NumberTitle', 'off');

hold on
plot(theta, psi1, '-k')
plot(theta, psi2, '-k')
plot(theta, rho1, '-g')
plot(theta, rho1next, '-g')
plot(theta, rho2, '-g')
plot(theta, rho2next, '-g')
%plot(theta, drho, '-r')
plot(theta, rho, '-b')
hold off

set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
fcam3 = gcf;

%Plot of the normalized breathing cycle and first derivate

fnorm = figure('Name', 'Normalized Breath Cycle', 'Units', 'centimeters', 'NumberTitle', 'off');

hold on
%plot(theta, drhonorm, '-r')
plot(theta, rhonorm, '-b')
hold off

set(gcf,'PaperUnits','centimeters', 'PaperSize', [42/2 27.9/2]);
set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
fcam3 = gcf;

%Plot of a 1-cycle camshaft

for n = 1:numel(d)

    fcam1 = figure('Name', '1-Cycle Camshaft', 'Units', 'centimeters', 'NumberTitle', 'off');
    %hold on

    %polarplot(theta, drhocam, '-r')
    polar(theta, rhocam(n,:), '-b')

    %rlim([0 25]);
    hold off

    set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
    set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
    fcam3 = gcf;

end

% %Plot of a 2-cycle camshaft
%
% fcam2 = figure('Name', '2-Cycle', 'Units', 'centimeters', 'NumberTitle', 'off');
%
% %hold on;
% %polar(theta, drhocam2, '-r')
% polar(theta2, rhocam2, '-b')
% %hold off;
%
% set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
% set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
% fcam3 = gcf;
%
%
% %Plot of a 3-cycle camshaft
%
% fcam3 = figure('Name', '3-Cycle', 'Units', 'centimeters', 'NumberTitle', 'off');
%
% %hold on;
% %polar(theta,drhocam3)
% polar(theta3, rhocam3)
% %hold off;
%
% set(gcf,'PaperUnits','centimeters', 'PaperSize', [42 27.9]);
% set(gcf, 'units', 'centimeters', 'position', [0, 0, 27.9, 27.9]);
% fcam3 = gcf;

% The OxyGEN proyect by Profoty.xyz
% Together against the Covid-19
% V4.0 rev.17/03/2020
%
% Website/blog: oxygen.protofy.xyz
% Contact: oxygen@protofy.xyz


function [C] = K2C(K)
% Convert temperature from Kelvin to degrees Celsius.
C = K-273.15;