%ARDEM	Demonstrates modules of the ARfit package.

%   Revised: 30-Dec-99 Tapio Schneider

format short
format compact

echo on
clc

%  ARfit is a collection of Matlab modules for the modeling of
%  multivariate time series with autoregressive (AR) models. ARfit
%  contains modules for estimating parameters of AR models from given
%  time series data; for checking the adequacy of an estimated
%  AR model; for analyzing eigenmodes of an estimated AR model; and
%  for simulating AR processes.
%
%  This demo illustrates the use of ARfit with a bivariate AR(2)
%  process
%
%       v(k,:)' = w' + A1*v(k-1,:)' + A2*v(k-2,:)' + eta(k,:)',
%
%  where the row vectors eta(k,:) are independent and identically
%  distributed Gaussian noise vectors with zero mean and covariance
%  matrix C. The kth row v(k,:) of the 2-column matrix v represents an
%  observation of the process at instant k. The intercept vector w is
%  included to allow for a nonzero mean of the AR(p) process.

pause   	% Press any key to continue.

clc

%  Let us simulate observations from a bivariate AR(2) process,
%  choosing the parameters

w = [ 0.25 ;  0.1 ];

% for the intercept vector,

A1 = [ 0.4   1.2;   0.3   0.7 ];

%  and

A2 = [ 0.35 -0.3;  -0.4  -0.5 ];

%  for the AR coefficient matrices, and

C = [ 1.00  0.50;   0.50  1.50 ];

%  for the noise covariance matrix. The two 2x2 matrices A1 and A2 are
%  assembled into a single 2x4 coefficient matrix:

A = [ A1 A2 ];

%  We use the module ARSIM to simulate 200 observations of this AR
%  process:

v = arsim(w, A, C, 200);

pause   	% Press any key to continue.

clc

%  Suppose that we have no information about how the time series
%  data v are generated, but we want to try to fit an AR model to the
%  time series. That is, we must estimate the AR model parameters,
%  including the model order. Assuming that the correct model order
%  lies between 1 and 5, we use the module ARFIT to determine the
%  optimum model order using Schwarz's Bayesian Criterion (SBC):

pmin = 1;
pmax = 5;
[west, Aest, Cest, SBC, FPE, th] = arfit(v, pmin, pmax);

%  The output arguments west, Aest, and Cest of ARFIT are the
%  estimates of the intercept vector w, of the coefficient matrix A,
%  and of the noise covariance matrix C. (The matrix th will be needed
%  later in the computation of confidence intervals.) These parameters
%  are estimated for a model of order popt, where the optimum model
%  order popt is chosen as the minimizer of an approximation to
%  Schwarz's Bayesian Criterion. The selected order popt in our
%  example is:

m    = 2;                 % dimension of the state space
popt = size(Aest, 2) / m;

disp(['popt = ', num2str(popt)])

pause   	% Press any key to continue.

clc

%  Besides the parameter estimates for the selected model, ARFIT has
%  also returned approximations to Schwarz's Bayesian Criterion SBC
%  and to Akaike's Final Prediction Error FPE, each for models of
%  order pmin:pmax. In this demo, the model order was chosen as the
%  minimizer of SBC. Here are the SBCs for the fitted models of order
%  1,...,5:

disp(SBC)

%  To see if using Akaike's Final Prediction Error as a criterion to
%  select the model order would have resulted in the same optimum
%  model order, compare the FPEs:

disp(FPE)

%  Employing FPE as the order selection criterion, the optimum model
%  order would have been chosen as the minimizer of FPE. The values of
%  the order selection criteria are approximations in that in
%  evaluating an order selection criterion for a model of order p <
%  pmax, the first pmax-p observations of the time series are ignored.

pause   	% Press any key to continue.

clc

%  Next it is necessary to check whether the fitted model is adequate
%  to represent the time series v. A necessary condition for model
%  adequacy is the uncorrelatedness of the residuals. The module ARRES

[siglev,res] = arres(west,Aest,v);

%  returns the time series of residuals res as well as the
%  significance level siglev with which a modified Li-McLeod
%  portmanteau test rejects the null hypothesis that the residuals are
%  uncorrelated. A model passes this test if, say, siglev > 0.05.  In
%  our example, the significance level of the modified Li-McLeod
%  portmanteau statistic is

disp(siglev);

%  (If siglev is persistently smaller than about 0.05, even over
%  several runs of this demo, then there is most likely a problem with
%  the random number generator that ARSIM used in the simulation of
%  v.)

pause   	% Press any key to continue.

clc

if exist('xcorr')    % If the Signal Processing Toolbox is installed, plot
                     % autocorrelation function of residuals ...

%  Using ACF, one can also plot the autocorrelation function of, say,
%  the first component of the time series of residuals:

acf(res(:,1));

%  95% of the autocorrelations for lag > 0 should lie between the
%  dashdotted confidence limits for the autocorrelations of an IID
%  process of the same length as the time series of residuals res.

%  Since uncorrelatedness of the residuals is only a necessary
%  condition for model adequacy, further diagnostic tests should, in
%  practice, be performed. However, we shall go on to the estimation
%  of confidence intervals.

pause   	% Press any key to continue.
end

clc

%  Being reasonably confident that the model adequately represents the
%  data, we compute confidence intervals for the AR parameters with
%  the module ARCONF:

[Aerr, werr] = arconf(Aest, Cest, west, th);

%  The output arguments Aerr and werr contain margins of error such
%  that (Aest +/- Aerr) and (west +/- werr) are approximate 95%
%  confidence intervals for the individual AR coefficients and for the
%  components of the intercept vector w. Here is the estimated
%  intercept vector with margins of error for the individual
%  components in the second column:

disp([west werr])

%  For comparison, the `true' vector as used in the simulation:

disp(w)

pause   	% Press any key to display the other parameter estimates.

clc

%  The estimated coefficient matrix:

disp(Aest)

%  with margins of error for its elements:

disp(Aerr)

%  For comparison, the `true' AR coefficients:

disp(A)

pause   	% Press any key to continue.

echo off
%  Compute `true' eigenmodes from model parameters:
%  Eigenvectors and eigenvalues of corresponding AR(1) coefficient
%  matrix:
[Strue,EvTrue] = eig([A; eye(2) zeros(2)]);
EvTrue         = diag(EvTrue)';   % `true' eigenvalues
Strue          = adjph(Strue);    % adjust phase of eigenmodes

clc
echo on

%  Finally, ARMODE computes the eigendecomposition of the fitted AR
%  model:

[S, Serr, per, tau, exctn] = armode(Aest, Cest, th);

%  The columns of S are the estimated eigenmodes:

disp(S)

%  with margins of error Serr:

disp(Serr)

%  The intervals (S +/- Serr) are approximate 95% confidence intervals
%  for the individual components of the eigenmodes.  Compare the
%  estimated eigenmodes above with the eigenmodes obtained from the
%  `true' model parameters:

disp(Strue(3:4,:))

%  (Note that the estimated modes can be a permutation of the `true'
%  modes. The sign of the modes is also ambiguous.)

pause   	% Press any key to continue.

echo off
pertrue = 2*pi./abs(angle(EvTrue)); % `true' periods

clc

echo on
%  Associated with the eigenmodes are the following oscillation periods:

disp(per)

%  The second row contains margins of error for the periods such that
%  (per(1,k) +/- per(2,k)) is an approximate 95% confidence interval
%  for the period of eigenmode S(:,k). [Note that for a purely
%  relaxatory eigenmode, the period is infinite (Inf).] Compare the
%  above estimated periods with the `true' periods:

disp(pertrue)

pause   	% Press any key to get the damping time scales.

echo off
tautrue = -1./log(abs(EvTrue)); % `true' damping time scales

clc

echo on

%  The damping times associated with each eigenmode are:

disp(tau)

%  with margins of error again in the second row. For comparison, the
%  `true' damping times:

disp(tautrue)

pause   	% Press any key to get the excitation of each eigenmode.
echo off
%  Compute `true' excitation of eigenmodes from the designed parameters:
p  = 2;              % true model order

invStr = inv(Strue); % inverse of matrix with eigenvectors as columns

% covariance matrix of corresponding decoupled AR(1) system
CovDcpld = invStr*[C zeros(2,(p-1)*2); zeros((p-1)*2, p*2)]*invStr';

% diagonal of that covariance matrix
DgCovDcpld = real(diag(CovDcpld))';

% excitation
TrueExctn = DgCovDcpld(1:2*p)./(1-abs(EvTrue).^2);

% normalize excitation
TrueExctn = TrueExctn./sum(TrueExctn);

clc

echo on
%  ARMODE has also returned the excitations, measures of the relative
%  dynamical importance of the eigenmodes:

disp(exctn)

%  Compare the estimated excitations with the `true' excitations
%  computed from the parameters used in the simulation:

disp(TrueExctn)

echo off
disp('End')


% StackExchange Signal Processing Q76344
% https://dsp.stackexchange.com/questions/76344
% Generate the Matrix Form of 1D Convolution Kernel
% References:
%   1.
% Remarks:
%   1.  B
% TODO:
% 	1.  C
% Release Notes
% - 1.0.000     19/07/2021
%   *   First release.

%% General Parameters

subStreamNumberDefault = 79;

run('InitScript.m');

figureIdx           = 0;
figureCounterSpec   = '%04d';

generateFigures = ON;

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

%% Simulation Parameters

vK              = [1; 4; 6; 4; 1] / 16; %<! Regularization
numSamples      = 50;
vConvShape      = [1; 2; 3];
cConvShapeStr   = {['Full'], ['Same'], ['Valid']};

%% Generate Data

cConvMtx = cell(3, 1);

for ii = 1:length(vConvShape)
    cConvMtx{ii} = CreateConvMtx1D(vK, numSamples, vConvShape(ii));
end

%% Display Results

figureIdx = figureIdx + 1;

hFigure     = figure('Position', [100, 100, 1200, 600]);
for ii = 1:length(vConvShape)
    hAxes       = subplot(1, 3, ii);
    hScatterObj = ScatterSparse(cConvMtx{ii}, 'fill');
    set(hAxes, 'YDir', 'reverse');
    set(hAxes, 'DataAspectRatio', [1, 1, 1]);
    set(hAxes, 'YLim', [0, numSamples + size(vK, 1) - 1]);
    % set(hLineObj, 'LineWidth', lineWidthNormal);
    set(get(hAxes, 'Title'), 'String', {['Convolution Type: ', cConvShapeStr{ii}]}, ...
        'FontSize', fontSizeTitle);
    % set(get(hAxes, 'XLabel'), 'String', {['Sample Index']}, ...
    %     'FontSize', fontSizeAxis);
    % set(get(hAxes, 'YLabel'), 'String', {['Sample Value']}, ...
    %     'FontSize', fontSizeAxis);
    % hLegend = ClickableLegend({['Ground Truth Signal'], ['Measured Signal']});
end

if(generateFigures == ON)
    % saveas(hFigure, ['Figure', num2str(figureIdx, figureCounterSpec), '.png']);
    print(hFigure, ['Figure', num2str(figureIdx, figureCounterSpec), '.png'], '-dpng', '-r0'); %<! Saves as Screen Resolution
end

%% Restore Defaults

% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);


function cycle_floyd_test03 ( )

%*****************************************************************************80
%
%% CYCLE_FLOYD_TEST03 tests CYCLE_FLOYD for F3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 June 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CYCLE_FLOYD_TEST03\n' );
  fprintf ( 1, '  Test CYCLE_FLOYD for F3().\n' );
  fprintf ( 1, '  f3(i) = mod ( 123 * i + 456, 100000 ).\n' );

  x0 = 789;
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Starting argument X0 = %d\n', x0 );

  [ lam, mu ] = cycle_floyd ( @f3, x0 );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Reported cycle length is %d\n', lam );
  fprintf ( 1, '  Expected value is 50000\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Reported distance to first cycle element is %d\n', mu );
  fprintf ( 1, '  Expected value is 0\n' );

  return
end


% function allAcc = LRSearchLambdaSGD(Xtrain, Ytrain, Xvalidation, Yvalidation, lambdas)
% For each value of lambda provided, fit parameters to the training data and return
% the accuracy in the validation data in the corresponding entry of allAcc.
% For instance, allAcc(i) = accuracy in the validation set using lambdas(i).
%
% Inputs:
% Xtrain        training data features   (numTrainInstances x numFeatures)
% Ytrain        training set labels      (numTrainInstances x 1)
% Xvalidation   validation data features (numValidInstances x num features)
% Yvalidation   validation set labels    (numValidInstances x 1)
% lambdas       values of lambda to try  (numLambdas x 1)
%
% Output:
% allAcc        vector of accuracies in validation set  (numLambdas x 1)
%
% Copyright (C) Daphne Koller, Stanford Univerity, 2012

function allAcc = LRSearchLambdaSGD(Xtrain, Ytrain, Xvalidation, Yvalidation, lambdas)

  % You may use the functions we have provided such as LRTrainSGD, LRPredict, and LRAccuracy.

  allAcc = zeros(size(lambdas));

  %%%%%%%%%%%%%%
  %%% Student code
 for i = 1: length(lambdas)
	 theta = LRTrainSGD(Xtrain,Ytrain,lambdas(i));
	 pred = LRPredict(Xvalidation,theta);
	 allAcc(i) = LRAccuracy(pred,Yvalidation);
 end

  %%%%%%%%%%%

end


function [signature] = getAertsSign_DICOMconvention(vol,mask,spatialRef,scanType)

% PARAMETERS
if strcmp(scanType,'CT')
    res = [1,1,3]; % In (Aerts,2014), all features were calculated from 1 X 1 X 3 mm^3 raw images
    levels = 0:25:3000; % Division of quantized bins in (Aerts,2014) for texture analysis
elseif strcmp(scanType,'PET') % Novelty tested in this work
    levels = 0:1:100; % Division of quantized bins for texture analysis, similarly to (Aerts,2014)
    res = [4,4,4]; % Resolution is here set up to the approximate resolution of PET scans
end

% INITIALIZATION
signature = zeros(1,4);
nLevels = numel(levels) - 1;

% STEP 0: RESAMPLING OF VOLUME AND MASK
pixelW = spatialRef.PixelExtentInWorldX;
sliceS = spatialRef.PixelExtentInWorldZ;
a = pixelW/res(1); b = pixelW/res(2); c = sliceS/res(3);
maskBox = imresize3D(mask,[],[round(double(size(mask,1))*a),round(double(size(mask,2))*b),round(double(size(mask,3))*c)],'nearest','fill');
ROIbox = imresize3D(vol,[],[round(double(size(vol,1))*a),round(double(size(vol,2))*b),round(double(size(vol,3))*c)],'cubic','fill');
ROIonly = ROIbox; ROIonly(~maskBox) = NaN;

% STEP 1: CALCULATE FEATURE 1
energy = ROIonly .^2; energy = sum(energy(~isnan(energy)));
signature(1) = energy;

% STEP 2: CALCULATE FEATURE 2
maskArea = imfill(maskBox,'holes'); maskArea = padarray(maskArea,[1,1,1],0); % Not using inner surfaces
volume = sum(maskBox(:)) * prod(res); % In mm^3
[p,q,r] = meshgrid(res(1).*(1:1:size(maskArea,2)),res(2).*(1:1:size(maskArea,1)),res(3).*(1:1:size(maskArea,3)));
[faces,vertices] = isosurface(p,q,r,maskArea,.5);
a = vertices(faces(:,2),:) - vertices(faces(:,1),:);
b = vertices(faces(:,3),:) - vertices(faces(:,1),:);
c = cross(a,b,2);
surface = 1/2 * sum(sqrt(sum(c.^2,2)));
compactness = volume/(sqrt(pi)*surface^(2/3));
signature(2) = compactness;

% STEP 3: CALCULATE FEATURE 3
ROIquant = ROIonly;
ROIquant(ROIonly < levels(1)) = 1;
for n = 1:nLevels
    ROIquant(ROIonly>=levels(n) & ROIonly<levels(n+1)) = n;
end
ROIquant(ROIonly >= levels(end)) = nLevels;
newLevels = 1:max(ROIquant(~isnan(ROIquant)));
[GLN] = getGLN_Aerts(ROIquant,newLevels);
signature(3) = GLN;

% STEP 4: CALCULATE FEATURE 4 (HLH --> 1) H: DICOM = left-right, Axial image = left-right; 2) L: DICOM = anterior posterior, Axial image = top-bottom; 3) H: DICOM = superior-inferior, Axial image = 3rd dimension)
% - DICOM XYZ coordinates are assumed in HLH feature definition of (Aerts et al, 2014)
% - From the swt2 function, we have in DICOM XYZ coordinates: [LL,LH,HL,HH] = swt2(image,N,'wavName')
sizeV = size(ROIbox);
if mod(sizeV(1),2)
    sizeV(1) = sizeV(1) + 1;
end
if mod(sizeV(2),2)
    sizeV(2) = sizeV(2) + 1;
end
if mod(sizeV(3),2)
    sizeV(3) = sizeV(3) + 1;
end
HLH = zeros(sizeV);
maskBox = imresize3D(maskBox,[],sizeV,'nearest','fill'); % Making sure the dimensions are even for decomposition at level 1
ROIbox = imresize3D(ROIbox,[],sizeV,'cubic','fill');
for k = 1:sizeV(3) % In this image plane (axial), we need the HL sub-band
    image = ROIbox(:,:,k);
    [~,~,HL,~] = swt2(image,1,'coif1');
    HLH(:,:,k) = HLH(:,:,k) + HL;
end
for i = 1:sizeV(1) % In this image plane (coronal), we need the HH sub-band
    image = squeeze(ROIbox(i,:,:))';
    [~,~,~,HH] = swt2(image,1,'coif1');
    for k = 1:sizeV(3)
        HLH(i,:,k) = HLH(i,:,k) + HH(k,:);
    end
end
for j = 1:sizeV(2) % In this image plane (sagittal), we need the HL sub-band
    image = squeeze(ROIbox(:,j,:));
    [~,~,HL,~] = swt2(image,1,'coif1');
    for k = 1:sizeV(3)
        HLH(:,j,k) = HLH(:,j,k) + HL(:,k);
    end
end
HLH = HLH/3;

ROIquant = HLH; ROIquant(~maskBox) = NaN;
Ng = numel(newLevels); [ROIquant,levels] = uniformQuantization(ROIquant,Ng);
[GLN] = getGLN_Aerts(ROIquant,levels);
signature(4) = GLN;

end


function pdf = english_word_length_pdf ( x )

%*****************************************************************************80
%
%% ENGLISH_WORD_LENGTH_PDF evaluates the English Word Length PDF.
%
%  Discussion:
%
%    PDF(A,B;X) = B(X) if 1 <= X <= A
%                = 0    otherwise
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 July 2006
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Henry Kucera, Winthrop Francis,
%    Computational Analysis of Present-Day American English,
%    Brown University Press, 1967.
%
%  Parameters:
%
%    Input, integer X, the word length whose probability is desired.
%
%    Output, real PDF, the value of the PDF.
%
  word_length_max = 27;

  pdf_vec = [ ...
    0.03160, ...
    0.16975, ...
    0.21192, ...
    0.15678, ...
    0.10852, ...
    0.08524, ...
    0.07724, ...
    0.05623, ...
    0.04032, ...
    0.02766, ...
    0.01582, ...
    0.00917, ...
    0.00483, ...
    0.00262, ...
    0.00099, ...
    0.00050, ...
    0.00027, ...
    0.00022, ...
    0.00011, ...
    0.00006, ...
    0.00005, ...
    0.00002, ...
    0.00001, ...
    0.00001, ...
    0.00001, ...
    0.00001, ...
    0.00001 ];
  pdf_sum = 0.99997;

  if ( 1 <= x & x <= word_length_max )
    pdf = pdf_vec(x) / pdf_sum;
  else
    pdf = 0.0;
  end

  return
end


function [pf,f]=v_lpcar2pf(ar,np)
%V_LPCAR2PF Convert AR coefs to power spectrum PF=(AR,NP)
%
%  Inputs: ar(nf,n)     AR coefficients, one frame per row
%          np           Size of output spectrum is np+1 [n]
%
% Outputs: pf(nf,np+1)  Power spectrum from DC to Nyquist
%          f(1,np+1)    Normalized frequencies (0 to 0.5)
%
% For high speed make np equal to a power of 2

%      Copyright (C) Mike Brookes 1998-2014
%      Version: $Id: v_lpcar2pf.m 10865 2018-09-21 17:22:45Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[nf,p1]=size(ar);
if nargin<2
    if nargout
        np=p1-1;
    else
        np=128;
    end
end
pf=abs(v_rfft(ar.',2*np).').^(-2);
f=(0:np)/(2*np);
if ~nargout
        plot(f,pf.');
        xlabel('Normalized frequency f/f_s');
        ylabel('LPC Power Spectrum');
end


function hermite_cubic_test09 ( )

%*****************************************************************************80
%
%% HERMITE_CUBIC_TEST09 tests HERMITE_CUBIC_SPLINE_INTEGRATE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 February 2011
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'HERMITE_CUBIC_TEST09:\n' );
  fprintf ( 1, '  HERMITE_CUBIC_SPLINE_INTEGRATE integrates a Hermite\n' );
  fprintf ( 1, '  cubic spline from A to B.\n' );
%
%  Define the cubic spline.
%
  x1 = 0.0;
  x2 = 10.0;

  nn = 11;
  xn = linspace ( x1, x2, nn );
  [ fn, dn, sn, tn ] = cubic_value ( xn );

  n = 25;
  a = linspace ( 2.5, 2.5, n );
  b = linspace ( x1 - 1.0, x2 + 1.0, n );

  q = hermite_cubic_spline_integrate ( nn, xn, fn, dn, n, a, b );

  fprintf ( 1, '\n' );
  fprintf ( 1, '                                 Exact       Computed\n' );
  fprintf ( 1, '    I      A           B         Integral    Integral\n' );
  fprintf ( 1, '\n' );

  for i = 1 : n

    q_exact = cubic_integrate ( a(i), b(i) );

    fprintf ( 1, '  %3d  %10f  %10f  %10.6g  %10.6g\n', ...
      i, a(i), b(i), q_exact, q(i) );

  end

  return
end


function R = sw_han_converse(a, n_vals, eps)
% Compute the converse sum rate (at the symmetrical rate point) from Han's SW converse
% for the joint source distribution: [a 1/3*(1-a); 1/3*(1-a) 1/3*(1-a)].

% Input:
% a: parameter to define the joint source distribution, should be in range [0.25, 1)
% n_vals: a vector containing the blocklengths
% eps: target error probability
% Output:
% R: the rates for the blocklengths specified in n_vals.

    p = [a 1/3*(1-a); 1/3*(1-a) 1/3*(1-a)];                                 % Stores joint probabilities
    H = sum(sum(p.*log(1./p)));                                             % Joint entropy
    b = [a/(a+1/3*(1-a)) 1/3*(1-a)/(2*1/3*(1-a)) 1/3*(1-a)/(a+1/3*(1-a))];  % Stores conditional probabilities

    % Compute log binomial coefficients
    log_b = binomial_coeff(max(n_vals));

    R = zeros(length(n_vals),1);

    for i = 1:length(n_vals)
        n = n_vals(i);
        m = 0:n;
        log_Pr = m*log(a)+(n-m)*log(1/3*(1-a));

        % Search the range of gamma specified in r_vals
        % The range of r_vals could be set smaller for large n to save computation time.
        if n <= 500
            r_vals = 0.0001:0.00005:2;
        else
            r_vals = 0.0001:0.00005:0.1;
        end

        R_r = zeros(1,length(r_vals));
        for ri = 1:length(r_vals)
            r = r_vals(ri);
            x = 0;
            y = H + 0.1;

            %%%%%%%%%% Use this part to check if the range is valid for bisection algorithm %%%%%%%%%%
            c = x;
            m0 = max(0, floor(n*(log(1/3*(1-a))+c+r)/log(1/3*(1-a)/a)));
            if m0 >= n
                err = 1 - 3*exp(-n*r);
            else
                log_err_m1 = my_logsumexp(log_Pr(1:m0+1)+log_b{n+1}(1:m0+1)+(n-(0:m0))*log(3));
                log_err_m2 = [];
                for m = m0+1:n
                    B_m = ceil((m*log(b(1))+(n-m)*log(b(2))+n*(c/2+r))/(log(b(2)/b(3))));
                    if B_m <= 0
                        C_m = log_Pr(m+1) + log_b{n+1}(m+1) + (n-m)*log(3);
                        log_err_m2 = [log_err_m2 C_m];
                    elseif B_m <= n-m
                        C_m1 = my_logsumexp(log_b{n-m+1}(B_m+1:n-m+1)+(n-m-(B_m:n-m))*log(2));
                        log_err_k = [];
                        for k = 0:B_m-1
                            if B_m <= n-m-k
                                D_m = log_b{n-m+1}(k+1) + my_logsumexp(log_b{n-m-k+1}(B_m+1:n-m-k+1));
                                log_err_k = [log_err_k D_m];
                            end
                        end
                        C_m2 = my_logsumexp(log_err_k);
                        C_m = log_Pr(m+1) + log_b{n+1}(m+1) + my_logsumexp([C_m1 C_m2]);
                        log_err_m2 = [log_err_m2 C_m];
                    end
                end
                log_err = my_logsumexp([log_err_m1 log_err_m2]);
                err = exp(log_err) - 3*exp(-n*r);
            end
            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

            % Start of bisection iteration
            iter = 0;
            while abs(x - y) >= 0.00001 && iter <= 30
                c = (x+y)/2;
                %%%%%%%%%%%%%%%%%%% body of iteration %%%%%%%%%%%%%%%%%%%%
                m0 = max(0, floor(n*(log(1/3*(1-a))+c+r)/log(1/3*(1-a)/a)));
                if m0 >= n
                    err = 1 - 3*exp(-n*r);
                else
                    log_err_m1 = my_logsumexp(log_Pr(1:m0+1)+log_b{n+1}(1:m0+1)+(n-(0:m0))*log(3));
                    log_err_m2 = [];
                    for m = m0+1:n
                        B_m = ceil((m*log(b(1))+(n-m)*log(b(2))+n*(c/2+r))/(log(b(2)/b(3))));
                        if B_m <= 0
                            C_m = log_Pr(m+1) + log_b{n+1}(m+1) + (n-m)*log(3);
                            log_err_m2 = [log_err_m2 C_m];
                        elseif B_m <= n-m
                            C_m1 = my_logsumexp(log_b{n-m+1}(B_m+1:n-m+1)+(n-m-(B_m:n-m))*log(2));
                            log_err_k = [];
                            for k = 0:B_m-1
                                if B_m <= n-m-k
                                    D_m = log_b{n-m+1}(k+1) + my_logsumexp(log_b{n-m-k+1}(B_m+1:n-m-k+1));
                                    log_err_k = [log_err_k D_m];
                                end
                            end
                            C_m2 = my_logsumexp(log_err_k);
                            C_m = log_Pr(m+1) + log_b{n+1}(m+1) + my_logsumexp([C_m1 C_m2]);
                            log_err_m2 = [log_err_m2 C_m];
                        end
                    end
                    log_err = my_logsumexp([log_err_m1 log_err_m2]);
                    err = exp(log_err) - 3*exp(-n*r);
                end
                %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                if err - eps < 0
                    y = c;
                else
                    x = c;
                end
                iter = iter + 1;
            end
            R_r(ri) = c;
        end
        % Optimize with respect to gamma
        R(i) = max(R_r);
    end
end


function rpy = quat2elu(qw, qx, qy, qz)

sinr_cosp = 2 * qw .* qx + qy .* qz;
cosr_cosp = 1 - 2 * qx .* qx + qy .* qy;
roll = atan2(sinr_cosp, cosr_cosp);

sinp = 2 * (qw .* qy - qz .* qx);
% remove out of range
sinp(sinp > 1) = 1;
sinp(sinp < -1) = -1;

pitch = asin(sinp);

siny_cosp = 2 * (qw .* qz + qx .* qy);
cosy_cosp = 1 - 2 * (qy .* qy + qz .* qz);
yaw = atan2(siny_cosp, cosy_cosp);

rpy = [roll, pitch, yaw];


% Y = HealpixNestedInvLinearTrans(X, A, m)
%
% Description
% This function calculates Y = WX where
% W = kron( eye(12), W_0 * W_1 * W_2 * ... * W_{m-2} * W_{m-1} )
% W_i = kron( eye( 4^{m-i-1} ), V_i )
% V_i = kron( eye(4), diag([0 1 1 ... 1]) ) + kron( A, diag([1 0 0 ...0]) )
%
% Parameters
% X : input row-vector
% Y : output row-vector (same size as X)
% A : linear transform applied to the adjacent elements
% m : log4(length(X) / 12)

function Y = HealpixNestedInvLinearTrans(X, A, m)

for itr = (m - 1):(-1):0
    num_trans = 12 * 4^(m - itr - 1);
    interval = 4^itr;
    begin_idx = 1;
    %itr
    for trans = 0:(num_trans - 1)
        IDX = begin_idx + interval * [0:3];
        %IDX
        X(IDX) = A * X(IDX);
        begin_idx = begin_idx + 4 * interval;
    end
end

Y = X;


function [cost,source] = cs_results(px,py,pz,rho,u,param)

e=1e-6;

h     = param.h;
dim   = param.dim;
gamma = param.gamma;
A1x   = param.A1x;
A1y   = param.A1y;
A1z   = param.A1z;
A2    = param.A2;
A3    = param.A3;
a     = param.a;
c     = param.c;
F1    = param.F1;
F2    = param.F2;

n  = dim(1);
nx = dim(2);
ny = dim(3);
nz = dim(4);
nt = dim(5);
hx = h(1);
hy = h(2);
hz = h(3);
ht = h(4);

%compute p^2 and u^2

pxsq  = px.^2;
pysq  = py.^2;
pzsq  = pz.^2;
usq   = u.^2;

% inverse of rho
rhoinv  = 1./rho;
rhoinv2 = 1./(F2'*rho(:));

E=eye(n);
E(n,n)=e;
W1=kron(speye((nx-1)*ny*nz*nt),E);
W2=kron(speye((ny-1)*nx*nz*nt),E);
W3=kron(speye((nz-1)*nx*ny*nt),E);

% cost f
cost = (A1x*W1*pxsq(:)+A1y*W2*pysq(:)+A1z*W3*pzsq(:))'*(A2*rhoinv(:) + a(:))*hx*hy*hz*ht + usq(:)'*(A3*rhoinv2(:)+ c(:))*hx*hy*hz*ht*gamma;
source=usq(:)'*(A3*rhoinv2(:)+ c(:))*hx*hy*hz*ht;
end


function [yr] = s2yr(s)
% Convert time from seconds to Julian years (365.25 days).
% Chad Greene 2012
yr = s*3.168808781403e-8;


avg_odd = 3.93;
max_odd = 4.27;

p_margin = 0.04;
p_real = (1 / avg_odd) - p_margin; % pur estimate of the "true" probability

p_max = 1 / max_odd;

payoff = p_real * max_odd - 1;

if payoff > 0
    msg = sprintf('Payoff = %2.2f. Place bet', payoff);
    disp(msg)
else
    msg = sprintf('Payoff = %2.2f. Do not Place bet', payoff);
    disp(msg)
end


function [kJ] = kWh2kJ(kWh)
% Convert energy or work from kilowatt-hours to kilojoules.
% Chad A. Greene 2012
kJ = kWh*3600;


function bpsksys(bin,f)

disp('========================================');
disp(' HAM DIEU CHE DICH 2 PHA: BPSK');
disp(' VI DU:bpsksys([0 1 0 1 1 0 1 1 0],3)');
disp('Written by Nguyen Hoang Minh DHCNTPHCM. he..he..');
disp('========================================');

bin=[0 1 0 1 1 0 1 1 1 0];f=3;k=1000;

t=0:2*pi/(k-1):2*pi;

L = length(bin);sig0=cos(f*t);sig1=cos(f*t+pi);
bit1=ones(1,k);bit0=zeros(1,k);
mbit=[];mcw=[];

for n=1:L;
    if bin(n)==0;
       cw=sig0;bit=bit0;
    else
       cw=sig1;bit=bit1;
    end
   mbit=[mbit bit];
   mcw=[mcw cw];
end
psk=mcw;
%================================================
s=length(mcw);mrec=[];

for m=0:k:s
    if mcw(m)<0
       rec=bit1;
    elseif mcw(m)>0
       rec=bit0;
    end
    mrec=[mrec rec];
end
depsk=mrec;
subplot(3,1,1);plot(mbit,'r','linewidth',2);axis([0  k*L -0.5 1.5]);grid on;title('Data in');
subplot(3,1,2);plot(psk,'m','linewidth',1.5);axis([0  k*L -1.5 1.5]);grid on;title('PSK modulation');
subplot(3,1,3);plot(depsk,'g','linewidth',2);axis([0  k*L -.5 1.5]);grid on;title('PSK demodulation,Data out');


%
% Bayesian Optimization of Combinatorial Structures
%
% Copyright (C) 2018 R. Baptista & M. Poloczek
%
% BOCS 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.
%
% BOCS 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 BOCS.  If not, see <http://www.gnu.org/licenses/>.
%
% Copyright (C) 2018 MIT & University of Arizona
% Authors: Ricardo Baptista & Matthias Poloczek
% E-mails: rsb@mit.edu & poloczek@email.arizona.edu
%

% Script runs discrete optimization algorithms for the
% binary quadratic programming problem. The results are
% compared for different values of the \lambda tuning
% parameter.

clear; close all; clc
addpath(genpath('../algorithms'))
addpath(genpath('../stat_model'))
addpath(genpath('../test_problems/Quadratic'))
addpath(genpath('../tools'))

%% Setup parameters

% Setup fixed parameters
n_vars  = 10;
n_proc  = 1;
test_name = 'quad';

% Number of runs and optimization iterations
n_func     = 50;
n_runs     = 10;
n_init     = 20;
evalBudget = 120;

% problem parameters (Monte Carlo samples)
alpha_vect = logspace(0,2,3);

% Variance prior parameters (Inverse Gamma)
aPr    = 2;
bPr    = 1;

% Regularization parameters
lambda_vals = [0, 1e-4, 1e-2, 1];
lambda_str  = {'0', '1em4', '1em2', '1'};

% Set additive regularization function
reg_term = @(x) sum(x,2);

%% Generate Test Cases

% setup objective functions
inputs_all = cell(n_func, length(alpha_vect), n_runs);

for a=1:length(alpha_vect)

    % compute decay function
    K = @(s,t) exp(-1*(s-t)^2/alpha_vect(a));
    decay = zeros(n_vars,n_vars);

    for i=1:n_vars
        for j=1:n_vars
            decay(i,j) = K(i,j);
        end
    end

    for t1=1:n_func

        % Generate random quadratic model
        % apply exponential decay to Q
        Q = randn(n_vars, n_vars);
        Qa = Q.*decay;

        for t2=1:n_runs

            % Set inputs struct for each problem
            inputs_all{t1,a,t2} = struct;
            inputs_all{t1,a,t2}.n_vars      = n_vars;

            % Save other definitions
            inputs_all{t1,a,t2}.evalBudget  = evalBudget;
            inputs_all{t1,a,t2}.n_runs      = n_runs;
            inputs_all{t1,a,t2}.n_init      = n_init;
            inputs_all{t1,a,t2}.lambda_vals = lambda_vals;

            % Set priors for estimator
            inputs_all{t1,a,t2}.aPr         = aPr;
            inputs_all{t1,a,t2}.bPr         = bPr;

            % Setup true objective function
            inputs_all{t1,a,t2}.model = @(x) diag(x*Qa*x');

            % Save regularization term
            inputs_all{t1,a,t2}.reg_term = @(x) reg_term(x);

            % Generate initial samples for statistical models
            inputs_all{t1,a,t2}.x_vals = sample_models(n_init, n_vars);
            inputs_all{t1,a,t2}.y_vals = inputs_all{t1,a,t2}.model(inputs_all{t1,a,t2}.x_vals);

        end
    end
end

inputs_all = reshape(inputs_all, n_func*length(alpha_vect)*n_runs, 1);

% Make folder
mkdir(['../results/' test_name])

% Save test cases
save(['../results/' test_name '/all_tests'])

% Run cases
run_cases(inputs_all, lambda_vals, test_name, n_proc);

% -- END OF FILE --


%mg_cd  GMG preconditioner for convection-diffusion problem
%   IFISS scriptfile: DJS, HCE; 15 April 2005.
% Copyright (c) 2005 D.J. Silvester, H.C. Elman, A. Ramage

nc=log2(length(x)-1);
%
% compute new MG data or reload existing data?
compute_mg = default('compute / load MG data? 1/2 (default 1)',1);
if compute_mg==2
   load mgdata_cd
else
   h=2^(1-nc);
   fprintf('Setting up MG data ...')
   % top level
   mgdata(nc).matrix=Asupg;
   mgdata(nc).prolong=mg_prolong(2^nc,2^nc,x,y);
   xn=x(1:2:end);yn=y(1:2:end);
   % loop over remaining levels
   for level = nc-1:-1:2;
      mgdata(level).matrix=mg_cd_setup(xn,yn,viscosity,outbc);
      mgdata(level).prolong=mg_prolong(2^level,2^level,xn,yn);
      xn=xn(1:2:end);yn=yn(1:2:end);
   end
   fprintf('done\n')
   gohome, cd datafiles, save mgdata_cd mgdata
end
%
% MG parameters
smooth = default('Jacobi / Gauss-Seidel / ILU smoother? 1/2/3 (default is Gauss-Seidel)',2);
if smooth==3 % point ILU
   sweeps=1;stype=1;
elseif smooth==2 % Gauss-Seidel
   stype = default('point / line Gauss-Seidel? 1/2 (default is line)',2);
   if stype==2
      sweeps = default('number of Gauss-Seidel directions? 1/2/3/4 (default is 2)',2);
   else
      sweeps=1;
   end
else % point Jacobi
   sweeps=1;stype=1;
end
npre = default('number of pre-smoothing steps? (default is 1)',1);
npost = default('number of post-smoothing steps? (default is 1)',1);
%
% construct smoother
smooth_data = mg_smooth(mgdata,nc,sweeps,smooth,stype);


function [ET_table,EV_table,ETV_index]=edge_tangents_double(V,Ne)
% Edge tangents table
ET_table=zeros(size(V,1)*4,3);
% Edge velocity table
EV_table=zeros(size(V,1)*4,1);
% Edge tangents/velocity index for tables
ETV_index=zeros(size(V,1)*4,2);
ETV_num=0;

% Calculate the tangents and velocity for each edge
Pn=zeros(length(Ne),3); Pnop=zeros(length(Ne),3);
for i=1:size(V,1)
    P=V(i,:);
    Pneig=Ne{i};

    % Find the opposite vertex of each neigbourh vertex.
    % incase of odd number of neigbourhs interpolate the opposite neigbourh
    if(mod(length(Pneig),2)==0)
       for k=1:length(Pneig)
            neg=k+length(Pneig)/2; if(neg>length(Pneig)), neg=neg-length(Pneig); end
            Pn(k,:) = V(Pneig(k),:); Pnop(k,:) = V(Pneig(neg),:);
       end
    else
       for k=1:length(Pneig)
           neg=k+length(Pneig)/2; neg1=floor(neg); neg2=ceil(neg);
           if(neg1>length(Pneig)), neg1=neg1-length(Pneig); end
           if(neg2>length(Pneig)), neg2=neg2-length(Pneig); end
           Pn(k,:) = V(Pneig(k),:); Pnop(k,:) = (V(Pneig(neg1),:)+V(Pneig(neg2),:))/2;
       end
    end

    for j=1:length(Pneig);
        % Calculate length edges of face
        Ec=sqrt(sum((Pn(j,:)-P).^2))+1e-14;
        Eb=sqrt(sum((Pnop(j,:)-P).^2))+1e-14;
        Ea=sqrt(sum((Pn(j,:)-Pnop(j,:)).^2))+1e-14;

        % Calculate face surface area
        s = ((Ea+Eb+Ec)/2);
        h = (2/Ea)*sqrt(s*(s-Ea)*(s-Eb)*(s-Ec))+1e-14;
        x = (Ea^2-Eb^2+Ec^2)/(2*Ea);

        % 2D triangle coordinates
        % corx(1)=0;    cory(1)=0;
        % corx(2)=x;    cory(2)=h;
        % corx(3)=Ea;   cory(3)=0;
        % corx(4)=0;    cory(4)=0;

        % Calculate tangent of 2D triangle
        Np=[-h x]; Np=Np/(sqrt(sum(Np.^2))+1e-14);
        Ns=[h Ea-x]; Ns=Ns/(sqrt(sum(Ns.^2))+1e-14);
        Nb=Np+Ns;
        Tb=[Nb(2) -Nb(1)];

        % Back to 3D coordinates
        Pm=(Pn(j,:)*x+Pnop(j,:)*(Ea-x))/Ea;
        X3=(Pn(j,:)-Pnop(j,:))/Ea;
        Y3=(P-Pm)/h;

        % 2D tangent to 3D tangent
        Tb3D=(X3*Tb(1)+Y3*Tb(2));  Tb3D=Tb3D/(sqrt(sum(Tb3D.^2))+1e-14);

        % Edge Velocity
        Vv=0.5*(Ec+0.5*Ea);

        ETV_num=ETV_num+1;
        ETV_index(ETV_num,:)=[i Pneig(j)];
        ET_table(ETV_num,:)= Tb3D;
        EV_table(ETV_num)=Vv;
    end
end


function [ fea, out ] = ex_heattransfer1( varargin )
%EX_HEATTRANSFER1 2D ceramic strip with radiation and convection.
%
%   [ FEA, OUT ] = EX_HEATTRANSFER1( VARARGIN ) 2D heat transfer of a ceramic strip with
%   both radiation and convection on the top boundary.
%
%         _                q = h*(T_inf-T) + epsilon*sigma*(T_inf^4-T^4)
%         ^            +------------------+
%         |            |                  |
%         |            |                  |
%       0.01m  T=900C  |                  |  T=900C
%         |            |                  |
%         |            |                  |
%         v            +------------------+
%                           dt/dn = 0
%                      |<---- 0.02m ----->|
%
%   The ceramic has a thermal conductivity of 3 W/mC and the sides are fixed
%   at a temperature of 900C while the bottom boundary is insulated. The surrounding
%   temperature is 50C. The top boundary is exposed to both natural convection (with
%   a film coefficient h=50W/m^2K) and radiation (with emissivity epsilon=0.7
%   and the Stefan-Boltzmann 5.669e-8 W/m^2K^4). The solution is sought at three
%   points along the vertical symmetry line.
%
%   Reference:
%
%      [1] Holman, J. P., Heat Transfer, Fifth Edition, New York: McGraw-Hill,
%          1981, page 96, Example 3-8.
%
%   Accepts the following property/value pairs.
%
%       Input       Value/{Default}        Description
%       -----------------------------------------------------------------------------------
%       hmax        scalar {0.001}         Grid cell size
%       igrid       scalar {0}/1/2         Cell type (0=quadrilaterals, 1=triangles,
%       solver      string fenics/{}       Use FEniCS or default solver
%       ischeme     scalar {0}             Time stepping scheme (0 = stationary)
%       sfun        string {sflag1}        Finite element shape function
%       iplot       scalar {1}/0           Plot solution (=1)
%                                                                                .
%       Output      Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       fea         struct                 Problem definition struct
%       out         struct                 Output struct

% Copyright 2013-2022 Precise Simulation, Ltd.

cOptDef = { 'hmax',     0.001;
            'igrid',    0;
            'solver',   '';
            'ischeme',  0;
            'sfun',     'sflag1';
            'iplot',    1;
            'tol',      0.01;
            'fid',      1 };
[got,opt] = parseopt(cOptDef,varargin{:});
if( opt.ischeme==2 && ~got.tol )
  opt.tol = 0.05;
end

% Geometry definition.
gobj = gobj_rectangle( 0, 0.02, 0, 0.01 );
fea.geom.objects = { gobj };

% Grid generation.
switch opt.igrid
  case 0
    fea.grid = rectgrid( round(0.02/opt.hmax), round(0.01/opt.hmax), [0 0.02;0 0.01] );
  case 1
    fea.grid = gridgen( fea, 'hmax', opt.hmax, 'fid', opt.fid );
  case 2
    fea.grid = rectgrid( round(0.02/opt.hmax), round(0.01/opt.hmax), [0 0.02;0 0.01] );
    fea.grid = quad2tri( fea.grid, 1 );
end

% Problem definition.
fea.sdim  = { 'x', 'y' };             % Space coordinate name.
fea = addphys( fea, @heattransfer );  % Add heat transfer physics mode.
fea.phys.ht.sfun = { opt.sfun };      % Set shape function.

% Equation coefficients.
fea.phys.ht.eqn.coef{3,end} = 3;      % Thermal conductivity.

% Boundary conditions.
fea.phys.ht.bdr.sel = [3 1 4 1];
fea.phys.ht.bdr.coef{1,end}   = { [] 900+273 [] 900+273 };
fea.phys.ht.bdr.coef{4,end}{3}{2} = 50;
fea.phys.ht.bdr.coef{4,end}{3}{3} = 50+273;
fea.phys.ht.bdr.coef{4,end}{3}{4} = 0.7*5.669e-8;
fea.phys.ht.bdr.coef{4,end}{3}{5} = 50+273;

% Parse physics modes and problem struct.
fea = parsephys(fea);
fea = parseprob(fea);

% Compute solution.
if( strcmp(opt.solver,'fenics') )
  fea = fenics( fea, 'fid', opt.fid, ...
                'tstep', 0.1, 'tmax', 1, 'ischeme', opt.ischeme );
else
  if( opt.ischeme<=0 )
    fea.sol.u = solvestat( fea, 'fid', opt.fid, 'init', {'T0_ht'} );
  else
    [fea.sol.u,fea.sol.t] = solvetime( fea, 'fid', opt.fid, 'init', {'T0_ht'}, ...
                                       'tstep', 0.1, 'tmax', 1, 'ischeme', opt.ischeme );
  end
end

% Postprocessing.
if( opt.iplot>0 )
  postplot( fea, 'surfexpr', 'T', 'isoexpr', 'T' )
  title('Temperature, T')
end

% Error checking.
T2_sol = evalexpr( 'T', [0.01;0.01], fea );
T2_ref = 984;
T5_sol = evalexpr( 'T', [0.01;0.005], fea );
T5_ref = 1064;
T8_sol = evalexpr( 'T', [0.01;0], fea );
T8_ref = 1088;
out.err  = abs([T2_sol-T2_ref T5_sol-T5_ref T8_sol-T8_ref])./[T2_ref T5_ref T8_ref];
out.pass = all(out.err<opt.tol);

if( nargout==0 )
  clear fea out
end


% DEMOPTIMISEGP Shows that there is an optimum for the covariance function length scale.
% DESC shows that by varying the length scale an artificial data
% set has different likelihoods, yet there is an optimum for which
% the likelihood is maximised.

% COPYRIGHT : Neil D. Lawrence, 2006, 2008

% GP

randn('seed', 1e5);
rand('seed', 1e5);

fillColor = [0.7 0.7 0.7];
markerSize = 20;
markerWidth = 2;
markerType = 'k.';
lineWidth = 2;

x = linspace(-1, 1, 6)';
trueKern = kernCreate(x, {'rbf', 'white'});
kern.comp{2}.variance = 0.001;
K = kernCompute(trueKern, x);
y = gsamp(zeros(1, 6), K, 1)';

xtest = linspace(-1.5, 1.5, 200)';
kern = trueKern;

lengthScale = [0.05 0.1 0.25 0.5 1 2 4 8 16];
counter = 0;

figure(1)
p = plot(x, y, markerType);
set(p, 'markersize', markerSize, 'lineWidth', markerWidth);
set(gca, 'fontname', 'times')
set(gca, 'fontsize', 18)
set(gca, 'ylim', [-2 1])
set(gca, 'xlim', [-1.5 1.5])

zeroAxes(gca);
fileName = ['demOptimiseGp' num2str(counter)];
if exist('printDiagram') && printDiagram
  printPlot(fileName, '../tex/diagrams', '../html');
end
clf

void = semilogx(NaN, NaN, 'k.-');
set(gca, 'fontname', 'times')
set(gca, 'fontsize', 18)
set(gca, 'ylim', [-12 -4])
set(gca, 'xlim', [0.025 32])
grid on
ylabel('log-likelihood')
xlabel('length scale')
fileName = ['demOptimiseGp' num2str(counter) '0'];
if exist('printDiagram') && printDiagram
  printPlot(fileName, '../tex/diagrams', '../html');
end

clf

for i = 1:length(lengthScale)
  kern.comp{1}.inverseWidth = 1/(lengthScale(i)*lengthScale(i));
  K = kernCompute(kern, x);
  [invK, U] = pdinv(K);
  logDetK = logdet(K, U);
  ll(i) = -0.5*(logDetK + y'*invK*y + size(y, 1)*log(2*pi));
  llLogDet(i) = -.5*(logDetK+size(y, 1)*log(2*pi));
  llFit(i) = -.5*y'*invK*y;
  Kx = kernCompute(kern, x, xtest);
  ypredMean = Kx'*invK*y;
  ypredVar = kernDiagCompute(kern, xtest) - sum((Kx'*invK).*Kx', 2);

  counter = counter + 1;
  figure(counter)
  clf
  fill([xtest; xtest(end:-1:1)], ...
       [ypredMean; ypredMean(end:-1:1)] ...
         + 2*[ypredVar; -ypredVar], ...
       fillColor,'EdgeColor',fillColor)
  hold on;
  t = plot(xtest, ypredMean, 'k-');

  p = plot(x, y, markerType);
  set(p, 'markersize', markerSize, 'lineWidth', markerWidth);
  set(t, 'linewidth', lineWidth);
  set(gca, 'fontname', 'times')
  set(gca, 'fontsize', 18)
  set(gca, 'ylim', [-2 1])

  zeroAxes(gca);
  fileName = ['demOptimiseGp' num2str(counter)];
  if exist('printDiagram') && printDiagram
    printPlot(fileName, '../tex/diagrams', '../html');
  end

  counter = counter + 1;
  figure(counter)
  t = semilogx(lengthScale(1:i), ll(1:i), 'k.-');
  hold on
  t = [t; semilogx(lengthScale(1:i), llLogDet(1:i), 'k.:')];
  t = [t; semilogx(lengthScale(1:i), llFit(1:i), 'k.--')];
  set(t, 'markersize', markerSize, 'lineWidth', markerWidth);
  set(gca, 'fontname', 'times')
  set(gca, 'fontsize', 18)
  set(gca, 'ylim', [-15 5])
  set(gca, 'xlim', [0.025 32])
  grid on
  ylabel('log-likelihood')
  xlabel('length scale')
  fileName = ['demOptimiseGp' num2str(counter)];
  if exist('printDiagram') && printDiagram
    printPlot(fileName, '../tex/diagrams', '../html');
  end
end


function c = tapas_logrt_linear_whatworld_config
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Contains the configuration for the linear log-reaction time response model according to as
% developed with Louise Marshall and Sven Bestmann
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The Gaussian noise observation model assumes that responses have a Gaussian distribution around
% the inferred mean of the relevant state. The only parameter of the model is the noise variance
% (NOT standard deviation) zeta.
%
% --------------------------------------------------------------------------------------------------
% Copyright (C) 2014 Christoph Mathys, UZH & ETHZ
%
% This file is part of the HGF toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

% Config structure
c = struct;

% Model name
c.model = 'Linear log-reaction time for WhatWorld models';

% Sufficient statistics of Gaussian parameter priors
%
% Beta_0
c.be0mu = log(500);
c.be0sa = 4;

% Beta_1
c.be1mu = 0;
c.be1sa = 4;

% Beta_2
c.be2mu = 0;
c.be2sa = 4;

% Beta_3
c.be3mu = 0;
c.be3sa = 4;

% Zeta
c.logzemu = log(log(20));
c.logzesa = log(2);

% Gather prior settings in vectors
c.priormus = [
    c.be0mu,...
    c.be1mu,...
    c.be2mu,...
    c.be3mu,...
    c.logzemu,...
         ];

c.priorsas = [
    c.be0sa,...
    c.be1sa,...
    c.be2sa,...
    c.be3sa,...
    c.logzesa,...
         ];

% Model filehandle
c.obs_fun = @tapas_logrt_linear_whatworld;

% Handle to function that transforms observation parameters to their native space
% from the space they are estimated in
c.transp_obs_fun = @tapas_logrt_linear_whatworld_transp;

return;


%  Figure 7.65      Feedback Control of Dynamic Systems, 6e
%                        Franklin, Powell, Emami
% script to generate Fig. 7.65
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Robust Servo Example
% Example 7.36; Figure 7.65
clf;
F=[0 1; 0 -1];
G=[0;1];
H=[1 0];
J=[0];
omega=1;
a=[0 1 0 0;-omega*omega 0 1 0;0 0 0 1;0 0 0 -1];
b=[0;0;G];

% desired closed-loop poles
pc=[-1+sqrt(3)*j;-1-sqrt(3)*j;-sqrt(3)+j;-sqrt(3)-j];
k=place(a,b,pc);

% form controller matrices
k1=k(:,1:2);
ko=k(:,3:4);
ac=[0 1;-omega*omega 0];
bc=-[k(2);k(1)];;
cc=[1 0];
dc=[0];

% closed-loop system
acl=[F-G*ko G*cc;bc*H ac];
bcl=[0;0;-bc];
ccl=[H 0 0];
dcl=[0];
syscl=ss(acl,bcl,ccl,dcl);
pole(syscl)
tzero(syscl)

% blocking zeros
dcle=-1;
syse=ss(acl,bcl,ccl,dcle);
tzero(syse)

% Closed-loop response
t=0:.01:25;
r=sin(t);
y=lsim(syscl,r,t);

% blocking zeros from w to y
G1=[0;1;0;0];
sysclw=ss(acl,G1,ccl,dcl);
tzero(sysclw)

% closed-loop response from w to y
w=sin(t);
y=lsim(sysclw,w,t);
figure(1)
plot(t,y,t,w);
text(0.5,0.9,'w');
text(1.5,0.1,'y');
xlabel('Time (sec)');
ylabel('Disturbance, output');
title('Fig. 7.65 (a): Disturbance response');
nicegrid;

% control effort
cclu=[-ko cc];
dclu=[0];
sysclu=ss(acl,G1,cclu,dclu);
u=lsim(sysclu,w,t);
figure(2)
plot(t,u);
xlabel('Time (sec)');
ylabel('Control, u');
title('Fig. 7.65 (b): Control effort');
nicegrid;

% error signal
ccle=[-H 0 0];
dcle=[0];
syscle=ss(acl,G1,ccle,dcle);
e=lsim(syscle,w,t);
figure(3)
plot(t,e);
xlabel('Time (sec)');
ylabel('Error, e');
title('Fig. 7.65 (c): Tracking error signal')
nicegrid


function [ ft ] = gsp_translate_old(G, f, i)
%GSP_TRANSLATE Generalized translation of the signal f to the node i
%   Usage: ft = gsp_translate(G, f, i);
%
%   Input parameters
%       G   : Graph
%       f   : Signal (column)
%       i   : Indices of vertex (int)
%   Output parameters
%       ft  : translate signal
%
%   This function translate the column vector f onto the node i. If f*
%   is a matrix, the translation will be done to each column.
%
%

fhat=gsp_gft(G,f);
nt = size(f,2);

ft = sqrt(G.N)*gsp_igft(G,fhat .* ...
    repmat(transpose(G.U(i,:)),1,nt));

end


function err = test_factorize (A)
%TEST_FACTORIZE test the accuracy of the factorization object
%
% Example
%   test_factorize (A) ;    % where A is a square matrix (sparse or dense)
%
% See also test_all, factorize1, factorize, inverse, mldivide

% Copyright 2009, Timothy A. Davis, University of Florida

if (nargin < 1)
    A = rand (100) ;
end

[m n] = size (A) ;
err = 0 ;
if (min (m,n) > 0)
    anorm = norm (A,1) ;
else
    anorm = 1 ;
end

for nrhs = 1:3

    for bsparse = 0:1

        % fprintf ('n %4d nrhs %d bsparse %d : ', n, nrhs, bsparse) ;

        b = rand (m,nrhs) ;
        if (bsparse)
            b = sparse (b) ;
        end

        %-------------------------------------------------------------------
        % test backslash and related methods
        %-------------------------------------------------------------------

        % method 0:
        x = A\b ;           err = check_resid (err, anorm, A, x, b) ;

        % method 1:
        S = inverse (A) ;
        x = S*b ;           err = check_resid (err, anorm, A, x, b) ;

        % method 2:
        if (m == n)
            F = factorize1 (A) ;
            x = F\b ;       err = check_resid (err, anorm, A, x, b) ;
        end

        % method 3:
        if (m == n)
            S = inverse (F) ;
            x = S*b ;       err = check_resid (err, anorm, A, x, b) ;
        end

        % method 4:
        F = factorize (A) ;
        x = F\b ;           err = check_resid (err, anorm, A, x, b) ;

        % method 5:
        S = inverse (F) ;
        x = S*b ;           err = check_resid (err, anorm, A, x, b) ;

        % method 6:
        if (m == n)
            [L,U,p] = lu (A, 'vector') ;
            x = U \ (L \ (b (p,:))) ;
            err = check_resid (err, anorm, A, x, b) ;
        end

        % method 7 (ack!)
        if (m == n)
            S = inv (A) ;
        else
            S = pinv (full (A)) ;
            if (issparse (A))
                S = sparse (S) ;
            end
        end
        x = S*b ;           err = check_resid (err, anorm, A, x, b) ;

        %-------------------------------------------------------------------
        % test mtimes
        %-------------------------------------------------------------------

        S = inverse (F) ;
        d = rand (n,1) ;
        x = F*d ;
        y = A*d ;
        z = S\d ;
        e = max (norm (x-y,1), norm (x-z,1)) ;
        if (e > 0)
            error ('mtimes error') ;
        end

        if (m == n)
            F = factorize1 (A) ;
            S = inverse (F) ;
            d = rand (n,1) ;
            x = F*d ;
            y = A*d ;
            z = S\d ;
            e = max (norm (x-y,1), norm (x-z,1)) ;
            if (e > 0)
                error ('mtimes error') ;
            end
        end

        %-------------------------------------------------------------------
        % test slash and related methods
        %-------------------------------------------------------------------

        b = rand (nrhs,n) ;
        if (bsparse)
            b = sparse (b) ;
        end

        % method 0:
        x = b/A ;           err = check_resid (err, anorm, A, x, b, 1) ;

        % method 1:
        S = inverse (A) ;
        x = b*S ;           err = check_resid (err, anorm, A, x, b, 1) ;

        % method 2:
        if (m == n)
            F = factorize1 (A) ;
            x = b/F ;       err = check_resid (err, anorm, A, x, b, 1) ;
        end

        % method 3:
        if (m == n)
            S = inverse (F) ;
            x = b*S ;       err = check_resid (err, anorm, A, x, b, 1) ;
        end

        % method 4:
        F = factorize (A) ;
        x = b/F ;           err = check_resid (err, anorm, A, x, b, 1) ;

        % method 5:
        S = inverse (F) ;
        x = b*S ;           err = check_resid (err, anorm, A, x, b, 1) ;

        % method 6:
        if (m == n)
            [L,U,p] = lu (A, 'vector') ;
            x = (b / U) / L ; x (:,p) = x ;
            err = check_resid (err, anorm, A, x, b, 1) ;
        end

        % method 7 (ack!)
        if (m == n)
            S = inv (A) ;
        else
            S = pinv (full (A)) ;
            if (issparse (A))
                S = sparse (S) ;
            end
        end
        x = b*S ;           err = check_resid (err, anorm, A, x, b, 1) ;

        %-------------------------------------------------------------------
        % test double
        %-------------------------------------------------------------------

        Y = double (inverse (A)) ;
        if (m == n)
            Z = inv (A) ;
        else
            Z = pinv (full (A)) ;
        end
        e = norm (Y-Z,1) ;
        if (n > 0)
            e = e / norm (Z,1) ;
        end
        err = max (e, err) ;

        %-------------------------------------------------------------------
        % test subsref
        %-------------------------------------------------------------------

        F = factorize (A) ;
        Y = inverse (A) ;
        if (numel (A) > 1)
            if (F (end) ~= A (end))
                error ('factorization subsref error') ;
            end
            if (F.A (end) ~= A (end))
                error ('factorization subsref error') ;
            end
        end
        if (n > 0)
            if (F (1,1) ~= A (1,1))
                error ('factorization subsref error') ;
            end
            if (F.A (1,1) ~= A (1,1))
                error ('factorization subsref error') ;
            end
            e = abs (Y (1,1) - Z (1,1)) ;
            err = max (e,err) ;
            if (m > 1 && n > 1)
                e = norm (Y (1:2,1:2) - Z (1:2,1:2), 1) ;
                err = max (e,err) ;
            end
        end
        if (m > 3 && n > 1)
            if (any (F (2:end, 1:2) - A (2:end, 1:2)))
                error ('factorization subsref error') ;
            end
            if (any (F (2:4, :) - A (2:4, :)))
                error ('factorization subsref error') ;
            end
            if (any (F (:, 1:2) - A (:, 1:2)))
                error ('factorization subsref error') ;
            end
        end

        %-------------------------------------------------------------------
        % test update/downdate
        %-------------------------------------------------------------------

        if (F.kind == 6)
            w = rand (n,1) ;
            b = rand (n,1) ;
            % update
            G = F + w ;
            x = G\b ;       err = check_resid (err, anorm, A+w*w', x, b) ;
            % downdate
            G = G - w ;
            x = G\b ;       err = check_resid (err, anorm, A, x, b) ;
            clear G
        end

        %-------------------------------------------------------------------
        % test size
        %-------------------------------------------------------------------

        [m1 n1] = size (F) ;
        [m n] = size (A) ;
        if (m1 ~= m || n1 ~= n)
            error ('size error') ;
        end
        [m1 n1] = size (Y) ;
        if (m1 ~= n || n1 ~= m)
            error ('pinv size error') ;
        end
        if (size (Y,1) ~= n || size (Y,2) ~= m)
            error ('pinv size error') ;
        end
        if (size (F,1) ~= m || size (F,2) ~= n)
            error ('size error') ;
        end

        %-------------------------------------------------------------------
        % test mtimes
        %-------------------------------------------------------------------

        d = rand (1,m) ;
        x = d*F ;
        y = d*A ;
        z = d/Y ;
        e = max (norm (x-y,1), norm (x-z,1)) ;
        if (e > 0)
            error ('mtimes error') ;
        end

        if (m == n)
            F = factorize1 (A) ;
            Y = inverse (F) ;
            d = rand (1,m) ;
            x = d*F ;
            y = d*A ;
            z = d/Y ;
            e = max (norm (x-y,1), norm (x-z,1)) ;
            if (e > 0)
                error ('mtimes error') ;
            end
        end

        %-------------------------------------------------------------------
        % test inverse
        %-------------------------------------------------------------------

        Y = double (inverse (inverse (A))) ;
        e = norm (A-Y,1) ;
        if (e > 0)
            error ('inverse error') ;
        end

    end
end

fprintf ('.') ;

if (err > 1e-8)
    fprintf ('error: %8.3e\n', err) ;
    error ('error is too high!') ;
end

%---------------------------------------------------------------------------

function err = check_resid (err, anorm, A, x, b, transposed)
if (nargin < 6)
    transposed = 0 ;
end
[m n] = size (A) ;

if (transposed)
    if (m >= n)
        e = norm (A'*x'-b',1) / (anorm + norm (x,1)) ;
    else
        e = norm (A*(A'*x')-A*b',1) / (anorm + norm (x,1)) ;
    end
else
    if (m <= n)
        e = norm (A*x-b,1) / (anorm + norm (x,1)) ;
    else
        e = norm (A'*(A*x)-A'*b,1) / (anorm + norm (x,1)) ;
    end
end

if (min (m,n) > 1)
    if (issparse (A) && issparse (b))
        if (~issparse (x))
            error ('x must be sparse') ;
        end
    else
        if (issparse (x))
            error ('x must be full') ;
        end
    end
end
err = max (err, e) ;


%
% Precompute the rotation matrices to rotate the high-resolution kernels (500 directions)
%
% Parameters
% ----------
% lmax : unsigned int
%   Maximum spherical harmonics order to use for the rotation phase
%
function AMICO_PrecomputeRotationMatrices( lmax )
	if nargin < 1, lmax = 12; end
	global AMICO_data_path

	fprintf( '\n-> Precomputing rotation matrices for l_max=%d:\n', lmax );

	filename = fullfile(AMICO_data_path,sprintf('AUX_matrices__lmax=%d.mat',lmax) );
	if exist( filename, 'file' )
		fprintf( '   [ already computed ]\n' );
		return
	end

	TIME = tic();

	% load file with 500 directions
	grad500 = importdata( '500_dirs.txt' );
	for i = 1:size(grad500,1)
		grad500(i,:) = grad500(i,:) ./ norm( grad500(i,:) );
        if grad500(i,2) < 0
            grad500(i,:) = -grad500(i,:);
        end
	end

	% precompute the matrix to fit the SH coefficients
	[colatitude, longitude] = AMICO_Cart2sphere( grad500(:,1), grad500(:,2), grad500(:,3) );
	Ylm = AMICO_CreateYlm( lmax, colatitude, longitude );
	fit = pinv( Ylm'*Ylm ) * Ylm';

	% precompute the matrices to rotate the functions in SH space
	Ylm_rot = {};
	for ox = 0:180
	for oy = 0:180
		Ylm_rot{ox+1,oy+1} = AMICO_CreateYlm( lmax, ox/180.0*pi, oy/180.0*pi );
	end
	end

	save( filename , 'Ylm_rot', 'fit', 'lmax' );
	fprintf( '   [ %.1f seconds ]\n', toc(TIME) );
end


%KNNM Trainable K-Nearest Neighbour density estimation
%
%   W = KNNM(A,KNN)
%   W = A*KNNM([],KNN)
%   W = A*KNNM(KNN)
%
%   D = B*W
%
% INPUT
% 	A     Dataset used for training
%   B     Dataset used for evaluation
%   KNN   Number of nearest neighbours
%
% OUTPUT
%   W     Density estimate
%
% DESCRIPTION
% A density estimator is constructed based on the k-Nearest Neighbour rule
% using the objects in A. In case A is labeled, density estimates are
% performed classwise and combined by the class priors. The default KNN is
% the square root of the size of the class. The data is scaled by variance
% normalisation determined by the training set.
%
% The mapping W may be applied to a new dataset B using DENSITY = B*W.
%
% SEE ALSO (PRTools Guide)
% DATASETS, MAPPINGS, KNNC, PARZENM, GAUSSM

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

function w = knnm(varargin)

  mapname = 'KNN density estimation';
  argin = shiftargin(varargin,'scalar');
  argin = setdefaults(argin,[],[]);

  if mapping_task(argin,'definition')

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

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

		[a,knn] = deal(argin{:});
		if isa(a,'prdataset')
			labname = getname(a);
		else
			labname = '';
		end
		if (~isdataset(a) && ~isdatafile(a)) || getsize(a,3) ~= 1
			w = mclassm(a,prmapping(mfilename,knn),'weight');
			w = setlabels(w,labname);
			w = setname(w,mapname);
			return
		end
		islabtype(a,'crisp');
		isvaldfile(a,1);
		a = testdatasize(a,'objects');
		a = remclass(a);
		[m,k] = size(a);
    knn = setdefaults({knn},round(sqrt(m)));
		w = prmapping(mfilename,'trained',{a,knn},labname,k,1);
		w = setname(w,mapname);

	else															% Execute a trained mapping V.

    [a,v] = deal(argin{:});
    [b,knn] = getdata(v);
		[m,k] = size(b);
		u = scalem(b,'variance');
		a = a*u;
		b = b*u;
		d = sqrt(distm(+a,+b));					% Calculate squared distances
		s = sort(d,2);						    	% and find nearest neighbours.
		ss = s(:,knn);									% Find furthest neighbour
		ss(ss==0) = realmin.^(1/k);	    % Avoid zero distances
		f = knn./(m*nsphere(k)*(ss.^k));% Normalize by the volume of sphere
																		% defined by the furthest neighbour.
		f = f*prod(u.data.rot);         % Correct for scaling

		w = setdat(a,f,v);							% proper normalisation has still to be done.

	end

return

function v = nsphere(k)

	% Volume k-dimensional sphere
	v = (2*(pi^(k/2))) / (k*gamma(k/2));

return


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Example code for estimating the HRF using the Inverse-Logit Model, a
% Finte Impluse Response Model and the Canonical HRF with 2 derivatives.
% Also the code illustrates our code for detecting model misspecification.
%
% By Martin Lindquist and Tor Wager
% Created  10/02/09
% Last edited 05/20/13
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Load time course
%

mypath = which('ilogit');
if isempty(mypath), error('Cannot find directory with ilogit.m and other functions. Not on path?'); end
[mydir] = fileparts(mypath)

load(fullfile(mydir,'timecourse'))

tc = (tc- mean(tc))/std(tc);
len = length(tc);

%% Or: create your own
[xBF] = spm_get_bf(struct('dt', .5, 'name', 'hrf (with time and dispersion derivatives)', 'length', 32));
clear Xtrue
for i = 1:1, xx = conv(xBF.bf(:,i), [1 1 1 1 1 1 ]');
    Xtrue(:, i) = xx(1:66);
end
for i = 2:3, xx = conv(xBF.bf(:,i), [1 1]');
    Xtrue(:, i) = xx(1:66);
end
hrf = Xtrue * [1 .3 .2]';
xsecs = 0:.5:32;

hrf = [ 0; 0; hrf];
hrf = hrf(1:length(xsecs));
hrf = hrf ./ max(hrf);
figure; plot(xsecs, hrf, 'k')
%hrf = hrf(1:4:end); % downsample to TR, if TR is > 0.5

R = randperm(640); R = sort(R(1:36));
Run = zeros(640,1);
for i=1:length(R), Run(R(i)) = 1; end;
true_sig = conv(Run, hrf);
true_sig = true_sig(1:640);

tc_noise = noise_arp(640, [.3 0]);
tc = true_sig +  0.5 * tc_noise;
% tc = true_sig;
%figure; plot(tc);

Runc{1} = Run;

%%

create_figure; subplot(3,1,1); han = plot(tc);
title('Sample time course'); drawnow

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Settings
%

TR = 0.5;
%T = round(30/TR);
T = 30;
t = 1:TR:T;                        % samples at which to get Logit HRF Estimate
FWHM = 4;                       % FWHM for residual scan
pval = 0.01;
df = 600;
alpha = 0.001;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Create stick function (sample event onsets)
% Variable R contains onset times
% Variable Run contains stick (a.k.a. delta or indicator) function

% R = [3, 21, 56, 65, 109, 126, 163, 171, 216, 232, 269, 282, 323, 341, 376, 385, 429, 446, 483, 491, 536, 552, 589, 602];
% Run = zeros(640,1);
% for i=1:length(R), Run(R(i)) = 1; end;
%

try
    hold on;
    hh = plot_onsets(R,'k',-3,1, 1);
    drawnow
catch
    disp('Couldn''t find function to add onset sticks to plot. Skipping.')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fit HRF using IL-function

% Choose mode (deterministic/stochastic)

mode = 0;   % 0 - deterministic aproach
            % 1 - simulated annealing approach
            % Please note that when using simulated annealing approach you
            % may need to perform some tuning before use.

[h1, fit1, e1, param] = Fit_Logit2(tc,TR,Runc,T,mode);
[pv sres sres_ns1] = ResidScan(e1, FWHM);
[PowLoss1] = PowerLoss(e1, fit1, (len-7) , tc, TR, Runc, alpha);

hold on; han(2) = plot(fit1,'r');

disp('Summary: IL_function');

disp('Amplitude:'); disp(param(1));
disp('Time-to-peak:'); disp(param(2)*TR);
disp('Width:'); disp(param(3)*TR);

disp('MSE:'); disp((1/(len-1)*sum(e1.^2)));
disp('Mis-modeling:'); disp(pv);
disp('Power Loss:'); disp(PowLoss1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fit HRF using FIR-model

% Choose mode (FIR/sFIR)

mode = 1;   % 0 - FIR
            % 1 - smooth FIR

[h2, fit2, e2, param] = Fit_sFIR(tc,TR,Runc,T,mode);
[pv sres sres_ns2] = ResidScan(e2, FWHM);
[PowLoss2] = PowerLoss(e2, fit2, (len-T) , tc, TR, Runc, alpha);

hold on; han(3) = plot(fit2,'g');

disp('Summary: FIR');

disp('Amplitude'); disp(param(1));
disp('Time-to-peak'); disp(param(2)*TR);
disp('Width'); disp(param(3)*TR);

disp('MSE:'); disp((1/(len-1)*sum(e2.^2)));
disp('Mis-modeling'); disp(pv);
disp('Power Loss:'); disp(PowLoss2);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fit HRF using Canonical HRF + 2 derivatives

p=1;

[h3, fit3, e3, param, info] = Fit_Canonical_HRF(tc,TR,Runc,30,p);
[pv sres sres_ns3] = ResidScan(e3, FWHM);
[PowLoss3] = PowerLoss(e3, fit3, (len-p) , tc, TR, Runc, alpha);

hold on; han(4) = plot(fit3,'m');

legend(han,{'Data' 'IL' 'sFIR' 'DD'})

disp('Summary: Canonical + 2 derivatives');

disp('Amplitude'); disp(param(1));
disp('Time-to-peak'); disp(param(2)*TR);
disp('Width'); disp(param(3)*TR);

disp('MSE:'); disp((1/(len-1)*sum(e3.^2)));
disp('Mis-modeling'); disp(pv);
disp('Power Loss:'); disp(PowLoss3);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%figure;
%%

subplot(3,2,5); hold on;
plot(xsecs, hrf, 'k')
xsecs1 = xsecs(1:length(h1));
han2 = plot(xsecs1, h1,'r');
xsecs2 = xsecs(1:length(h2));
han2(2) = plot(xsecs2, h2,'g');
xsecs3 = xsecs(1:length(h3));
han2(3) = plot(xsecs3, h3,'m');
legend(han2,{'IL' 'sFIR' 'DD'})
title('Estimated HRF');

subplot(3,1,2); hold on;
hh = plot_onsets(R,'k',-3,1);
drawnow

han3 = plot(sres_ns1,'r');
hold on; han3(2) = plot(sres_ns2,'g');
hold on; han3(3) = plot(sres_ns3,'m');
hold on; plot((1:len),zeros(len,1),'--k');
legend(han3,{'IL' 'sFIR' 'DD'})
title('Mis-modeling (time course)');

subplot(3,2,6); hold on;

[s1] = Fit_sFIR(sres_ns1,TR,Runc,T,0);
[s2] = Fit_sFIR(sres_ns2,TR,Runc,T,0);
[s3] = Fit_sFIR(sres_ns3,TR,Runc,T,0);

han4 = plot(s1(1:T),'r');
hold on; han4(2) = plot(s2(1:T),'g');
hold on; han4(3) = plot(s3(1:T),'m');
hold on; plot((1:T),zeros(T,1),'--k');
legend(han4,{'IL' 'sFIR' 'DD'})
title('Mis-modeling (HRF)');


clear all
close all

disp('Temporal discounting model');

% Parameters for first level
Nobs=200;

[M,U] = mci_discount_struct (Nobs);

% Generate Data
%w_true = spm_normrnd(M.pE,M.pC,1);
w_true = [0.25, 1.5]';
w_true = log(w_true);
[g,Y] = mci_discount_gen (w_true,M,U);

[a,v1,v2,k] = mci_discount_act (w_true,M,U);

t=sort(U.t1);
r=mean(U.r1);
figure;plot(t,r./(1+k*t),'k.');
set(gca,'FontSize',16);
xlabel('Delay, Weeks');

t=sort(U.t2);
r=mean(U.r2);
hold on
plot(t,r./(1+k*t),'r.');
ylabel('Mean Reward, £');
grid on

disp(sprintf('Average prob of choosing first option = %1.2f',mean(g)));

%mcmc.inference='amc';
%mcmc.inference='vl';
mcmc.inference='langevin';

mcmc.verbose=0;
mcmc.maxits=1024;

post = spm_mci_post (mcmc,M,U,Y,w_true);
disp('Posterior Mean from MCI');
disp(post.Ep)

plot_post=1;
if plot_post
    % Plot posterior surface
    S.Nbins=50;
    r=2;
    S.pxy(1,:)=linspace(-r*w_true(1),r*w_true(1),S.Nbins);
    S.pxy(2,:)=linspace(-0.5*r*w_true(2),1.5*r*w_true(2),S.Nbins);
    S.param{1}='P(1)';
    S.param{2}='P(2)';
    S.name={'log k','log \beta'};
    [L,S] = mci_plot_surface (w_true,M,U,Y,S,'post');
    hold on
    ms=10;
    plot(M.pE(1),M.pE(2),'wo','MarkerSize',ms);
    plot(post.Ep(1),post.Ep(2),'wx','MarkerSize',ms);
    plot(w_true(1),w_true(2),'w+','MarkerSize',ms);
end

stats = spm_mci_mvnpost (post,'ESS')
stats = spm_mci_mvnpost (post,'thinning')


function [Q, V, policy, mean_discrepancy] = mdp_Q_learning(P, R, discount, N)

% mdp_Q_learning   Evaluation of the matrix Q, using the Q learning algorithm
%
% Arguments
% -------------------------------------------------------------------------
% Let S = number of states, A = number of actions
%   P(SxSxA)  = transition matrix
%              P could be an array with 3 dimensions or
%              a cell array (1xA), each cell containing a sparse matrix (SxS)
%   R(SxSxA) or (SxA) = reward matrix
%              R could be an array with 3 dimensions (SxSxA) or
%              a cell array (1xA), each cell containing a sparse matrix (SxS) or
%              a 2D array(SxA) possibly sparse
%   discount  = discount rate in ]0; 1[
%   N(optional) = number of iterations to execute, default value: 10000.
%                 It is an integer greater than the default value.
% Evaluation --------------------------------------------------------------
%   Q(SxA) = learned Q matrix
%   V(S)   = learned value function.
%   policy(S) = learned optimal policy.
%   mean_discrepancy(N/100) = vector of V discrepancy mean over 100 iterations
%             Then the length of this vector for the default value of N is 100.

% MDPtoolbox: Markov Decision Processes Toolbox
% Copyright (C) 2009  INRA
% Redistribution and use in source and binary forms, with or without modification,
% are permitted provided that the following conditions are met:
%    * Redistributions of source code must retain the above copyright notice,
%      this list of conditions and the following disclaimer.
%    * Redistributions in binary form must reproduce the above copyright notice,
%      this list of conditions and the following disclaimer in the documentation
%      and/or other materials provided with the distribution.
%    * Neither the name of the <ORGANIZATION> nor the names of its contributors
%      may be used to endorse or promote products derived from this software
%      without specific prior written permission.
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
% ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
% WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
% IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
% OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
% OF THE POSSIBILITY OF SUCH DAMAGE.

% check of arguments
if (discount <= 0 || discount >= 1)
    disp('--------------------------------------------------------')
    disp('MDP Toolbox ERROR: Discount rate must be in ]0,1[')
    disp('--------------------------------------------------------')
elseif (nargin >= 4) && (N < 10000)
    disp('--------------------------------------------------------')
    disp('MDP Toolbox ERROR: N must be upper than 10000')
    disp('--------------------------------------------------------')
else

    % initialization of optional arguments
    if (nargin < 4); N=10000; end;

    % Find number of states and actions
    if iscell(P)
        S = size(P{1},1);
        A = length(P);
    else
        S = size(P,1);
        A = size(P,3);
    end;

    % Initialisations
    Q = zeros(S,A);
    dQ = zeros(S,A);
    mean_discrepancy = [];
    discrepancy = [];

    % Initial state choice
    s = randi([1,S]);

    for n=1:N

        % Reinitialisation of trajectories every 100 transitions
        if (mod(n,100)==0); s = randi([1,S]); end;

        % Action choice : greedy with increasing probability
        % probability 1-(1/log(n+2)) can be changed
        pn = rand(1);
        if (pn < (1-(1/log(n+2))))
          [nil,a] = max(Q(s,:));
        else
          a = randi([1,A]);
        end;

        % Simulating next state s_new and reward associated to <s,s_new,a>
        p_s_new = rand(1);
        p = 0;
        s_new = 0;
        while ((p < p_s_new) && (s_new < S))
            s_new = s_new+1;
            if iscell(P)
                p = p + P{a}(s,s_new);
            else
                p = p + P(s,s_new,a);
            end;
        end;
        if iscell(R)
            r = R{a}(s,s_new);
        elseif ndims(R) == 3
            r = R(s,s_new,a);
        else
            r = R(s,a);
        end;

        % Updating the value of Q
        % Decaying update coefficient (1/sqrt(n+2)) can be changed
        delta = r + discount*max(Q(s_new,:)) - Q(s,a);
        dQ = (1/sqrt(n+2))*delta;
        Q(s,a) = Q(s,a) + dQ;

        % Current state is updated
        s = s_new;

        % Computing and saving maximal values of the Q variation
        discrepancy(mod(n,100)+1) = abs(dQ);

        % Computing means all over maximal Q variations values
        if (length(discrepancy) == 100)
           mean_discrepancy = [ mean_discrepancy mean(discrepancy)];
           discrepancy = [];
        end;

    end;

    %compute the value function and the policy
    [V, policy] = max(Q,[],2);

end;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%               successive approximation converter                 %
%            with finite DAC's slew-rate and bandwidth             %
%       code by Fabrizio Conso, university of pavia, student       %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [counter,thresholds]=Approx(input,nbit,f_bw,sr,f_s)
% input= input sample
% nbit=  number of converter bits
% f_bw=  DAC bandwidth [f_s]
% sr=    DAC slew-rate [V_fs/T_s]
% f_s=   sampling frequency

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                global variables                 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                 %
 threshold(1,nbit+1)=0;  % threshold array
 counter=0;              % converter decimal output
 threshold(1)=0.5;       % 0 threshold
 threshold(2)=0.5;       % first threshold
 threshold_id=0.5;       % next ideal threshold
 tau=1/(2*pi*f_bw);      % DAC output pole
 in=input;
 Tmax=1/(f_s*nbit);      % clock period
%                                                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 for i=2:(nbit+1)       % conversion cycle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                  finite  bandwidth & slew-rate                   %
%                       error calculation                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                  %
   deltaV=abs(threshold_id-threshold(i-1));
   slope=deltaV/tau;
   if slope > sr
        tslew=(deltaV/sr) - tau;
            if tslew >= Tmax              % only slewing
                error = deltaV - sr*Tmax;
            else
                texp = Tmax - tslew;
                error = (deltaV-sr*tslew)*exp(-texp/tau);
            end

   else			                % only exponential settling
	    texp = Tmax;
	    error = deltaV*exp(-texp/tau);
   end

   threshold(i) = threshold_id - sign(threshold_id-threshold(i-1))*error;
%                                                                   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%      successive approximation       %
%        conversion algorythm         %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                     %
    if (in-threshold(i)) > 0
        threshold_id=threshold_id+1/2^i;
        bit=1;
    else
        threshold_id=threshold_id-1/2^i;
        bit=0;
    end
 counter=(counter+bit*2^(nbit-i+1));
 thresholds(i-1)=threshold(i);
 end
%                                     %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%             Output             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                %
 counter=counter;
 if nargout > 1
	thresholds=thresholds;
 end
%                                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function [A]=rician_LMMSE_filter(M,S,k)

%Based on Aja-Fernandez et al. 2008. Restoration of DWI Data Using a Rician
%LMMSE Estimator

%%
% Sg=1;
pad_step=(k-1)/2;
% hg=gaussiankernel(2,k,Sg); %Equivalent to: hg = fspecial('gaussian',[k k], S);

% hg=gauss_kernel(k,nd,f,m);
% hg=gauss_kernel(k,2,Sg,'sigma');
hg=gauss_kernel(k,2,1.5,'width');

Mij2=M.^2; Mij4=M.^4;

%% Gaussian filtering M.^2

[Mij2_gauss]=padrep(Mij2,pad_step.*ones(1,3)); %Padding array
Mij2_gauss=convn(Mij2_gauss,hg,'same');
Mij2_gauss=Mij2_gauss(pad_step+1:(size(Mij2_gauss,1)-pad_step),pad_step+1:(size(Mij2_gauss,2)-pad_step),pad_step+1:(size(Mij2_gauss,3)-pad_step)); %Trimming back to normal size

%% Gaussian filtering M.^4

[Mij4_gauss]=padrep(Mij4,pad_step.*ones(1,3)); %Padding array
Mij4_gauss=convn(Mij4_gauss,hg,'same');
Mij4_gauss=Mij4_gauss(pad_step+1:(size(Mij4_gauss,1)-pad_step),pad_step+1:(size(Mij4_gauss,2)-pad_step),pad_step+1:(size(Mij4_gauss,3)-pad_step)); %Trimming back to normal size

%% Calculating K

Kij_nom=(4.*(S.^2)).*(Mij2_gauss-(S.^2));
Kij_denom=Mij4_gauss-(Mij2_gauss.^2);
L=Kij_denom~=0; %Logic index of non zero values
Kij=zeros(size(Kij_denom));
Kij(L)=1-(Kij_nom(L)./Kij_denom(L));
Kij(Kij<0)=0;

%% Calculating signal A

A2= Mij2_gauss-2.*(S.^2) + Kij.*(Mij2-Mij2_gauss) ;
A2(A2<0)=0; %Smaller then zero set to zero
A=sqrt(A2);

%% END

%%
% _*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 [Dict Coeff]=KSVD_Inpainting(Dict,blkMatrixIm,blkMask,sigma,rc_min,max_coeff,max_iter)
% Author: Chongyang
% Date: 2016/06/05
% KSVD for Inpainting
%
% sigma: residual error stopping criterion, normalized by signal norm  0.01
% rc_min: minimal residual correlation before stopping 0.01
% max_coeff: maximal number of non-zero coefficients for signal 10t

fprintf('KSVD begin .....\n')
tic
for KSVDiter=1:max_iter
    fprintf('iteration: %d/%d | time: %d \n',KSVDiter,max_iter,toc)
 	Coeff=OMP_Inpainting(Dict,blkMatrixIm.*blkMask,blkMask,sigma,rc_min,max_coeff); %256*146405
    for atom=1:1:size(Dict,2)
        Omega=find(abs(Coeff(atom,:))>0);
         % this atom will be useless
        if isempty(Omega)
            continue;
        end;
        CoeffM=Coeff;
        CoeffM(atom,:)=0;
        Err=blkMask(:,Omega).*(blkMatrixIm(:,Omega)-Dict*CoeffM(:,Omega));

        dd=diag(1./(blkMask(:,Omega)*(Coeff(atom,Omega).^2)'))*(Err*Coeff(atom,Omega)');
        Dict(:,atom)=dd/norm(dd);
        Coeff(atom,Omega)=(dd'*Err)./sum((blkMask(:,Omega).*(dd*ones(1,length(Omega)))).^2,1);

    end;
%     save Dict Dict;
%     save Coeff Coeff;
end;


function result = isVertexInRadius(vertex, origin, radius)

vt = vertex - origin;

result = ( ((vt(1)^2 + vt(2)^2) <= (radius^2)) & ...
            ((vt(2)^2 + vt(3)^2) <= (radius^2)) & ...
            ((vt(1)^2 + vt(3)^2) <= (radius^2)) );


% Lightspeed Toolbox.
% Efficient operations for Matlab programming.
% Version 2.8   04-Jan-2017
% By Tom Minka
%
% Matrix algebra
%   repmat           - Fast replacement for matlab's repmat.
%   xrepmat          - Matlab's original repmat.
%   setnonzeros      - Fast creation of sparse matrix.
%   row_sum          - Sum for each row.  Faster than 'sum'.
%   scale_rows       - Scale each row of a matrix.
%   scale_cols       - Scale each column of a matrix.
%   solve_triu       - Left division by upper triangular matrix.
%   solve_tril       - Left division by lower triangular matrix.
%   sqdist           - Squared Euclidean and Mahalanobis distance.
%   isposdef         - Check for positive-definiteness.
%   logdet           - log(determinant) for positive definite matrix.
%   cholproj         - Projected Cholesky factorization.
%   inv_posdef       - Invert positive definite matrix.
%
% Statistics
%   mvnormpdf        - Multivariate normal density.
%   mvnormpdfln      - Log of multivariate normal density.
%   normcdf          - Normal cumulative distribution.
%   normcdfln        - Log of normal cumulative distribution.
%   normcdflogit     - Logit of normal cumulative distribution.
%   invnormcdf       - Normal quantile function.
%   wishpdf          - Wishart probability density function.
%   wishpdfln        - Log of Wishart probability density function.
%   sample           - Sample from categorical distribution.
%   sample_vector    - Sample from multiple categorical distributions.
%   sample_hist      - Sample from multinomial distribution.
%   randbinom        - Sample from binomial distribution.
%   randnorm         - Sample from multivariate normal.
%   randgamma        - Sample from Gamma distribution.
%   randbeta         - Sample from Beta distribution.
%   randwishart      - Sample from Wishart distribution.
%   randomseed       - Get or set the random seed.
%   int_hist         - Histogram of integer values.
%
% Utility
%   logsumexp        - Sum in the log domain.
%   logmulexp        - Matrix multiply in the log domain.
%   ndgridmat        - Matrix of grid points.
%   ind2subv         - Subscript vector from linear index.
%   subv2ind         - Linear index from subscript vector.
%   gammaln          - Fast replacement for matlab's gammaln.
%   digamma          - Derivative of gammaln.
%   trigamma         - Derivative of digamma.
%   tetragamma       - Derivative of trigamma.
%   ndsum            - Sum over multiple dimensions.
%   ndmax            - Maximum over multiple dimensions.
%   ndlogsumexp      - Sum over multiple dimensions in the log domain.
%   maxdiff          - Maximum difference between structs or arrays.
%   sameobject       - Test if two variables correspond to the same object.
%   find_sameobject  - Find an object in a cell array.
%   toJava           - Convert to Java representation.
%   fromJava         - Convert from Java to Matlab.
%   glob             - Filename expansion via wildcards.
%   globstrings      - String matching via wildcards.
%
% Argument lists
%   argfilter        - Remove unwanted arguments from a key/value list.
%   makestruct       - Cell-friendly alternative to STRUCT.
%   setfields        - Set multiple fields of a structure.
%   struct2arglist   - Convert structure to cell array of fields/values.
%
% Mutation
%   mutable          - Convert to a mutable object.
%   immutable        - Convert to an ordinary (immutable) object.
%
% Set operations
%   ismember_sorted  - True for member of sorted set.
%   match            - Location of matches in a set.
%   match_sorted     - Location of matches in a sorted set.
%   setdiff_sorted   - Set difference between sorted sets.
%   intersect_sorted - Set intersection between sorted sets.
%   union_sorted     - Set union of sorted sets.
%   union_sorted_rows - Set union of sorted sets of row vectors.
%   duplicated       - Find duplicated rows in a matrix.
%
% Readability
%   rows             - Number of rows.
%   cols             - Number of columns.
%   col_sum          - Sum for each column.
%   setdiag          - Modify the diagonals of a matrix.
%   finddiag         - Index of elements on diagonals.
%   argmax           - Index of maximum element.
%   argmin           - Index of minimum element.
%
% Flop counting
%   flops            - Read/write flop counter.
%   addflops         - Add to flop counter.
%   flops_chol       - Flops for Cholesky decomposition.
%   flops_col_sum    - Flops for column sums.
%   flops_det        - Flops for matrix determinant.
%   flops_digamma    - Flops for gammaln, digamma, and trigamma.
%   flops_div        - Flops for division.
%   flops_exp        - Flops for exponential.
%   flops_inv        - Flops for matrix inversion.
%   flops_mul        - Flops for real matrix multiplication.
%   flops_normpdfln  - Flops for normpdfln.
%   flops_pow        - Flops for raising to real power.
%   flops_randnorm   - Flops for randnorm.
%   flops_row_sum    - Flops for row sums.
%   flops_sample     - Flops for sample(p,n).
%   flops_solve      - Flops for matrix left division.
%   flops_solve_tri  - Flops for triangular left division.
%   flops_spadd      - Flops for sparse matrix addition.
%   flops_spmul      - Flops for sparse matrix multiplication.
%   flops_sqrt       - Flops for square root.
%
% Stand alone programs
%   matfile          - Read/write MAT files.
%   tests/test_flops - Compare time versus flops for various math operations.
%
% Graphics utilities
%  see graphics/Contents.m
%
% Demos
%   tests/test_repmat,
%   tests/test_solve_tri, ...


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

function test_dst_1(testCase)
    x = cos((1:15) * .1);
    alpha = spx.dsp.dst.forward_1(x);
    y = spx.dsp.dst.inverse_1(alpha);
    tolerance = 1e-6;
    verifyEqual(testCase, x, y, 'AbsTol', tolerance);
end

function test_dst_2(testCase)
    n = 256;
    tolerance = 1e-6;
    for i=randperm(n, 40)
        x = spx.vector.unit_vector(n, i);
        alpha = spx.dsp.dst.forward_2(x);
        verifyEqual(testCase, norm(x), norm(alpha), 'AbsTol', tolerance);
        y = spx.dsp.dst.inverse_2(alpha);
        verifyEqual(testCase, norm(y), norm(alpha), 'AbsTol', tolerance);
        verifyEqual(testCase, x, y, 'AbsTol', tolerance);
        alpha = spx.dsp.dst.forward_3(x);
        verifyEqual(testCase, norm(x), norm(alpha), 'AbsTol', tolerance);
        y = spx.dsp.dst.inverse_3(alpha);
        verifyEqual(testCase, norm(y), norm(alpha), 'AbsTol', tolerance);
        verifyEqual(testCase, x, y, 'AbsTol', tolerance);
    end
end


function [MPa] = Torr2MPa(Torr)
% Convert pressure from torr (same as mmHg) to megapascals
% Chad Greene 2012
MPa = Torr*0.000133322;


function [varargout]=kolmogorov_max_flow(A,u,v,varargin)
% KOLMOGOROV_MAX_FLOW Kolmogorov's max flow algorithm
%
% Kolmogorov's algorithm implements a variation on the augmenting path idea
% to compute a maximum flow or minimum cut in a network.
%
% See the max_flow function for calling information and return parameters.
% This function just calls max_flow(...,struct('algname','kolmogorov'));
%
% Example:
%   load('graphs/max_flow_example.mat');
%   kolmogorov_max_flow(A,1,8)

% David Gleich
% Copyright, Stanford University, 2007-2008

%% History
%  2007-07-07: Initial version
%  2008-10-07: Changed options parsing
%%

algname = 'kolmogorov';
if ~isempty(varargin),
    options = merge_options(struct(),varargin{:});
    options.algname= algname;
else options = struct('algname',algname);
end

varargout = cell(1,max(nargout,1));

[varargout{:}] = max_flow(A,u,v,options);


% barvar(X,Y,W)
%
% using patches to re-implement the bar-plot function, allowing different
% width for each bar.
%
% columns in Y are regarded as a data series (same color). rows are grouped
% into adjacent bars having different colors.
%
% to set the width for each data series input a row vector:
% W = [w1,w2,w3...]. to a set a different width for each bars group input a
% column vector: W = [w1;w2;w3...].

function hBar = barvar( X, Y, W)

if nargin < 3
    fprintf( 'this is a demo of barvar(X,Y,Z). \nnext time give me all the required inputs.\n');
    W = randi(3,1,5);
    X = (1:5)' * sum(W) * 1.5;
    Y = 10*(rand(5,5) - 0.5);
end

% rectify input, if possible
for dim = 1:2
    Repeat = ones(1,2);
    if size(X,dim) ~= size(Y,dim)
        if size(X,dim) == 1
            Repeat(dim) = size( Y,dim);
            X = repmat( X, Repeat);
        elseif size(Y,dim) == 1
            Repeat(dim) = size( X,dim);
            Y = repmat( Y, Repeat);
        else
            error( 'each input dimension should be either 1 or equal to other inputs.');
        end
    end
    if size(W,dim) ~= size(Y,dim)
        if size(W,dim) == 1
            Repeat(dim) = size( Y,dim);
            W = repmat( W, Repeat);
        else
            error( 'each input dimension should be either 1 or equal to other inputs.');
        end
    end
end

%% draw bars

nSets = size( Y,2);
nBars = size( Y,1);
hBar = zeros( 1, nSets);
SetWidth = sum( W,2); % width of combined sets per bar
cdata = (1:nSets)';

for s = 1:nSets

    % 4 vertices for each bar
    Xdata = zeros(4,nBars);
    Ydata = zeros(4,nBars);
    for b = 1:nBars
        % X-left
        Xdata(1,b) = X(b,s); % ref data point
        Xdata(1,b) = Xdata(1,b) - SetWidth(b) / 2; % begining of set (centered on Xdata)
        Xdata(1,b) = Xdata(1,b) + sum( W(b,1:s-1)); % current set position
        Xdata(2,b) = Xdata(1,b);
        % X-right = Xl + W
        Xdata(3,b) = Xdata(1,b) + W(b,s);
        Xdata(4,b) = Xdata(3,b);
        % Y-down
        Ydata(1,b) = 0;
        Ydata(4,b) = 0;
        % Y-up
        Ydata(2,b) = Y(b,s);
        Ydata(3,b) = Y(b,s);
    end

    hBar(s) = patch( Xdata, Ydata, s);
%     set(gca,'CLim',[0 40])
%     set( hBar(s), 'FaceColor', 'flat', 'FaceVertexCData', cdata(b), 'CDataMapping', 'direct');
    hold on
end

% x-axis
line( [ min(X(:)) - 100, max(X(:)) + 100], [0,0], 'Color', 'k');
hold off
AxisMargin = max( sum(W,2));
set( gca, 'Box', 'on', 'Xlim', [ min(X(:)) - AxisMargin, max(X(:)) + AxisMargin]);
figure(gcf)


maxmag = ceil(10*max(newt2.Magnitude))/10;
mima = min(newt2.Magnitude);
if mima > 0 ; mima = 0 ; end

[bval,xt2] = hist(newt2.Magnitude,(mima:0.1:maxmag));
% normalise to annula rates
bval = bval/(max(newt2.Date)-min(newt2.Date));
bvalsum = cumsum(bval); % N for M <=
bval2 = bval(length(bval):-1:1);
bvalsum3 = cumsum(bval(length(bval):-1:1));    % N for M >= (counted backwards)
xt3 = (maxmag:-0.1:mima);

backg_ab = log10(bvalsum3);

figure_w_normalized_uicontrolunits(bfig);delete(gca);delete(gca); delete(gca); delete(gca)
rect = [0.22,  0.3, 0.65, 0.6];           % plot Freq-Mag curves
axes('position',rect);

%%
% plot the cum. sum in each bin  %%
%%

pl =semilogy(xt3,bvalsum3,'sb');
set(pl,'LineWidth',1.0,'MarkerSize',6,...
    'MarkerFaceColor','w','MarkerEdgeColor','k');
hold on
%pl1 =semilogy(xt3,bval2,'^b');
%set(pl1,'LineWidth',1.0,'MarkerSize',4,...
%    'MarkerFaceColor',[0.7 0.7 .7],'MarkerEdgeColor','k');

bv2 = [];bv3 = [] ; me = [];BV = [];
ni2 = 300;
BB = [];
for i = 1:ni2/1:length(newt2)-ni2
    [bv magco stan ] =  bvalca2(newt2(i:i+ni2,:));
    nn2 = newt2(i:i+ni2,:);
    l = nn2(:,6) >= magco+0.0;
    nn2 = nn2(l,:);

    [bval,xt2] = hist(nn2(:,6),(mima:0.1:maxmag));
    % normalise to annual rates
    bval = bval/(max(nn2(:,3))-min(nn2(:,3)));
    k = mima:0.1:magco;
    bval(1:length(k)) = nan;
    BB = [BB ; bval];
    bvalsum = cumsum(bval); % N for M <=
    bval2 = bval(length(bval):-1:1);
    bvalsum3 = cumsum(bval(length(bval):-1:1));    % N for M >= (counted backwards)

    hold on
    pl =semilogy(xt3,bvalsum3,'sb');
    set(pl,'LineWidth',1.0,'MarkerSize',4,...
        'MarkerFaceColor',[rand(1,1) rand(1,1) rand(1,1)],'MarkerEdgeColor',[rand(1,1) rand(1,1) rand(1,1)]);
    hold on

end

allsum = mean(BB, 'omitnan');
bvalsum = cumsum(allsum); % N for M <=
bvalsum3 = cumsum(allsum(length(allsum):-1:1));    % N for M >= (counted backwards)
pl =semilogy(xt3,bvalsum3,'hb');
set(pl,'LineWidth',1.0,'MarkerSize',10,...
    'MarkerFaceColor','y','MarkerEdgeColor','k');
hold on