function [f,lambda,delta] = fit(ori,varargin)
% determines the fibre that fits best a list of orientations
%
% Syntax
%   f = fibre.fit(ori) % fit fibre to a list of orientations
%
%   f = fibre.fit(ori,'local')
%
%   f = fibre.fit(odf) % fit fibre to a list of orientations
%
% Input
%  ori1, ori2, ori - @orientation
%  odf - @SO3Fun
%
% Output
%  f       - @fibre
%  lambda  - eigenvalues of the orientation tensor
%
% Options
%  local   - fast approach for locally concentrated orientations

if isa(ori,'SO3Fun')

  odf = ori;
  cs = odf.CS.properGroup;

  hGrid = Miller(equispacedS2Grid('resolution',10*degree,...
    cs.fundamentalSector),cs);
  rGrid = equispacedS2Grid('resolution',1.25*degree,odf.SS.fundamentalSector);
  lGrid = equispacedS2Grid('resolution',0.5*degree,'maxTheta',10*degree);

  % search through all pole figures
  v = -inf;
  for ih = 1:length(hGrid)

    % detect maximum in pole figure
    [~,ir] = max(calcPDF(odf,hGrid(ih),rGrid));

    % detect local maximum in corresponding inverse pole figure
    lhGrid = rotation.byAxisAngle(zvector + hGrid(ih),pi) * lGrid;
    [~,ih2] = max(calcPDF(odf,lhGrid,rGrid(ir)));

    % detect local maximum in corresponding pole figure - second iteration
    lrGrid = rotation.byAxisAngle(zvector + rGrid(ir),pi) * lGrid;
    [vTmp,ir2] = max(calcPDF(odf,lhGrid(ih2),lrGrid));

    % maybe we have found a new optimum
    if vTmp > v
      f = fibre(Miller(lhGrid(ih2),odf.CS),lrGrid(ir2));
      v = vTmp;
    end

  end
  return

elseif check_option(varargin,{'noSymmetry','local'}) || ori.CS.numProper==1

  [~,~,lambda,eigv] = mean(ori,varargin{:});

  ori12 = orientation(quaternion(eigv(:,4:-1:3)),ori.CS,ori.SS);
  f = fibre(ori12(1),ori12(2),'full',varargin{:});

  if nargout == 3
    delta = norm(angle(f,ori)) / length(ori);
  end

  return

end

% the global approach
odf = calcDensity(ori,'halfwidth',10*degree);
cs = ori.CS.properGroup;
rotSym = cs.rot;
fs = cs.fundamentalSector;

hGrid = Miller(equispacedS2Grid('resolution',10*degree,fs),cs);
rGrid = equispacedS2Grid('resolution',1.25*degree,ori.SS.fundamentalSector);
% a local grid
lGrid = equispacedS2Grid('resolution',0.5*degree,'maxTheta',10*degree);
%localhGrid = [localhGrid;-localhGrid];

% search through all pole figures
v = inf;
for ih = 1:length(hGrid)

  % detect maximum in pole figure
  [~,ir] = max(calcPDF(odf,hGrid(ih),rGrid));

  % detect local maximum in corresponding inverse pole figure
  lhGrid = rotation.byAxisAngle(zvector + hGrid(ih),pi) * lGrid;
  [~,ih2] = max(calcPDF(odf,lhGrid,rGrid(ir)));

  % project to fibre
  d = angle_outer(times(rotSym,lhGrid(ih2),1), times(inv(ori),rGrid(ir),0),'noSymmetry').';
  [m,idSym] = min(d,[],2);

  % robust estimate
  oriP = times(ori(m<quantile(m,0.8)), rotSym(idSym(m<quantile(m,0.8))),0);
  %oriP = times(ori, rotSym(idSym),0);

  % fit fibre
  fTmp = fibre.fit(oriP,'noSymmetry');
  %fTmp = fibre(Miller(rhGrid(id2),ori.CS),rGrid(id));

  % maybe we have found a new optimum
  vTmp = mean(angle(fTmp,ori));
  if vTmp < v, f = fTmp; v = vTmp; end

end

function test

  cs = crystalSymmetry('432');
  f = fibre.rand(cs);
  odf = fibreODF(f,'halfwidth',20*degree);

  ori = discreteSample(odf,100000);

  tic
  fRec = fibre.fit(ori,'refine')
  toc

  mean(angle(fRec,ori))./degree

  mean(angle(f,ori))./degree

  angle(fRec,f)./degree

end

end


function eps = deformationTensor(sS)
% deformation tensor
%
% Syntax
%   eps = deformationTensor(sS)
%
% Input
%  sS - list of @slipSystem
%
% Output
%  eps - deformationTensor
%

eps = dyad(sS.b.normalize,sS.n.normalize);


function memory_test ( n_log_min, n_log_max )

%*****************************************************************************80
%
%% MEMORY_TEST carries out some tests of memory limits in MATLAB.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 June 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N_LOG_MIN, the logarithm of the minimum N to try.
%
%    Input, integer N_LOG_MAX, the logarithm of the maximum N to try.
%
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'MEMORY_TEST\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Try to see how big vectors and matrices can be.\n' );

  if ( nargin < 1 )
    n_log_min = 0;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default value of N_LOG_MIN = %d\n', n_log_min );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, '  User input value of N_LOG_MIN = %d\n', n_log_min );
  end

  if ( nargin < 2 )
    n_log_max = 25;
    fprintf ( 1, '\n' );
    fprintf ( 1, '  Using default value of N_LOG_MAX = %d\n', n_log_max );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, '  User input value of N_LOG_MAX = %d\n', n_log_max );
  end
%
%  I4VEC test.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'I4VEC Memory Test\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, ...
    'Log2(N)            N   Ave     CPU        Real\n' );
  fprintf ( 1, '\n' );

  for n_log = n_log_min : n_log_max

    i4vec_memory_test ( n_log );

  end
%
%  R8VEC test.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8VEC Memory Test\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, ...
    'Log2(N)            N   Ave     CPU        Real\n' );
  fprintf ( 1, '\n' );

  for n_log = n_log_min : n_log_max

    r8vec_memory_test ( n_log );

  end
%
%  I4MAT test.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'I4MAT Memory Test\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, ...
    'Log2(N)            N            N1            N2   Ave     CPU        Real\n' );
  fprintf ( 1, '\n' );

  for n_log = n_log_min : n_log_max

    i4mat_memory_test ( n_log );

  end
%
%  R8MAT test.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8MAT Memory Test\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, ...
    'Log2(N)            N            N1            N2   Ave     CPU        Real\n' );
  fprintf ( 1, '\n' );

  for n_log = n_log_min : n_log_max

    r8mat_memory_test ( n_log );

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, 'MEMORY_TEST\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  fprintf ( 1, '\n' );
  timestamp ( );

  return
end
function i4mat_memory_test ( n_log )

%*****************************************************************************80
%
%% I4MAT_MEMORY_TEST declares and uses an I4MAT of total size N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 June 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N_LOG, the logarithm base 2 of N.
%
  n = 2^n_log;

  n1_log = floor ( n_log / 2 );
  n1 = 2^n1_log;
  n2_log = n_log - n1_log;
  n2 = 2^n2_log;

  fprintf ( 1, '  %4d  %12d', n_log, n );

  tic;
  cpu_time1 = cputime;

  i4mat = zeros ( n1, n2 );

  i4mat = round ( 2.0 * rand ( n1, n2 ) );

  average = ( sum ( sum ( i4mat(1:n1,1:n2) ) ) ) / n1 / n2;

  cpu_time2 = cputime;
  real_diff = toc;

  cpu_diff = cpu_time2 - cpu_time1;

  fprintf ( 1, '  %12d  %12d  %4.2f  %10e  %10e\n', ...
    n1, n2, average, cpu_diff, real_diff );

  return
end
function i4vec_memory_test ( n_log )

%*****************************************************************************80
%
%% I4VEC_MEMORY_TEST declares and uses an I4VEC of size N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 June 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N_LOG, the logarithm base 2 of N.
%
  n = 2^n_log;

  fprintf ( 1, '  %4d  %12d', n_log, n );

  tic;
  cpu_time1 = cputime;

  i4vec = zeros ( n, 1 );

  i4vec = round ( 2.0 * rand ( n, 1 ) );

  average = ( sum ( i4vec(1:n) ) ) / n;

  cpu_time2 = cputime;
  real_diff = toc;

  cpu_diff = cpu_time2 - cpu_time1;

  fprintf ( 1, '  %4.2f  %10e  %10e\n', average, cpu_diff, real_diff );

  return
end
function r8mat_memory_test ( n_log )

%*****************************************************************************80
%
%% R8MAT_MEMORY_TEST declares and uses an R8MAT of total size N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 June 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N_LOG, the logarithm base 2 of N.
%
  n = 2^n_log;

  n1_log = floor ( n_log / 2 );
  n1 = 2^n1_log;
  n2_log = n_log - n1_log;
  n2 = 2^n2_log;

  fprintf ( 1, '  %4d  %12d', n_log, n );

  tic;
  cpu_time1 = cputime;

  r8mat = zeros ( n1, n2 );

  r8mat = 2.0 * rand ( n1, n2 );

  average = ( sum ( sum ( r8mat(1:n1,1:n2) ) ) ) / n1 / n2;

  cpu_time2 = cputime;
  real_diff = toc;

  cpu_diff = cpu_time2 - cpu_time1;

  fprintf ( 1, '  %12d  %12d  %4.2f  %10e  %10e\n', ...
    n1, n2, average, cpu_diff, real_diff );

  return
end
function r8vec_memory_test ( n_log )

%*****************************************************************************80
%
%% R8VEC_MEMORY_TEST declares and uses an R8VEC of size N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 June 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N_LOG, the logarithm base 2 of N.
%
  n = 2^n_log;

  fprintf ( 1, '  %4d  %12d', n_log, n );

  tic;
  cpu_time1 = cputime;

  r8vec = zeros ( n, 1 );

  r8vec = 2.0 * rand ( n, 1 );

  average = ( sum ( r8vec(1:n) ) ) / n;

  cpu_time2 = cputime;
  real_diff = toc;

  cpu_diff = cpu_time2 - cpu_time1;

  fprintf ( 1, '  %4.2f  %10e  %10e\n', average, cpu_diff, real_diff );

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


function res = spm_eeg_specest_mtmfft(S, data, time)
% Plugin for spm_eeg_tf implementing spectral estimation using Fieldtrip's freqanalysis_mtmconvol
% FORMAT res = spm_eeg_specest_mtmfft(S, data, time)
%
% S                     - input structure
% fields of S:
%    S.taper       - taper to use ('hanning', 'rectwin', 'dpss', 'sine' or
%                    other possible inputs of 'window'
%    S.freqres     - frequency resolutions (plus-minus for each frequency, can
%                    be a vector with a value per frequency)
%    S.frequencies - vector of frequencies%
% Output:
%  res -
%   If no input is provided the plugin returns a cfg branch for itself
%
%   If input is provided:
%      res.fourier - the complex output of wavelet transform (in the case
%                    of single taper)
%      res.pow     - power (in case of multiple tapers, phase is not computed)
%      res.time    - time axis
%      res.freq    - frequency axis
%______________________________________________________________________________________
% Copyright (C) 2011-2014 Wellcome Trust Centre for Neuroimaging

% $Id: spm_eeg_specest_mtmfft.m 6021 2014-05-27 16:41:37Z vladimir $

%-This part if for creating a config branch that plugs into spm_cfg_eeg_tf
% Any parameters can be specified and they are then passed to the plugin
% when it's called.
%--------------------------------------------------------------------------
if nargin == 0
    freqres = cfg_entry;
    freqres.tag = 'freqres';
    freqres.name = 'Frequency resolution';
    freqres.strtype = 'r';
    freqres.num = [1 Inf];
    freqres.val = {2};
    freqres.help = {'Frequency resolution.',...
        'Note: 1 Hz resolution means plus-minus 1 Hz, i.e. 2 Hz badwidth',...
        'Either a single value or a vector of the same length as frequencies can be input'};

    taper = cfg_menu;
    taper.tag = 'taper';
    taper.name = 'Taper';
    taper.help = {'Save taper as well as power'};
    taper.labels = {'Hanning', 'Rectangular', 'DPSS', 'Sine'};
    taper.values = {'hanning', 'rectwin', 'dpss', 'sine'};
    taper.val = {'sine'};

    mtmfft = cfg_branch;
    mtmfft.tag = 'mtmfft';
    mtmfft.name = 'Spectrum';
    mtmfft.val = {taper, freqres};

    res = mtmfft;

    return
elseif nargin < 3
    error('Three input arguments are required');
end

%-Defaults
%--------------------------------------------------------------------------
if ~isfield(S, 'taper')
    S.taper = 'sine';
end

dt = time(end) - time(1) + diff(time(1:2));

if ~isfield(S, 'frequencies') || isempty(S.frequencies)
    S.frequencies = (1/dt):max(1/dt, floor(dt)/dt):48;
end

if ~isfield(S, 'freqres')
    S.freqres = max(1/dt, floor(dt)/dt);
end

if length(S.freqres) == 1
    freqres = S.freqres*ones(1, length(S.frequencies));
elseif length(S.freqres) == length(S.frequencies)
    freqres = S.freqres;
else
    error('Frequency resolution should be either a scalar or a vector the same length as the number of frequencies.')
end

%-Data dimensions
%--------------------------------------------------------------------------
fsample = 1./diff(time(1:2));

df = unique(diff(S.frequencies));
if length(df) == 1
    pad = ceil(dt*df)/df;
else
    pad = [];
end

[spectrum,ntaper,freqoi] = ft_specest_mtmfft(data, time, 'taper', S.taper,'freqoi', S.frequencies,...
    'tapsmofrq', freqres, 'pad', pad, 'padtype', 'mirror', 'verbose', 0);

% This in principle should not happen
if length(unique(diff(freqoi)))>1 && max(abs(diff(unique(diff(freqoi)))))>1e-3
    error('Non-uniform output frequency axis')
end

res = [];
res.freq = linspace(freqoi(1), freqoi(end), length(freqoi));
res.time = [1 1]*mean(time);

if ndims(spectrum) == 3 && size(spectrum, 1)>1
    res.pow = spm_squeeze(nanmean(spectrum.*conj(spectrum), 1), 1);
elseif ndims(spectrum) == 3
    res.fourier = spm_squeeze(spectrum, 1);
else
    res.fourier = spectrum;
end
end

function y = nansum(x, dim)

x(isnan(x)) = 0;
if nargin==1
    y = sum(x);
else
    y = sum(x,dim);
end
end

function y = nanmean(x, dim)
N = sum(~isnan(x), dim);
y = nansum(x, dim) ./ N;
end


classdef filterer < dml.method
% FILTERER filtering approach to feature selection.
%
%   DESCRIPTION
%   The filterer produces an ordering of the features based on a univariate measure
%   and uses that ordering to greedily determine the 'optimal' feature set
%   or to select the best m features.
%
%   If filter is a string, e.g. 'ttest' then it calls rankfeatures in the bioinformatics
%   toolbox. If it is a function it will just evaluate that function on
%   each feature and the output.
%
%   EXAMPLE
%   dml.filterer('validator',dml.crossvalidator('mva',dml.naive,'stat','accuracy'))
%
%   DEVELOPER
%   Marcel van Gerven (m.vangerven@donders.ru.nl)

  properties

    maxfeatures = Inf; % maximum number of used features

    filter = @(x,y)(abs(corr(x,y))); % the used filter

    value % the value  of the filter for each feature

    order % the ordering of the features according to value

    criterion % the value of the validator for feature 1:N

    validator % the used crossvalidator

    subset % subset of selected features

  end

  methods

    function obj = filterer(varargin)

      obj = obj@dml.method(varargin{:});

    end

    function obj = train(obj,X,Y)

      % multiple datasets
      if iscell(X) || iscell(Y)
        obj = ft_mv_ndata('mvmethod',obj);
        obj = obj.train(X,Y);
        return;
      end

      maxf = min(obj.maxfeatures,size(X,2));

      if obj.verbose
        if isempty(obj.validator)
          fprintf('selecting %d features based on %s filter\n',maxf,obj.filter);
        else
          fprintf('selecting optimal features based on %s filter\n',obj.filter);
        end
      end

      if isempty(obj.validator)
      % just take the best N features based on a univariate criterion

        % compute function values
        nf = size(X,2);
        obj.value = zeros(1,nf);
        if ischar(obj.filter)

          if obj.verbose
            fprintf('computing %s filter using rankfeatures\n');
          end
          Z = rankfeatures(X',Y','Criterion',obj.filter);
          for j=1:nf
            obj.value(j) = Z(j);
          end

        else

          for j=1:nf

            if obj.verbose
              fprintf('computing %s filter for feature %d of %d\n',obj.filter,j,nf);
            end

            obj.value(j) = obj.filter(X(:,j),Y);
          end

        end

        % get ordering of the features
        [tmp,obj.order] = sort(obj.value,'descend');

        % select the best n features
        obj.subset = obj.order(1:maxf);

      else
        % currently we use a simple approach. A better approach would be
        % the following:
        %
        % use procedure to determine the best feature subset.
        % first we use the procedure to compute the univariate filter
        % values per fold. Then we determine the average best number of features
        % over folds using the crossvalidation procedure. Then we recompute the
        % univariate filter values for all data and return the optimal
        % subset

        % compute function values
        nf = size(X,2);
        obj.value = zeros(1,nf);
        if ischar(obj.filter)

          if obj.verbose
            fprintf('computing %s filter using rankfeatures\n');
          end
          Z = rankfeatures(X',Y','Criterion',obj.filter);
          for j=1:nf
            obj.value(j) = Z(j);
          end

        else
          for j=1:nf

            if obj.verbose
              fprintf('computing %s filter for feature %d of %d\n',obj.filter,j,nf);
            end

            obj.value(j) = obj.filter(X(:,j),Y);

          end

        end

        % get ordering of the features
        [tmp,obj.order] = sort(obj.value,'descend');

        obj.subset = [];
        metric = -Inf;

        obj.criterion = zeros(1,maxf);
        for f=1:maxf

          if obj.verbose
            fprintf('evaluating %d out of %d features; ',f,maxf);
          end

          cv = obj.validator.train(X(:,obj.order(1:f)),Y);

          m = cv.statistic;

          if obj.verbose, fprintf('criterion: %.2g\n',m); end

          if m > metric
            obj.subset = obj.order(1:f);
            metric = m;
          end

          obj.criterion(f) = m;

        end
      end

    end

    function Y = test(obj,X)

      Y = X(:,obj.subset);

    end

    function m = model(obj)
      % return logical array with ones indicating selected features
      % m.selected logical array with ones indicating selected features
      % m.importance importance according to the used filter

      indim = obj.indims;
      if length(indim) == 1, indim = [1 indim]; end

      m1 = zeros(indim);
      m1(obj.subset) = 1;
      m.selected = m1;

      m1 = zeros(indim);
      m1(:) = obj.value;
      m.importance = m1;

    end

  end

end


%% FUNCTION Least_SparseTrace
%   Incoherent Sparse and Low-Rank Learning with Least Squares Loss.
%
%% OBJECTIVE
%   argmin_W { sum_i^t (0.5 * norm (Y{i} - X{i}' * W(:, i))^2)
%            + gamma * \|P\|_1 }
%   subject to: W = P + Q, \|Q\|_* <= tau
%   where \|Q\|_*      = sum( svd(Q, 0) )
%
%% INPUT
%   X: {n * d} * t - input matrix
%   Y: {n * 1} * t - output matrix
%   gamma: sparse component P L1,2-norm sprasity controlling parameter
%   tau: low rank component Q trace-norm regularization parameter
%
%% OUTPUT
%   W: model: d * t
%   funcVal: function value vector.
%
%% LICENSE
%   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/>.
%
%   Copyright (C) 2011 - 2012 Jiayu Zhou, Jianhui and Jieping Ye
%
%   You are suggested to first read the Manual.
%   For any problem, please contact with Jiayu Zhou via jiayu.zhou@asu.edu
%
%   Last modified on June 3, 2012.
%
%% RELATED PAPERS
%
%   [1] Chen, J., Liu, J. and Ye, J. Learning Incoherent Sparse and Low-Rank
%   Patterns from Multiple Tasks, KDD 2010
%
%% RELATED FUNCTIONS
%   init_opts

function [W funcVal Tp_val Tq_val] = Least_SparseTrace(X, Y, gamma, tau, opts )

if nargin <4
    error('\n Inputs: X, Y, rho1, and rho2 should be specified!\n');
end
X = multi_transpose(X);

if nargin <5
    opts = [];
end

% initialize options.
opts=init_opts(opts);

zero_threshold = 0;

d = size(X{1}, 1); m = length(Y);

% Initialize L and S
if opts.init==2
    P0 = zeros(d, m);
    Q0 = zeros(d, m);
elseif opts.init == 0
    P0 = randn(d, m);
    Q0 = P0;
else
    if isfield(opts,'P0')
        P0=opts.P0;
        if (nnz(size(P0)-[d, m]))
            error('\n Check the input .L0');
        end
    else
        P0=randn(d, m);
    end

    if isfield(opts,'Q0')
        Q0=opts.Q0;
        if (nnz(size(Q0)-[d, m]))
            error('\n Check the input .S0');
        end
    else
        Q0=P0;
    end

end

% Initialize
Tp_i = P0;
Tq_i = Q0;
Tp_i_min_1 = P0;
Tq_i_min_1 = Q0;

% initial parameters setting
%  ++++++++++++++++++++++++++++++++++++++++++

% Initialize L
Li = 1;

% Set an array to save the objective value
funcVal = [ ];

% Set auxiliary parameters

t_i_min_2 = 0;
t_i_min_1 = 1;
XY = cell(m, 1);
for jj = 1:m
    XY{jj} = X{jj} * Y{jj};
end

% main loop
% ++++++++++++++++++++++++++++++++++++++++++
for iter = 1 : opts.maxIter

    alpha_i = ( t_i_min_2 - 1 ) / t_i_min_1;

    Sp = ( 1 + alpha_i ) * Tp_i - alpha_i * Tp_i_min_1;
    Sq = ( 1 + alpha_i ) * Tq_i - alpha_i * Tq_i_min_1;

    derivative = zeros(d, m);
    if opts.pFlag
        parfor kk = 1:m
            Xi = X{kk};
            col = Sp(:, kk) + Sq(:, kk);
            derivative(:, kk) = 2 * Xi * (Xi' * col)  - 2 * XY{kk};
        end
    else
        for kk = 1:m
            Xi = X{kk};
            col = Sp(:, kk) + Sq(:, kk);
            derivative(:, kk) = 2 * Xi * (Xi' * col)  - 2 * XY{kk};
        end
    end

    lambda_old = 1;
    sign = 1;

    while (sign)

        beta = Li / 2;

        hat_Sp = Sp - derivative / Li;
        hat_Sq = Sq - derivative / Li;

        % Compute Tp
        Tp = Solve_OneNorm(hat_Sp, beta, gamma);

        % Compute Tq
        [U S V] = svd(hat_Sq, 'econ');
        s_bar = diag(S);
        s_bar = s_bar( s_bar > zero_threshold );
        U = U( :, 1:length(s_bar));
        V = V( :, 1:length(s_bar));

        [s_hat, lambda_new ]=eplb(s_bar, size(s_bar, 1), tau, lambda_old);
        Tq = U * diag(s_hat) * V';

        [sign qp_term]= line_search_cond_sparse_lowrank(Tp, Tq, Sp, Sq, X, Y, derivative, Li, opts);

        if (sign)
            Li = Li * 2;
            lambda_old = lambda_new;
        end

    end

    funcVal = cat(1, funcVal,  qp_term +  gamma * sum( abs(Tp(:)) ) );

    % test stop condition.
    switch(opts.tFlag)
        case 0
            if iter>=2
                if (abs( funcVal(end) - funcVal(end-1) ) <= opts.tol)
                    break;
                end
            end
        case 1
            if iter>=2
                if (abs( funcVal(end) - funcVal(end-1) ) <=...
                        opts.tol* funcVal(end-1))
                    break;
                end
            end
        case 2
            if ( funcVal(end)<= opts.tol)
                break;
            end
        case 3
            if iter>=opts.maxIter
                break;
            end
    end

    t_i_min_2 = t_i_min_1;
    t_i_min_1 = ( 1 + ( 1+4*t_i_min_1^2 )^0.5 ) / 2;

    Tp_i_min_1 = Tp_i;
    Tq_i_min_1 = Tq_i;

    Tp_i = Tp;
    Tq_i = Tq;

end % for loop

Tp_val = Tp;
Tq_val = Tq;
W = Tp_val + Tq_val;

end


function smooth = score_smooth(score)
score = score';
tmp1 = [score(2:end),score(end)];
tmp2 = [score(1), score(1:end-1)];
smooth = (score +  tmp1 + 0*tmp2)/2;
end


function tilefigs(tile,border)
% <cpp> tile figure windows usage: tilefigs ([nrows ncols],border_in pixels)
% Restriction: maximum of 100 figure windows
% Without arguments, tilefigs will determine the closest N x N grid

%Charles Plum                    Nichols Research Corp.
%<cplum@nichols.com>             70 Westview Street
%Tel: (781) 862-9400             Kilnbrook IV
%Fax: (781) 862-9485             Lexington, MA 02173

maxpos  = get (0,'screensize'); % determine terminal size in pixels
maxpos(4) = maxpos(4) - 25;
hands   = get (0,'Children');   % locate fall open figure handles
hands   = sort(hands);          % sort figure handles
numfigs = size(hands,1);        % number of open figures

maxfigs = 100;

if (numfigs>maxfigs)            % figure limit check
        disp([' More than ' num2str(maxfigs) ' figures ... get serious pal'])
        return
end

if nargin == 0
  maxfactor = sqrt(maxfigs);       % max number of figures per row or column
  sq = [2:maxfactor].^2;           % vector of integer squares
  sq = sq(find(sq>=numfigs));      % determine square grid size
  gridsize = sq(1);                % best grid size
  nrows = sqrt(gridsize);          % figure size screen scale factor
  ncols = nrows;                   % figure size screen scale factor
elseif nargin > 0
  nrows = tile(1);
  ncols = tile(2);
  if numfigs > nrows*ncols
    disp ([' requested tile size too small for ' ...
        num2str(numfigs) ' open figures '])
        return
  end
end
if nargin < 2
  border = 0;
else
  maxpos(3) = maxpos(3) - 2*border;
  maxpos(4) = maxpos(4) - 2*border;
end
xlen = fix(maxpos(3)/ncols) - 30; % new tiled figure width
ylen = fix(maxpos(4)/nrows) - 45; % new tiled figure height

% tile figures by postiion
% Location (1,1) is at bottom left corner
pnum=0;
for iy = 1:nrows
  ypos = maxpos(4) - fix((iy)*maxpos(4)/nrows) + border +25; % figure location (row)
  for ix = 1:ncols
        xpos = fix((ix-1)*maxpos(3)/ncols + 1) + border+7;     % figure location (column)
        pnum = pnum+1;
    if (pnum>numfigs)
                break
        else
          figure(hands(pnum))
      set(hands(pnum),'Position',[ xpos ypos xlen ylen ]); % move figure
        end
  end
end
return

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


%................................................................

function outputDisplacementsReactionsPretty...
    (displacements,stiffness,GDof,prescribedDof,force)

% output of displacements and reactions in
% tabular form

% GDof: total number of degrees of freedom of
% the problem

disp('Displacements')
fprintf('node\t\tdisplacements\n')
% displacements
for jj=1:GDof
    fprintf('%2.0f:        %10.4e\n', jj, displacements(jj))
end

% reactions
F=stiffness*displacements;
reactions=F(prescribedDof)-force(prescribedDof);
disp('Reactions')
fprintf('node\t\treactions\n')
for jj=1:size(prescribedDof,1)
    fprintf('%2.0f:        %10.4e\n', prescribedDof(jj), reactions(jj))
end


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defmethod @@sym xor (@var{x}, @var{y})
%% Logical xor of symbolic arrays.
%%
%% Examples:
%% @example
%% @group
%% xor(sym(true), sym(true))
%%   @result{} ans = (sym) False
%% @end group
%%
%% @group
%% syms x y
%% xor (x, y)
%%   @result{} (sym) x ⊻ y
%% @end group
%% @end example
%%
%% @seealso{@@sym/and, @@sym/or, @@sym/not, @@sym/eq, @@sym/ne,
%%          @@sym/logical, @@sym/isAlways}
%% @end defmethod

function r = xor(x, y)

  if (nargin ~= 2)
    print_usage ();
  end

  r = elementwise_op ('Xor', sym(x), sym(y));

end

%!shared t, f
%! t = sym(true);
%! f = sym(false);

%!test
%! % simple
%! assert (isequal (xor(t, f), t))
%! assert (isequal (xor(t, t), f))

%!test
%! % array
%! w = [t t f f];
%! z = [t f t f];
%! assert (isequal (xor(w, z), [f t t f]))

%!xtest
%! % output is sym even for scalar t/f
%! % ₣IXME: should match other bool fcns
%! assert (isa (xor(t, f), 'sym'))

%!test
%! % eqns
%! syms x
%! e = xor(x == 4, x == 5);
%! assert (isequal (subs(e, x, [3 4 5 6]), [f t t f]))

%!test
%! % eqns, exclusive
%! syms x
%! e = xor(x == 3, x^2 == 9);
%! assert (isequal (subs(e, x, [-3 0 3]), [t f f]))

%!error xor (sym('x'), 1, 2)


%MDL_LWR Create model of Kuka LWR manipulator
%
% MDL_LWR is a script that creates the workspace variable KR5 which
% describes the kinematic characteristics of a Kuka KR5 manipulator using
% standard DH conventions.
%
% Also define the workspace vectors:
%   qz        all zero angles
%
% Notes::
% - SI units of metres are used.
%
% Reference::
% - Identifying the Dynamic Model Used by the KUKA LWR: A Reverse Engineering Approach
%   Claudio Gaz Fabrizio Flacco Alessandro De Luca
%   ICRA 2014
%
% See also mdl_kr5, mdl_irb140, mdl_puma560, SerialLink.

% Copyright (C) 1993-2017, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

% MODEL: Kuka, LWR, 7DOF, standard_DH

d1 =0.4; d2 = 0.39;

%All link lengths and offsets are measured in m
clear L
%            theta    d           a       alpha
links = [
	    Link([0        0           0       pi/2])
		Link([0        0           0      -pi])
		Link([0        d1          0      -pi/2])
		Link([0        0           0       pi/2])
		Link([0        d2          0       pi/2])
		Link([0        0           0       -pi/2])
		Link([0        0           0       0])
	];

LWR=SerialLink(links, 'name', 'Kuka LWR');

qz = [0 0 0 0 0 0 0];


function varargout = subsref( F, ref )
%SUBSREF   DISKFUNV subsref.
%   F(X,Y) or F(X, Y, 'cart') returns values of the DISKFUNV F evaluated on
%   the array (X, Y) in Cartesian coordinates.
%
%   F(T, R, 'polar') returns the values of the DISKFUNV F evaluated on the
%   array (T,R) in polar coordinates.
%
%   F(k) returns the kth component of F.
%
%   F.PROP returns the property PROP of F as defined by GET(F, 'PROP').
%
% See also DISKFUN/GET, DISKFUNV/SET

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

% Empty check:
if ( isempty( F ) )
   varargout = { [] };
   return
end

% Get indexing reference:
indx = ref(1).subs;

switch ( ref(1).type )

    case '.'
        if ( numel( ref ) == 1 )

            % This is a get call to get a property.
            varargout = { get(F, indx) };

        else

            % Probably .^ or maybe .*
            %t2 = index(2).type;
            t2 = ref(2).type;
            if ( strcmp(t2, '.') )
                out = get(F, indx, ref(2).subs{:});
            else
                out = get(F, indx);
                out = out( ref(2).subs{:} );
            end
            if ( numel(ref) > 2 )
                varargout = {subsref(out, ref(3:end))};
            else
                varargout = { out };
            end

        end

    case '()'
        % Either evaluation or the user wants the kth component of F:
        if ( length(indx) > 1 )
            % EVALUATION, call FEVAL:
            x = indx{1};
            y = indx{2}; % where to evaluate
            vals = feval(F, x, y, ref(1).subs{:});
            varargout = { vals };

        else
            % COMPONENTS, extract the component:
            if ( isa(indx{1},'double') )
                if all( indx{1} == 1  )
                    % F(1):
                    varargout = F.components(1);
                elseif ( all( indx{1} == 2 ) )
                    % F(2):
                    varargout = F.components(2);
                else
                    error('CHEBFUN:DISKFUNV:subsref:index', ...
                        'DISKFUNV only contains two components');
                end
            end
        end

    otherwise
        error('CHEBFUN:DISKFUNV:subsref:unexpectedType', ...
            ['??? Unexpected index.type of ' index(1).type]);

end

% Recurse down the subsref tree, if appropriate:
if ( numel( ref ) > 1 )
   ref(1) = [];
   varargout = { subsref( varargout{ : }, ref ) };
end

end


%% Script to plot MOP1
% This scripts plot the objective space for MOP1 given in Homework
% Assignment # 5. It used the function eveluate_objective to determine the
% objective values and plots the two dimensional objective space.
hold on
plot3(0,0,0);
axis([0 2 0 2 0 2]);
for i = 1 : 10
    s = sprintf('%d',i);
    %plot3(x(i,13),x(i,14),x(i,15),'String',i);
    %text(x(i,13)+.05,x(i,14)+.05,x(i,14)+.05,s);
    text(x(i,13),x(i,14),x(i,14),s);
end
hold off


function msg = apm_lti(sys,name)

if nargin < 1,
    error('Input State Space or Transfer Function Model')
end
if nargin == 1,
    name = 'sys';
end
if nargin == 2,
    % trim whitespace
    filename = strtrim(name);
    % parse file name and extension
    [path,name,ext] = fileparts(name);
end
filename = [name '.apm'];

% Convert to state space form
sys = ss(sys);
% Check if discrete
if (sys.Ts>0),
    discrete = true;
else
    discrete = false;
end

% extract A, B, C, D matrices in sparse form
[n,m] = size(sys.B);
[p,m] = size(sys.D);

[ai,aj,av] = find(sparse(sys.A));
a = [ai,aj,av]';
[bi,bj,bv] = find(sparse(sys.B));
b = [bi,bj,bv]';
[ci,cj,cv] = find(sparse(sys.C));
if (size(sys.C,1)==1),
    c = [ci;cj;cv];
else
    c = [ci,cj,cv]';
end
[di,dj,dv] = find(sparse(sys.D));
d = [di,dj,dv]';
if(size(d,2)==0),
    d = [1,1,0]';
end

fid = fopen(filename,'w');
fprintf( fid,'\n');
fprintf( fid,'Objects \n');
fprintf( fid,['  ' name ' = lti\n']);
fprintf( fid,'End Objects \n');
fprintf( fid,'\n');
fprintf( fid,'Connections\n');
fprintf( fid,['  u[1:%d] = ' name '.u[1:%d]\n'],m,m);
fprintf( fid,['  x[1:%d] = ' name '.x[1:%d]\n'],n,n);
fprintf( fid,['  y[1:%d] = ' name '.y[1:%d]\n'],p,p);
fprintf( fid,'End Connections\n');
fprintf( fid,'\n');
fprintf( fid,'Model \n');
fprintf( fid,'  Parameters \n');
fprintf( fid,'    u[1:%d] = 0\n',m);
fprintf( fid,'  End Parameters \n');
fprintf( fid,'\n');
fprintf( fid,'  Variables \n');
fprintf( fid,'    x[1:%d] = 0\n',n);
fprintf( fid,'    y[1:%d] = 0\n',p);
fprintf( fid,'  End Variables \n');
fprintf( fid,'\n');
fprintf( fid,'  Equations \n');
fprintf( fid,'    ! add any additional equations here \n');
fprintf( fid,'  End Equations \n');
fprintf( fid,'End Model \n');
fprintf( fid,'\n');
fprintf( fid,'! dimensions\n');
fprintf( fid,'! (nx1) = (nxn)*(nx1) + (nxm)*(mx1)\n');
fprintf( fid,'! (px1) = (pxn)*(nx1) + (pxm)*(mx1)\n');
fprintf( fid,'!\n');
if discrete,
    fprintf( fid,'! discrete form with sampling time = %f\n',sys.Ts);
    fprintf( fid,'! x[k+1] = A * x[k] + B * u[k]\n');
    fprintf( fid,'!   y[k] = C * x[k] + D * u[k]\n');
else
    fprintf( fid,'! continuous form\n');
    fprintf( fid,'! dx/dt = A * x + B * u\n');
    fprintf( fid,'!   y   = C * x + D * u\n');
end
fprintf( fid,['File ' name '.txt\n']);
if discrete,
    fprintf( fid,'  sparse, discrete  ! dense/sparse, continuous/discrete\n');
else
    fprintf( fid,'  sparse, continuous  ! dense/sparse, continuous/discrete\n');
end
fprintf( fid,'  %d      ! m=number of inputs\n',m);
fprintf( fid,'  %d      ! n=number of states\n',n);
fprintf( fid,'  %d      ! p=number of outputs\n',p);
fprintf( fid,'End File\n');
fprintf( fid,'\n');
fprintf( fid,['File ' name '.a.txt \n']);
fprintf( fid,'   %d %d %f\n', a );
fprintf( fid,'End File \n');
fprintf( fid,'\n');
fprintf( fid,['File ' name '.b.txt \n']);
fprintf( fid,'   %d %d %f\n', b );
fprintf( fid,'End File \n');
fprintf( fid,'\n');
fprintf( fid,['File ' name '.c.txt \n']);
fprintf( fid,'   %d %d %f\n', c );
fprintf( fid,'End File \n');
fprintf( fid,'\n');
fprintf( fid,['File ' name '.d.txt \n']);
fprintf( fid,'   %d %d %f\n', d );
fprintf( fid,'End File \n');
fclose(fid);

msg = ['Created Linear Time Invariant (LTI) Model: ' filename];

end


%kkbitwise 'Dual Operand Bitwise Operations'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kbitwise.pane file
%
% Parameters:
% InputFile: i1 'Input 1', required: 'first input data object'
% OutputFile: o 'Output', required: 'resulting output data object'
% InputFile: i2 'Input 2', optional: 'second input data object'
% Integer: real 'Constant ', default: 1: 'constant value'
% Toggle: and 'AND', default: 0: 'Bitwise AND: o = i1 & (i2 or val)'
% Toggle: ls 'Left Shift', default: 0: 'Bitwise Left Shift: o = i1 << by (i2 or val)'
% Toggle: or 'OR', default: 0: 'Bitwise OR: o = i1 | (i2 or val)'
% Toggle: rs 'Unsigned Right Shift', default: 0: 'Bitwise Right Shift: o = i1 >> by (i2 or val)'
% Toggle: xor 'XOR', default: 0: 'Bitwise XOR: o = i1 ^ (i2 or val)'
% Toggle: srs 'Signed Right Shift', default: 0: 'Bitwise Signed Right Shift by (i2 or val)'
% Toggle: nand 'NAND', default: 0: 'Bitwise NAND: o = (~i1) | (~(i2 or val))'
% Toggle: rr 'Right Rotate', default: 0: 'Bitwise Right Rotate by (i2 or val)'
% Toggle: nor 'NOR', default: 0: 'Bitwise NOR: o = (~i1) & (~(i2 or val))'
% Toggle: lr 'Left Rotate', default: 0: 'Bitwise Left Rotate by (i2 or val)'
% Toggle: andrev '1 AND (NOT 2)', default: 0: 'Bitwise AND Reverse: o = i1 & (~(i2 or val))'
% Toggle: andinv '(NOT 1) AND 2', default: 0: 'Bitwise AND Inverted: o = (~i1) & (i2 or val)'
% Toggle: orrev '1 OR (NOT 2)', default: 0: 'Bitwise OR Reverse: o = i1 | (~(i2 or val))'
% Toggle: orinv '(NOT 1) OR 2', default: 0: 'Bitwise OR Inverted: o = (~i1) | i2'
%
% Example: o = kkbitwise({i1, i2}, {'i1','';'o','';'i2','';'real',1;'and',0;'ls',0;'or',0;'rs',0;'xor',0;'srs',0;'nand',0;'rr',0;'nor',0;'lr',0;'andrev',0;'andinv',0;'orrev',0;'orinv',0})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kbitwise - Dual Operand Bitwise Operations
%
%  DESCRIPTION
% The bitwise operator, kbitwise, performs a the specified bitwise operation
% between each point in \fBInput 1" (i1) and each corresponding point in
% \fBInput 2" (i2), if the second input is specified.  If Input 2 is not
% specified, the operation will be performed using the \fBConstant" value
% (real).
%
% Therefore, if kbitwise were called with two input objects:
%
% 	kbitwise -i1 image:ball -i2 image:moon -o out -and
%
% then the following operation would be performed
%
% 	out = i1 & i2
%
% Whereas if kbitwise were called with a single data object and a constant:
%
% 	kbitwise -i1 image:ball -real 10 -o out -and
%
% then the following would be performed:
%
% 	o = i1 & 10
%
%
% The supported functions are:
%
%
% 	AND (and)                   o = i1 & (i2 or val)
% 	OR   (or)                   o = i1 | (i2 or val)
% 	Exclusive Or (xor)          o = i1 ^ (i2 or val)
% 	NAND (nand)                 o = (~i1) | (~(i2 or val))
% 	NOR  (nor)                  o = (~i1) & (~(i2 or val))
% 	AND Reverse  (andrev)       o = i1 & (~(i2 or val))
% 	AND Inverted (andinv)       o = (~i1) & (i2 or val)
% 	OR Reverse  (orrev)         o = i1 | (~(i2 or val))
% 	OR Inverted (orinv)         o = (~i1) | i2
% 	Unsigned Right Shift (rs)   o = i1 >> by (i2 or val)
% 	Unsigned Left  Shift (ls)   o = i1 << by (i2 or val)
%
%
%
%  "Data Type - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_1input
%
%  "Data Type - Two Input Objects" 5
% .cI $DATAMANIP/repos/shared/man/sections/value_type_2input
% The bitwise operators will not operate on float or complex data types.
%
%  "Map Data" 5
% The bitwise operations have not been written to be fully polymorphic yet.
% They does not
% check for map data, and will therefore always operate on the value data,
% even if a map exists.  This will most likely corrupt indexing into the map.
% In the case of a single input, it is recommended to use the "Copy to
% Value" (kcptoval) segment operator to temporarily move the map data into
% the value segment, run kbitwise on the data, then move it back to the
% map with the "Copy from Value" (kcpfromval) operator.
% When operating with two input objects, where at least one of the objects
% contains map data, data should be mapped prior to running the bitwise
% operator.  The "Map Data" operator (kmapdata) can be used to perform
% the mapping operation.
%
%  "Validity Mask - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/mask_1input
%
%  "Validity Mask - Two Input Objects" 5
% Masking has not been implemented yet for the bitwise operators.  Therefore,
% only the mask from the first input object will be transferred to the output.
%
%  "Input Objects of Different Sizes" 5
% .cI $DATAMANIP/repos/shared/man/sections/resize_2input
% The value used to pad the data when the input files are not the same size is
% zero.
%
%  "Explicit Location and Time Data - Single Input" 5
% .cI $DATAMANIP/repos/shared/man/sections/loc_and_time_1input
%
%  "Explicit Location and Time Data - Two Input Objects" 5
% The bitwise operations have not been extended to understand location and
% time data.  Therefore, only location and time data present in the first input
% object will be transferred to the output.
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
% THIS ROUTINE is still under development, and has not been modified to fully
% support the polymorphic data model.  See paragraphs above for discussions
% concerning the polymorphic data segments.
%
% All processing is currently performed as UNSIGNED long, so the operations
% may not work properly on negative values.
%
% The bitwise operators will not operate on float or complex data types.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkbitwise(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kkbitwise(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i1', '__input';'o', '__output';'i2', '__input';'real', 1;'and', 0;'ls', 0;'or', 0;'rs', 0;'xor', 0;'srs', 0;'nand', 0;'rr', 0;'nor', 0;'lr', 0;'andrev', 0;'andinv', 0;'orrev', 0;'orinv', 0};
maxval={0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
minval={0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
istoggle=[0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
was_set=istoggle * 0;
paramtype={'InputFile','OutputFile','InputFile','Integer','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle','Toggle'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(1,1);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
[varargout{:}]=callKhoros([w 'kbitwise"  '],Inputs,narglist);


function ind = find(S1G,x,epsilon)
% find close points
%
% Syntax
%   ind = find(S1G,x,epsilon) % find all points in distance epsilon
%   ind = find(S1G,x)         % find closest point
%
% Input
%  S1G     - @S1Grid
%  x       - double
%  epsilon - double
%
% Output
%  ind - int32

if S1G(1).periodic, p = S1G.max - S1G.min; else p = 0; end

if nargin == 2
  ind = S1Grid_find(S1G.points(:),S1G.min,p,x);
else
  ind = S1Grid_find_region(S1G.points(:),S1G.min,p,x,epsilon);
end


function file_name = file_name_inc ( file_name )

%*****************************************************************************80
%
% FILE_NAME_INC generates the next filename in a series.
%
%  Discussion:
%
%    It is assumed that the digits in the name, whether scattered or
%    connected, represent a number that is to be increased by 1 on
%    each call.  If this number is all 9's on input, the output number
%    is all 0's.  Non-numeric letters of the name are unaffected..
%
%    If the name is empty, then the routine stops.
%
%    If the name contains no digits, the empty string is returned.
%
%  Example:
%
%      Input            Output
%      -----            ------
%      'a7to11.txt'     'a7to12.txt'  (typical case.  Last digit incremented)
%      'a7to99.txt'     'a8to00.txt'  (last digit incremented, with carry.)
%      'a9to99.txt'     'a0to00.txt'  (wrap around)
%      'cat.txt'        ' '           (no digits in input name.)
%      ' '              STOP!         (error.)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 September 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character FILE_NAME(*), the string to be incremented.
%
%    Output, character FILE_NAME_NEW(*), the incremented string.
%
  lens = length ( file_name );

  if ( lens <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FILE_NAME_INC - Fatal error!\n' );
    fprintf ( 1, '  The input filename is empty.\n' );
    error ( 'FILE_NAME_INC - Fatal error!' );
  end

  change = 0;

  for i = lens : -1 : 1

    c = file_name(i);

    if ( '0' <= c & c <= '8' )

      change = change + 1;

      c = c + 1;

      file_name(i) = c;

      return

    elseif ( c == '9' )

      change = change + 1;

      c = '0';

      file_name(i) = c;

    end

  end

  if ( change == 0 )
    file_name = ' ';
  end

  return
end


function outVec = vecInsert(elemToInsert,position,vecIn)

%Inserts a vector of elements into the given positions.  elemToInsert is a
%vector that can be as small as 1 element and as large as desired.
%Position is an array of positions that can be as small as one element and
%as large as the number of elements you wish to insert.
%
%If position is smaller than the number of elements, this function will
%assume that the remaining elements will be inserted sequentially.
%
%If position is larger than the number of elements, this function will insert the
%last element of elemToInsert at the remaining given positions.

N = max(length(elemToInsert),length(position));
tmpVec = zeros(length(vecIn) + N,1);
tmpVec(:,1) = NaN;
if length(position) == length(elemToInsert)
    tmpVec(position) = elemToInsert;
elseif length(position) < length(elemToInsert)
    %More elements to insert than given positions
    tmpVec(position,1) = elemToInsert(1:length(position));
    tmpVec(position(end) + 1:position(end) + (length(elemToInsert) - length(position))) = elemToInsert(length(position)+1:end);
else
    %More positions than elements to insert
    tmpVec(position(1:length(elemToInsert))) = elemToInsert;
    tmpVec(position(length(elemToInsert)+1:end)) = elemToInsert(end);
end

%put vecIn back in
tmpVec(find(isnan(tmpVec(:)))) = vecIn;

outVec = tmpVec;


filename='Cantilever_hexahedra_coarse';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance';'perimeter'};
weights = [1, 0.1];
constraint = {'volumeConstraint'};
optimizer = 'IPOPT';
incrementFactor = 1;
designVariable = 'Density';
filterType = 'P1';

nsteps = 5;
Vfrac_final = 0.1;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-2;
constr_initial = 1e-3;
TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;


classdef MaxCrossCorr < Algorithm

    methods (Access = public)

        function obj = MaxCrossCorr()
            obj.name = 'MaxCrossCorr';
            obj.inputPort = DataType.kSignal2;
            obj.outputPort = DataType.kFeature;
        end

        function result = compute(~,signal)
            result = max(xcorr(signal(:,1),signal(:,2)));
        end

        function metrics = computeMetrics(~,input)
            n = size(input,1);
            flops = 161 * n;
            memory = n;
            outputSize = Constants.kFeatureBytes;
            metrics = Metric(flops,memory,outputSize);
        end
    end
end


function findelem(node,elem,range,varargin)
%% FINDELEM highlights some elements
%
%    FINDELEM(node,elem,range) finds all elements whose indices are in the
%    range array by displaying these elements in yellow. The size of the marker
%    is proportional to the number of digits of the indices. The font will
%    magnify as one resizes the figure.
%
%    FINDELEM(node,elem) finds all elements.
%
%    FINDELEM(node,elem,range,'noindex') skip the display of indices.
%
%    FINDELEM(node,elem,range,'param','value','param','value'...) allows
%    additional patch param/value pairs to highlight the elements.
%
% Example:
%     node = [1,0; 1,1; 0,1; -1,1; -1,0; -1,-1; 0,-1; 0,0];
%     elem = [1,2,8; 3,8,2; 8,3,5; 4,5,3; 7,8,6; 5,6,8];
%     subplot(1,2,1);
%     showmesh(node,elem);
%     findelem(node,elem,1,'index','FaceColor','r');
%     subplot(1,2,2);
%     showmesh(node,elem);
%     findelem(node,elem);
%
%   See also findelem3, findnode3, findedge.
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

hold on

if (nargin==2) || isempty(range) || (ischar(range) && strcmp(range,'all'))
    range = (1:size(elem,1))';
end
if islogical(range)
    range = find(range);
end
if size(range,2)>size(range,1)
    range = range';
end
nV = size(elem,2);
if nV == 3
    center=(node(elem(range,1),:)+node(elem(range,2),:)+node(elem(range,3),:))/3;
elseif nV == 4
    center=(node(elem(range,1),:)+node(elem(range,2),:)+node(elem(range,3),:)+node(elem(range,4),:))/4;
end
if length(range) < size(elem,1)
    x = reshape(node(elem(range,:),1),size(range,1), size(elem,2))';
    y = reshape(node(elem(range,:),2),size(range,1), size(elem,2))';
    h = patch(x,y,'y');
    if nargin > 3
        if strcmp(varargin{1},'noindex')
           if size(varargin,2)>=2
                set(h,varargin{2:end});
           end
        else
            set(h,varargin{:});
        end
    end
end
nDigit =ceil(log10(range+1));
oSize = 400*nDigit;
f = gcf;
set(f, 'Units', 'pixel');
fHeight = f.Position(4);
if (nargin <=3) || ~(strcmp(varargin{1},'noindex'))
    if size(node,2) == 2
        s = scatter(center(:,1),center(:,2),oSize,'o','LineWidth',1,'MarkerEdgeColor','k',...
            'MarkerFaceColor','y');
        if max(f.Position(3:4)) <= 1
            fSz = 20*f.Position(4); % font size is proportional to height
        else
            fSz = log(f.Position(3)*f.Position(4));
        end
        tShift = 0.02*(max(nDigit) + 1 - nDigit);
        tShift(nDigit==1) = 0.5*tShift(nDigit==1);
        t = text(center(:,1)-tShift,center(:,2),int2str(range),...
            'Fontsize',fSz,'FontWeight','bold','Color','k');
        nElemShown = length(t);
        set(f,'SizeChangedFcn',@resizeCallback);
        set(f,'Visible','on');
        drawnow;
    elseif size(node,2) == 3 % surface mesh
        scatter3(center(:,1),center(:,2),center(:,3),oSize,'o','LineWidth',1,...
            'MarkerEdgeColor','k','MarkerFaceColor','y');
        text(center(:,1)-0.02*nDigit,center(:,2),center(:,3),int2str(range),'FontSize',12,...
        'FontWeight','bold','Color','k');
    end
end
hold off
%% relative position of numbers
% add by Shuhao Cao
    function resizeCallback(f, ~)
        if max(f.Position(3:4)) <= 1 % relative
            newFSz = 80*f.Position(4); % font size is proportional to height
            newOSize = 10*oSize*(f.Position(4));
            newTshift = 4*tShift*f.Position(4);
        else % pixel
            newFSz = log(f.Position(3)*f.Position(4));
            newOSize = oSize*(f.Position(4)/fHeight);
            newTshift = tShift/(f.Position(4)/fHeight);
        end
        % change font size accordingly
        set(t,'FontSize',newFSz);
        set(s,'SizeData',newOSize);
        for i = 1:nElemShown
            set(t(i), 'Position', [center(i,1)-newTshift(i), center(i,2), 0]);
        end
    end

end


function h1 = imageplot(M,str, a,b,c)

% imageplot - diplay an image and a title
%
% Example of usages:
%   imageplot(M);
%   imageplot(M,title);
%   imageplot(M,title,1,2,1);   % to make subplot(1,2,1);
%
%   imageplot(M,options);
%
%   If you want to display several images:
%       imageplot({M1 M2}, {'title1', 'title2'});
%
%   Copyright (c) 2007 Gabriel Peyre

if nargin<2
    str = [];
end

options.null = 0;
if isstruct(str)
    options = str;
    str = '';
end

nbdims = nb_dims(M);

if iscell(M)
    q = length(M);
    if nargin<5
        c = 1;
    end
    if nargin<4
        a = ceil(q/4);
    end
    if nargin<3
        b = ceil(q/a);
    end
    if (c-1+q)>(a*b)
        warning('a and c parameters not large enough');
        a = ceil((c-1+q)/4);
        b = ceil((c-1+q)/a);
    end
    for i=1:q
        if iscell(str)
            str1 = str{i};
        else
            str1 = str;
        end
        h{i} = imageplot(M{i},str1, a,b,c-1+i);
    end
    global axlist;
    if not(isempty(axlist))
        linkaxes(axlist, 'xy');
    end

    if nargout>0
        if exist('h')
            h1 = h;
        else
            h1 = [];
        end
    end
    return;
end

if nargin==5
    global axlist;
    global imageplot_size;
    if c==1 || isempty(imageplot_size) || imageplot_size~=size(M,1)
        clear axlist;
        global axlist;
        axlist = [];
        imageplot_size = size(M,1);
    end
    axlist(end+1) = subplot(a,b,c);
end

if nbdims==1
    h = plot(M); axis tight;
elseif size(M,3)<=3
    % gray-scale or color image
    if size(M,3)==2
        M = cat(3,M, zeros(size(M,1),size(M,2)));
    end
    if not(isreal(M))
        if size(M,3)==1
            % turn into color matrix
            M = cat(3, real(M), imag(M), zeros(size(M,1),size(M,2)));
        else
            warning('Complex data');
            M = real(M);
        end
    end
    if size(M,3)==1
        colormap gray(256);
    else
        colormap jet(256);
    end
    h = imagesc(rescale(M)); axis image; axis off;
else

    if not(isfield(options, 'center') )
        options.center = .5; % here a value in [0,1]
    end
    if not(isfield(options, 'sigma'))
        options.sigma = .08; % control the width of the non-transparent region
    end
    a = compute_alpha_map('gaussian', options); % you can plot(a) to see the alphamap

    % volumetric image
    h = vol3d('cdata',rescale(M),'texture','2D');
    view(3);
    axis tight; % daspect([1 1 .4])
    colormap bone(256);
%    alphamap('rampup');
    % alphamap(.06 .* alphamap);
    vol3d(h);
end
if not(isempty(str))
    title(str);
end

if nargout>0
    if exist('h')
        h1 = h;
    else
        h1 = [];
    end
end

if nargin==5 && c==a*b
    linkaxes(axlist, 'xy');
end

function d = nb_dims(x)

% nb_dims - debugged version of ndims.
%
%   d = nb_dims(x);
%
%   Copyright (c) 2004 Gabriel Peyre

if isempty(x)
    d = 0;
    return;
end

d = ndims(x);

if d==2 && (size(x,1)==1 || size(x,2)==1)
    d = 1;
end


function z = rdivide( x, y )

%   Disciplined convex programming information for RDIVIDE:
%      For DCP purposes, the RDIVIDE division operator X./Y is identical
%      to X.*(1./Y). The right-hand term must be constant and non-zero;
%      and if the left-hand term is nonlinear, the constat must be real.
%
%   Disciplined geometric programming information for RDIVIDE:
%      Terms in a left divide must have opposite log-curvature, so the
%      following products are permitted:
%         {log-convex} ./ {log-concave}  {log-concave} ./ {log-convex}
%         {log-affine} ./ {log-affine}
%      Note that log-affine expressions are both log-convex and
%      log-concave.
%
%   For vectors, matrices, and arrays, these rules are verified
%   indepdently for each element.

z = times( x, y, './' );

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function updateSpatial_endoscope(obj, Y, num, method, smin)
%% udpate spatial components

%% inputs:
%   Y: d X T matrix, data
%   num: scalar. If method=='hals', then num is the number of iterations to
%       update A; If method=='nnls', then num is the maximum number of neurons
%       overlapping at one pixel
%   method: method for updating the spatial components {'hals', 'nnls'}.
%       default: 'nnls'

%% Author: Pengcheng Zhou, Carnegie Mellon University.

%% input parameters number of iterations
if ~exist('method', 'var')||isempty(method)
    method = 'nnls';
end
if ~exist('num', 'var')||isempty(num)
    if strcmpi(method, 'nnls')
        num=5;
    else
        num = 10;
    end
end
if ~exist('IND_thresh', 'var')||isempty(IND_thresh)
    IND_thresh = [];
end
%% determine the search locations
search_method = obj.options.search_method;
params = obj.options;
if strcmpi(search_method, 'dilate')
    obj.options.se = [];
end
IND = logical(determine_search_location(obj.A, search_method, params));

%% update spatial components
if strcmpi(method, 'hals')
    obj.A = HALS_spatial(Y, obj.A, obj.C, IND, num);
elseif strcmpi(method, 'nnls_thresh')&&(~isempty(IND_thresh))
    try
        sn = obj.P.sn;
    catch
        sn = get_noise_fft(Y);
        obj.P.sn = sn;
    end

    obj.A = nnls_spatial_thresh(Y, obj.A, obj.C, IND, num, smin, sn);
else
    obj.A = nnls_spatial(Y, obj.A, obj.C, IND, num);
end

%% thresholding the minimum number of neurons
obj.delete(sum(obj.A, 1)<=obj.options.min_pixel);

%% post-process
% obj.post_process_spatial();
% if strcmpi(method, 'nnls')
%     IND = bsxfun(@gt, obj.A, max(obj.A, [], 1)/100);
%     obj.A = nnls_spatial(Y, obj.A, obj.C, IND, num);
% end

end


function [fibercurvatures, curves]=dtiComputeFiberGroupCurvatures(fg)

%For fibers within a fibergroup fg computes their curvature values, returning an array of curvatures. Useful if
%feeding this function resampled fg and then computing correlations between
%these curves.
%Works only  if all the fibers are the same length -- use
%dtiFiberCurvature for prosessing individual fibers otherwise

%ER 04/2008

nfibers=size(fg.fibers, 1);
numNodes=size(fg.fibers{1}, 2);
curves=zeros(3, numNodes, nfibers);

for i=1:nfibers
    %Compute curvature representations
    fibercurvatures(i, :)=dtiFiberCurvature(fg.fibers{i}); %fiber_curvature_vals=fiber_curvature(fiber);
    curves(:, :, i)=fg.fibers{i};
end


function linplus_test426 ( )

%*****************************************************************************80
%
%% TEST426 tests R8CC_PRINT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  m = 5;
  n = 5;
  nz_num = 12;
  colptr = [ 1, 4, 6, 8, 10, 13 ];
  rowind = [ 1, 2, 4, 1, 2, 3, 5, 4, 5, 1, 2, 5 ];
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST426\n' );
  fprintf ( 1, '  R8CC_PRINT prints a R8CC matrix.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Matrix rows M =          %d\n', m );
  fprintf ( 1, '  Matrix columns N =       %d\n', n );
  fprintf ( 1, '  Matrix nonzeros NZ_NUM = %d\n', nz_num );
%
%  Set the matrix.
%
  [ a, seed ] = r8cc_random ( m, n, nz_num, colptr, rowind, seed );
%
%  Print the matrix.
%
  r8cc_print ( m, n, nz_num, colptr, rowind, a, '  The R8CC matrix:' );

  return
end


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @documentencoding UTF-8
%% @deftypefun  {@var{F} =} fibonacci (@var{n})
%% @deftypefunx {@var{p} =} fibonacci (@var{n}, @var{x})
%% Return symbolic Fibonacci numbers or Fibonacci polynomials.
%%
%% Examples:
%% @example
%% @group
%% fibonacci(15)
%%   @result{} (sym) 610
%% syms n
%% fibonacci(n)
%%   @result{} (sym)
%%       F
%%        n
%% @end group
%% @end example
%%
%% Polynomial example:
%% @example
%% @group
%% syms x
%% fibonacci(10, x)
%%   @result{} (sym)
%%        9      7       5       3
%%       x  + 8⋅x  + 21⋅x  + 20⋅x  + 5⋅x
%% @end group
%% @end example
%%
%% @seealso{euler, bernoulli}
%% @end deftypefun

function r = fibonacci(n, x)

  if (nargin == 1)
    r = pycall_sympy__ ('return sp.fibonacci(*_ins),', sym(n));
  elseif (nargin == 2)
    r = pycall_sympy__ ('return sp.fibonacci(*_ins),', sym(n), sym(x));
  else
    print_usage ();
  end

end

%!assert (isequal ( fibonacci (sym(0)), 0))
%!assert (isequal ( fibonacci (sym(14)), sym(377)))
%!assert (isequal ( fibonacci (14), 377))
%!test syms x
%! assert (isequal (fibonacci (5,x), x^4 + 3*x^2 + 1))


function [g,a,info] = dtwfb2filterbank( dualwt, varargin)
%DTWFB2FILTERBANK DTWFB equivalent non-iterated filterbank
%   Usage: [g,a] = dtwfb2filterbank(dualwt)
%          [g,a,info] = dtwfb2filterbank(...)
%
%   Input parameters:
%      dualwt : Dual-tree wavelet filterbank specification.
%
%   Output parameters:
%      g      : Cell array of filters.
%      a      : Downsampling rate for each channel.
%      info   : Additional information.
%
%   `[g,a] = dtwfb2filterbank(dualwt)` constructs a set of filters *g* and
%   subsampling factors *a* of a non-iterated filterbank, which is
%   equivalent to the dual-tree wavelet filterbank defined by *dualwt*.
%   The returned parameters can be used directly in |filterbank| and other
%   routines. The format of *dualwt* is the same as in |dtwfb| and
%   |dtwfbreal|.
%
%   The function internally calls |dtwfbinit| and passes *dualwt* and all
%   additional parameters to it.
%
%   `[g,a,info] = dtwfb2filterbank(...)` additionally outputs a *info*
%   struct containing equivalent filterbanks of individual real-valued
%   trees as fields *info.g1* and *info.g2*.
%
%   Additional parameters:
%   ----------------------
%
%   `'real'`
%      By default, the function returns a filtebank equivalent to |dtwfb|.
%      The filters can be restricted to cover only the positive frequencies
%      and to be equivivalent to |dtwfbreal| by passing a `'real'` flag.
%
%   `'freq'`(default),`'nat'`
%     The filters are ordered to produce subbands in the same order as
%     |dtwfb| or |dtwfbreal| with the same flag.
%
%   Examples:
%   ---------
%
%   The following two examples create a multirate identity filterbank
%   using a duel-tree of depth 3:::
%
%      [g,a] = dtwfb2filterbank({'qshift3',3},'real');
%      filterbankfreqz(g,a,1024,'plot','linabs');
%
%   In the second example, the filterbank is identical to the full
%   wavelet tree:::
%
%      [g,a] = dtwfb2filterbank({'qshift3',3,'full'},'real');
%      filterbankfreqz(g,a,1024,'plot','linabs');
%
%   See also: dtwfbinit

complainif_notenoughargs(nargin,1,'DTWFB2FILTERBANK');

% Search for the 'real' flag
do_real = ~isempty(varargin(strcmp('real',varargin)));
if do_real
    %Remove the 'real' flag from varargin
    varargin(strcmp('real',varargin)) = [];
end

if ~isempty(varargin(strcmp('complex',varargin)))
    %Remove the 'complex' flag from varargin
    %It is not used elsewhere anyway
    varargin(strcmp('complex',varargin)) = [];
end

% Initialize the dual-tree
dtw = dtwfbinit({'strict',dualwt},varargin{:});

% Determine relation between the tree nodes
[wtPath, rangeLoc, rangeOut] = treeBFranges(dtw);
slice = ~cellfun(@isempty,rangeOut); % Limit to nodes with unconnected outputs
wtPath   = wtPath(slice);
rangeLoc = rangeLoc(slice);
rangeOut = rangeOut(slice);

% Multirate identity filters of the first tree
[g1,a] = nodesMultid(wtPath,rangeLoc,rangeOut,dtw);

% Multirate identity filters of the second tree
dtw.nodes = dtw.dualnodes;
g2 = nodesMultid(wtPath,rangeLoc,rangeOut,dtw);

if nargin>2
   % Return the filterbanks before doing the alignment
   info.g1 = cellfun(@(gEl) setfield(gEl,'h',gEl.h/2),g1,'UniformOutput',0);
   info.g2 = cellfun(@(gEl) setfield(gEl,'h',gEl.h/2),g2,'UniformOutput',0);
end

% Align filter offsets so they can be summed
for ii = 1:numel(g1)
   % Sanity checks
   assert(g1{ii}.offset<=0,sprintf('%s: Invalid wavelet filters.',upper(mfilename)));
   assert(g2{ii}.offset<=0,sprintf('%s: Invalid wavelet filters.',upper(mfilename)));

   % Insert zeros and update offsets
   offdiff = g1{ii}.offset-g2{ii}.offset;
   if offdiff>0
       g1{ii}.offset = g1{ii}.offset - offdiff;
       g1{ii}.h = [zeros(offdiff,1);g1{ii}.h(:)];
   elseif offdiff<0
       g2{ii}.offset = g2{ii}.offset + offdiff;
       g2{ii}.h = [zeros(-offdiff,1);g2{ii}.h(:)];
   end

   % Pad with zeros to a common length
   lendiff = numel(g1{ii}.h) - numel(g2{ii}.h);
   if lendiff~=0
       maxLen = max(numel(g1{ii}.h),numel(g2{ii}.h));
       g1{ii}.h = postpad(g1{ii}.h,maxLen);
       g2{ii}.h = postpad(g2{ii}.h,maxLen);
   end
end

% Filters covering the positive frequencies
g = cellfun(@(gEl,g2El) setfield(gEl,'h',(gEl.h+1i*g2El.h)/2),g1,g2,'UniformOutput',0);

% Mirror the filters when negative frequency filters are required too
if ~do_real
   gneg = cellfun(@(gEl,g2El) setfield(gEl,'h',(gEl.h-1i*g2El.h)/2),g1,g2,'UniformOutput',0);
   g = [g;gneg(end:-1:1)];
   a = [a;a(end:-1:1)];
end


function varargout = rgb2xyz(varargin)
% VL_RGB2XYZ  Convert RGB color space to XYZ
%   J=VL_RGB2XYZ(I) converts the CIE RGB image I to the image J in
%   CIE XYZ format. CIE RGB has a white point of R=G=B=1.0
%
%   VL_RGB2XYZ(I,WS) uses the specified RGB working space WS. The
%   function supports the following RGB working spaces:
%
%   * `CIE'    E illuminant, gamma=2.2
%   * `Adobe'  D65 illuminant, gamma=2.2
%
%   The default workspace is CIE.
%
%   See also: VL_XYZ2RGB(), VL_HELP().
[varargout{1:nargout}] = vl_rgb2xyz(varargin{:});


function sc = sortcomp(compin)
%nejak to moc nefunguje....
compd = dip_image(compin);
comp = double(gaussf(compd,1));

amax = squeeze(max(max(abs(comp))));
amean = squeeze(mean(mean((abs(comp)))));
v = (amax-amean)./(amax+amean);
[a, b] = sort(v, 'descend');
sc = comp(:,:,b);

imax = squeeze(max(max(sc)));
imin = squeeze(min(min(sc)));
msub = find(abs(imin)>imax); %giggest nonzero value negative
sc(:,:,msub) = -sc(:,:,msub); %flip negative to positive


function [m, C, W] = gaussian_CPD_params_given_dps(CPD, domain, evidence)
% GAUSSIAN_CPD_PARAMS_GIVEN_EV_ON_DPS Extract parameters given evidence on all discrete parents
% function [m, C, W] = gaussian_CPD_params_given_ev_on_dps(CPD, domain, evidence)

ps = domain(1:end-1);
dps = ps(CPD.dps);
if isempty(dps)
  m = CPD.mean;
  C = CPD.cov;
  W = CPD.weights;
else
  odom = domain(~isemptycell(evidence(domain)));
  dops = myintersect(dps, odom);
  dpvals = cat(1, evidence{dops});
  if length(dops) == length(dps)
    dpsizes = CPD.sizes(CPD.dps);
    dpval = subv2ind(dpsizes, dpvals(:)');
    m = CPD.mean(:, dpval);
    C = CPD.cov(:, :, dpval);
    W = CPD.weights(:, :, dpval);
  else
    map = find_equiv_posns(dops, dps);
    index = mk_multi_index(length(dps), map, dpvals);
    m = CPD.mean(:, index{:});
    C = CPD.cov(:, :, index{:});
    W = CPD.weights(:, :, index{:});
  end
end


classdef AD9364Tests < HardwareTests

    properties
        uri = 'ip:192.168.2.1';
        author = 'ADI';
    end

    methods(TestClassSetup)
        % Check hardware connected
        function CheckForHardware(testCase)
            Device = @()adi.AD9364.Rx;
            testCase.CheckDevice('ip',Device,testCase.uri(4:end),false);
        end
    end

    methods (Static)
        function estFrequency(data,fs)
            nSamp = length(data);
            FFTRxData  = fftshift(10*log10(abs(fft(data))));
            df = fs/nSamp;  freqRangeRx = (-fs/2:df:fs/2-df).'/1000;
            plot(freqRangeRx, FFTRxData);
        end
    end

    methods (Test)

        function testAD9364Rx(testCase)
            % Test Rx DMA data output
            rx = adi.AD9364.Rx('uri',testCase.uri);
            rx.EnabledChannels = 1;
            [out, valid] = rx();
            rx.release();
            testCase.verifyTrue(valid);
            testCase.verifyGreaterThan(sum(abs(double(out))),0);
        end

        function testAD9364TooManyChannels(testCase)
            rx = adi.AD9364.Rx();
            testCase.verifyError(@SetchanelCount4,?MException);
            function SetchanelCount4
                rx.channelCount = 4;
            end
        end

        function testAD9364RxWithTxDDS(testCase)
            % Test DDS output
            tx = adi.AD9364.Tx('uri',testCase.uri);
            tx.DataSource = 'DDS';
            toneFreq = 5e5;
            tx.DDSFrequencies = repmat(toneFreq,2,2);
            tx.AttenuationChannel0 = -10;
            tx();
            pause(1);
            rx = adi.AD9364.Rx('uri',testCase.uri);
            rx.EnabledChannels = 1;
            rx.kernelBuffersCount = 1;
            for k=1:10
                valid = false;
                while ~valid
                    [out, valid] = rx();
                end
            end
            rx.release();

%             plot(real(out));
%             testCase.estFrequency(out,rx.SamplingRate);
            freqEst = meanfreq(double(real(out)),rx.SamplingRate);

            testCase.verifyTrue(valid);
            testCase.verifyGreaterThan(sum(abs(double(out))),0);
            testCase.verifyEqual(freqEst,toneFreq,'RelTol',0.01,...
                'Frequency of DDS tone unexpected')

        end

        function testAD9364RxWithTxData(testCase)
            % Test Tx DMA data output
            amplitude = 2^15; frequency = 0.12e6;
            swv1 = dsp.SineWave(amplitude, frequency);
            swv1.ComplexOutput = true;
            swv1.SamplesPerFrame = 1e4*10;
            swv1.SampleRate = 3e6;
            y = swv1();

            tx = adi.AD9364.Tx('uri',testCase.uri);
            tx.DataSource = 'DMA';
            tx.EnableCyclicBuffers = true;
            tx.AttenuationChannel0 = -10;
            tx(y);
            rx = adi.AD9364.Rx('uri',testCase.uri);
            rx.EnabledChannels = 1;
            rx.kernelBuffersCount = 1;
            for k=1:10
                valid = false;
                while ~valid
                    [out, valid] = rx();
                end
            end
            rx.release();

%             plot(real(out));
%             testCase.estFrequency(out,rx.SamplingRate);
            freqEst = meanfreq(double(real(out)),rx.SamplingRate);

            testCase.verifyTrue(valid);
            testCase.verifyGreaterThan(sum(abs(double(out))),0);
            testCase.verifyEqual(freqEst,frequency,'RelTol',0.01,...
                'Frequency of ML tone unexpected')
        end
    end

end


classdef PANELtype < uint8
    %Panel enmieration class to define the differnt type of panel objects
    %that can be run in a PanelVAR

    enumeration
        Mge                 (1) % OLS mean group estimator
        Pooled              (2) % pooled estimator
        Random_zh           (3) % random effect (Zellner and Hong)
        Random_hierarchical (4) % random effect (hierarchical)
        Factor_static       (5) % static factor approach
        Factor_dynamic      (6) % dynamic factor approach
    end

end


function [b0, dt6, mmPerVox] = dtiComputeTensorFromRaw(firstDataFile, gradsFile)
% Computes diffusion tensor from raw diffusion-weighted images.
%
% [b0, dt6, mmPerVox] = dtiComputeTensorFromRaw(firstDataFile, gradsFile)
%
% Loads a whole directory of raw image files, combines them according to
% the gradient direction information in gradsFile, then computes the
% diffusion tensor. Also returns the xform that will rotate the images into
% our cannonical orientation (as close to axial as possible- see
% computeCannonicalXformFromIfile).
%
% TODO:
%
%
% HISTORY:
% 2005.05.25: RFD (bob@sirl.stanford.edu) wrote it.
%

if(~exist('gradsFile','var')), gradsFile = []; end
if(~exist('firstDataFile','var')), firstDataFile = []; end

% Load raw data, averaging repeats
%
% *** TODO: we should NOT average repeated b>0 images. Rather, we should
% fit the tensor to all the individual data points.
[img, mmPerVox, gradDirs, bVals, xformToCan] = dtiAverageRawData(firstDataFile, gradsFile);

% Compute the tensor
%
% Maybe try code in AFNI's 3dDWItoDT?
% http://afni.nimh.nih.gov/sscc/presentations/Diffusion%20Tensor.pdf


function c = spones(a);
%SPONES       Implements  spones(a)  for sparse interval matrix
%
%   c = spones(a)
%

% written  10/16/98     S.M. Rump
% modified 08/09/02     S.M. Rump  zero components inf/sup or mid/rad handled
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged
%

  if a.complex
    c = spones(spones(a.mid)+spones(a.rad));
  else
    c = spones(spones(a.inf)+spones(a.sup));
  end


function [flag] = VBA_issymmetric (X)

% // VBA toolbox //////////////////////////////////////////////////////////
%
% [flag] = VBA_issymmetric (X)
% check if X is a symmetric matrix
%
% IN:
%   - X: matrix
% OUT:
%   - flag: - true if X is symmetric
%
% /////////////////////////////////////////////////////////////////////////

try
    flag = issymmetric (X);
catch
    flag = isequal (X, X');
end


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defmethod @@sym atanh (@var{x})
%% Symbolic atanh function.
%%
%% Example:
%% @example
%% @group
%% syms x
%% y = atanh (x)
%%   @result{} y = (sym) atanh(x)
%% @end group
%% @end example
%%
%% Note: this file is autogenerated: if you want to edit it, you might
%% want to make changes to 'generate_functions.py' instead.
%%
%% @end defmethod

function y = atanh(x)
  if (nargin ~= 1)
    print_usage ();
  end
  y = elementwise_op ('atanh', x);
end

%!error atanh (sym(1), 2)
%!assert (isequaln (atanh (sym(nan)), sym(nan)))

%!shared x, d
%! d = 1/2;
%! x = sym('1/2');

%!test
%! f1 = atanh(x);
%! f2 = atanh(d);
%! assert( abs(double(f1) - f2) < 1e-15 )

%!test
%! D = [d d; d d];
%! A = [x x; x x];
%! f1 = atanh(A);
%! f2 = atanh(D);
%! assert( all(all( abs(double(f1) - f2) < 1e-15 )))

%!test
%! % round trip
%! y = sym('y');
%! A = atanh (d);
%! f = atanh (y);
%! h = function_handle (f);
%! B = h (d);
%! assert (A, B, -eps)


function dimAdjust = getDimAdjust(L)
%GETDIMADJUST   Adjust dimension of discretization.
%   GETDIMADJUST(L) returns zero unless L is a LINOP.
%
%   A = GETDIMADJUST(L), where L is a LINOP,  returns a matrix of values, A, of
%   the same dimension as L.BLOCKS, which informs discretization methods how
%   the dimension L.DIM of that block must be adjusted (usually increased) so
%   that the highest order derivatives of each of the variables appearing in
%   the LINOP system are discretized at the same dimension.

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

if ( ~isa(L, 'linop') )

    % No adjustment
    dimAdjust = 0;

else

    % The input adjustment size of the (j,k) entry is max(diffOrder(:,k))
    dimAdjust = max(getDiffOrder(L), [], 1);
    dimAdjust = max(dimAdjust, 0);
    dimAdjust = repmat(dimAdjust, size(L, 1), 1);

end

end


function x = jpeg2im(y)
%JPEG2IM Decodes an IM2JPEG compressed image.
%   X = JPEG2IM(Y) decodes compressed image Y, generating
%   reconstructed approximation X.  Y is a structure generated by
%   IM2JPEG.
%
%   See also IM2JPEG.

%   Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
%   Digital Image Processing Using MATLAB, Prentice-Hall, 2004
%   $Revision: 1.4 $  $Date: 2003/10/26 18:39:08 $

error(nargchk(1, 1, nargin));             % Check input arguments

m = [16 11  10  16  24  40  51  61        % JPEG normalizing array
     12  12  14  19  26  58  60  55       % and zig-zag reordering
     14  13  16  24  40  57  69  56       % pattern.
     14  17  22  29  51  87  80  62
     18  22  37  56  68  109 103 77
     24  35  55  64  81  104 113 92
     49  64  78  87  103 121 120 101
     72  92  95  98  112 100 103 99];

order = [1 9  2  3  10 17 25 18 11 4  5  12 19 26 33  ...
        41 34 27 20 13 6  7  14 21 28 35 42 49 57 50  ...
        43 36 29 22 15 8  16 23 30 37 44 51 58 59 52  ...
        45 38 31 24 32 39 46 53 60 61 54 47 40 48 55  ...
        62 63 56 64];
rev = order;                          % Compute inverse ordering
for k = 1:length(order)
   rev(k) = find(order == k);
end

m = double(y.quality) / 100 * m;      % Get encoding quality.
xb = double(y.numblocks);             % Get x blocks.
sz = double(y.size);
xn = sz(2);                           % Get x columns.
xm = sz(1);                           % Get x rows.
x = huff2mat(y.huffman);              % Huffman decode.
eob = max(x(:));                      % Get end-of-block symbol

z = zeros(64, xb);   k = 1;           % Form block columns by copying
for j = 1:xb                          % successive values from x into
   for i = 1:64                       % columns of z, while changing
      if x(k) == eob                  % to the next column whenever
         k = k + 1;   break;          % an EOB symbol is found.
      else
         z(i, j) = x(k);
         k = k + 1;
      end
   end
end

z = z(rev, :);                                 % Restore order
x = col2im(z, [8 8], [xm xn], 'distinct');     % Form matrix blocks
x = blkproc(x, [8 8], 'x .* P1', m);           % Denormalize DCT
t = dctmtx(8);                                 % Get 8 x 8 DCT matrix
x = blkproc(x, [8 8], 'P1 * x * P2', t', t);   % Compute block DCT-1
x = uint8(x + 128);                            % Level shift


function im_merged = mergeAvg(varargin)
% Average merging on channels
% Support a changing number of inputs
% Merge via Euclidean norm
im_merged = sqrt(sum(cat(3, varargin{:}).^2, 3));
end


function out = simplifyMap(map, scalling)
% rescale map

mapB = map;
[a,b] = size(mapB);
out = zeros(a/scalling,b/scalling);
[c,d] = size(out);

s = scalling;
a = floor((scalling-1)/2);
b = scalling - a;

for x=1:1:c-1
    for y=1:1:d-1
        tmp = sum( sum(  mapB( x*s-a:x*s+b, y*s-a:y*s+b  )   ));
        if tmp<12
            out(x,y) = 0;
        else
            out(x,y) = 1;
        end
    end
end


function m = multiplicity(mori,varargin)
% multiplicity of a misorientation
%
% Syntax
%   m = multiplicity(mori)
%
% Input
%  mori - mis@orientation
%
% Output
%  m - integer
%

m = numSym(mori.CS) * numSym(mori.SS) ./ ...
  length(unique(symmetrise(mori),'noSymmetry'));


function test_scalingfactor

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY ft_scalingfactor ft_convert_units

% since the function to test is in a private directory, we explicitely have to cd into that directory
[ftver, ftpath] = ft_version;
cd(fullfile(ftpath, 'utilities', 'private'));

assert(ft_scalingfactor('m', 'mm') == 1000);
assert(ft_scalingfactor('mm', 'm') == 0.001);
assert(ft_scalingfactor('T/cm', 'fT/m') == 1e17);


function S = Diffmaps(S,varargin)

%% S = Diffmaps(S)
%% Returns component maps in S.DiffMap
%% S.DiffMap contains an m by n by j matrix with m and n being the x and
%% y pixel values, and j being the jth component map
%%
%% Stacks must be imported, aligned and converted to OD using ProcDir.m and
%% AlignOD.m
%%
%% COMPONENTS:
%% j=1 -- inorganic
%% j=2 -- potassium
%% j=3 -- sp2
%% j=4 -- CO3
%% j=5 -- carboxylic acid
%%
%% Example input
%% S =
%%
%%     eVenergy: [95x1 double]
%%       Xvalue: 4
%%       Yvalue: 4
%%       spectr: [67x67x95 double]  %% this is stack data!
%%     particle: '70202041'
%%
if isempty(varargin)
    spThresh=0.35;
    figsav=0;
elseif length(varargin)==1
    spThresh=varargin{1};
    figsav=0;
elseif length(varargin)==3
    spThresh=varargin{1};
    figsav=1;
    rootdir=varargin{2};
    sample=varargin{3};
end

stack=S.spectr;energy=S.eVenergy;particle=S.particle;

DiffMap=zeros(size(stack,1),size(stack,2),5);

peakregion1=find(energy > min(energy) & energy < 283);  %% Pre edge
if isempty(peakregion1)
    S.DiffMap=[];
    S.LabelMat=[];
    beep
    disp('This isnt the carbon edge');
    return
end

%% map inorganics
Preedge=mean(stack(:,:,peakregion1),3); %% compute average.
Preedge(Preedge==Inf)=0;
DetectThresh=3*mean(mean(std(stack(:,:,peakregion1),0,3)));
DiffMap(:,:,1)=ConstThresh(Preedge,DetectThresh);
DiffMap(:,:,1)=InorgMap1(S,DetectThresh,DiffMap(:,:,1));
Inorg=DiffMap(:,:,1);
DiffMap(DiffMap<.5 | DiffMap==NaN | DiffMap==Inf)=0;
DiffMap(:,:,1)=medfilt2(DiffMap(:,:,1));

postidx=find(energy > 315 & energy < 320);
postedge=mean(stack(:,:,postidx),3);

%% Potassium Map
% IaIdx=find(energy > 294 & energy < 295);  %% define first baseline point
IbIdx=find(energy > 302 & energy < 305);  %% second baseline point
DiffMap(:,:,2)=PeakDetect(S,[294,295],[302,305],[296.1,298.1],[298.6,301],[292,296],3);
DiffMap(:,:,2)=medfilt2(DiffMap(:,:,2));

%% 285 eV sp2 peak Minus post edge Map
ECpeakpos=find(energy > 284.75 & energy < 285.9);
Tmp=PeakDetect(S,[energy(1),energy(1)+1],[282,283],...
    [284.75,285.9],[284.75,285.9],[energy(1),283],6);
da=diff(stack(:,:,peakregion1),1,3);
de=diff(energy(peakregion1));
dade=zeros(size(stack(:,:,peakregion1)));
for i=1:length(de)
    dade(:,:,i)=da(:,:,i)./de(i);
end
avdade=mean(dade,3);
newstack=stack;
dep=diff(energy);
% calculate y intercept of preedge
for i=1:length(peakregion1)
    b(:,:,i)=stack(:,:,i)-avdade.*energy(i);
end
avb=mean(b,3);
% subtract linear preedge obtained above
for i=1:length(energy)
    newstack(:,:,i)=stack(:,:,i)-(avdade.*energy(i)+avb);
end

Tot = [280,310];
CCPeak = [284,287];
totidx=find(energy > Tot(1) & energy < Tot(2));
CCidx=find(energy > CCPeak(1) & energy < CCPeak(2));
Atot=trapz(energy(totidx),newstack(:,:,totidx),3);
ACC=trapz(energy(CCidx),newstack(:,:,CCidx),3);
sp2out=ACC./Atot.*8.6;
sp2out=medfilt2(sp2out.*Tmp);
sp2out(sp2out>1)=1;
sp2out(sp2out<0)=0;  %% sp2out is what is shown in the plot
Tmp=sp2out;

Tmp(Tmp<spThresh)=0; %% threshold map for output into partlabel.
DiffMap(:,:,3)=Tmp;
DiffMap(DiffMap(:,:,3)<0 | DiffMap(:,:,3)==NaN)=0;

% Post Edge Minus Pre Edge Map (total carbon)

% DiffMap(:,:,4)=medfilt2(negfilter(postedge(:,:)-Preedge));
% T.DiffMap=DiffMap;

%% CO3 Map

% DiffMap(:,:,4)=PeakDetect(S,[289.3,289.8],[291.1,292.5],...
%     [290.1,290.6],[290.1,290.6],[291.6,293.5]);
DiffMap(:,:,4)=PeakDetect(S,[289.3,289.8],[291.1,292.5],...
    [290.1,290.6],[290.1,290.6],[energy(1),283],6);
DiffMap(:,:,4)=medfilt2(DiffMap(:,:,4));
%% carboxylic map
CarbxIdx=find(energy > 288 & energy < 289);  %% define first baseline point
ICarbx=mean(stack(:,:,IbIdx),3);
ICarbx(ICarbx<DetectThresh)=0;
DiffMap(:,:,5)=ICarbx-Preedge;
tmp=DiffMap(:,:,5);
tmp(tmp<0 | isnan(tmp))=0;
tmp=medfilt2(tmp);
DiffMap(:,:,5)=tmp;

MatSiz=size(S.spectr);
XSiz=S.Xvalue/MatSiz(1);
YSiz=S.Yvalue/MatSiz(2);
xdat=[0:XSiz:S.Xvalue];
ydat=[0:YSiz:S.Yvalue];

%% Show DiffMaps
figure1=figure('Name',particle,'NumberTitle','off','Position',[1,1,715,869]);
title(sprintf(S.particle));
subplot(3,2,1)
plotIn=DiffMap(:,:,1);
plotIn(plotIn>3)=3;
imagesc(xdat,ydat,plotIn)
axis image
title('Inorganic')
colorbar
xlabel('X (\mum)');
ylabel('Y (\mum)');

subplot(3,2,2)
imagesc(xdat,ydat,DiffMap(:,:,2))
axis image
title('Potassium')
colorbar
xlabel('X (\mum)');
ylabel('Y (\mum)');

subplot(3,2,3)
% imagesc(xdat,ydat,DiffMap(:,:,3))
imagesc(xdat,ydat,sp2out)
axis image
title('Sp^{2}')
colorbar
xlabel('X (\mum)');
ylabel('Y (\mum)');

subplot(3,2,4)
imagesc(xdat,ydat,DiffMap(:,:,5))
axis image
% colormap('gray')
title('Carbox')
colorbar
xlabel('X (\mum)');
ylabel('Y (\mum)');

subplot(3,2,5)
imagesc(xdat,ydat,DiffMap(:,:,4))
axis image
title('CO_{3}')
colorbar
xlabel('X (\mum)');
ylabel('Y (\mum)');

subplot(3,2,6)

PartIm=DiffMap(:,:,5)+Preedge+DiffMap(:,:,3);
LabelMat=raw2mask(S);
title('Particle Map')
colorbar
axis image
xlabel('X (\mum)');
ylabel('Y (\mum)');

if figsav==1
filename=sprintf('%s%s%s%s',rootdir,sample,S.particle,'_f1_map');
saveas(gcf,filename,'tiff');
end

S=S;
S.DiffMap=DiffMap;
S.LabelMat=LabelMat;


function [cluster, total] = findcluster(onoff, spatdimneighbstructmat, varargin)

% FINDCLUSTER returns all connected clusters in a 3 dimensional matrix
% with a connectivity of 6.
%
% Use as
%   [cluster, num] = findcluster(onoff, spatdimneighbstructmat, minnbchan)
% or ar
%   [cluster, num] = findcluster(onoff, spatdimneighbstructmat, spatdimneighbselmat, minnbchan)
% where
%   onoff                   is a 3D boolean matrix with size N1xN2xN3
%   spatdimneighbstructmat  defines the neighbouring channels/combinations, see below
%   minnbchan               the minimum number of neighbouring channels/combinations
%   spatdimneighbselmat     is a special neighbourhood matrix that is used for selecting
%                           channels/combinations on the basis of the minnbchan criterium
%
% The neighbourhood structure for the first dimension is specified using
% spatdimneighbstructmat, which is a 2D (N1xN1) matrix. Each row and each column corresponds
% to a channel (combination) along the first dimension and along that row/column, elements
% with "1" define the neighbouring channel(s) (combinations). The first dimension of
% onoff should correspond to the channel(s) (combinations).
%
% See also SPM_BWLABEL (spm toolbox)

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

spatdimlength = size(onoff, 1);
nfreq = size(onoff, 2);
ntime = size(onoff, 3);

if length(size(spatdimneighbstructmat))~=2 || ~all(size(spatdimneighbstructmat)==spatdimlength)
  ft_error('invalid dimension of spatdimneighbstructmat');
end

minnbchan=0;
if length(varargin)==1
    minnbchan=varargin{1};
end
if length(varargin)==2
    spatdimneighbselmat=varargin{1};
    minnbchan=varargin{2};
end

if minnbchan>0
    % For every (time,frequency)-element, it is calculated how many significant
    % neighbours this channel has. If a significant channel has less than minnbchan
    % significant neighbours, then this channel is removed from onoff.

    if length(varargin)==1
        selectmat = single(spatdimneighbstructmat | spatdimneighbstructmat');
    end
    if length(varargin)==2
        selectmat = single(spatdimneighbselmat | spatdimneighbselmat');
    end
    nremoved=1;
    while nremoved>0
        nsigneighb=reshape(selectmat*reshape(single(onoff),[spatdimlength (nfreq*ntime)]),[spatdimlength nfreq ntime]);
        remove=(onoff.*nsigneighb)<minnbchan;
        nremoved=length(find(remove.*onoff));
        onoff(remove)=0;
    end
end

% for each channel (combination), find the connected time-frequency clusters
labelmat = zeros(size(onoff));
total = 0;
if nfreq*ntime>1
  for spatdimlev=1:spatdimlength
    [labelmat(spatdimlev, :, :), num] = spm_bwlabel(double(reshape(onoff(spatdimlev, :, :), nfreq, ntime)), 6); % the previous code contained a '4' for input
    labelmat(spatdimlev, :, :) = labelmat(spatdimlev, :, :) + (labelmat(spatdimlev, :, :)~=0)*total;
    total = total + num;
  end
else
  labelmat(onoff>0) = 1:sum(onoff(:));
  total = sum(onoff(:));
end
% combine the time and frequency dimension for simplicity
labelmat = reshape(labelmat, spatdimlength, nfreq*ntime);

% combine clusters that are connected in neighbouring channel(s)
% (combinations). Convert inputs to uint32 as that is required by the mex
% file (and the values will be positive integers anyway).
cluster = combineClusters(uint32(labelmat), logical(spatdimneighbstructmat), uint32(total));

% reshape the output to the original format of the data
cluster = reshape(cluster, spatdimlength, nfreq, ntime);

% update the total number
total = numel(unique(cluster(:)))-1; % the value of 0 does not count


function [k, gk, kern] = pathKernDiagCompute(kern, x)

% PATHKERNDIAGCOMPUTE Compute diagonal of PATH kernel.
% FORMAT
% DESC computes the diagonal of the kernel matrix for the path kernel given a design matrix of inputs.
% ARG kern : the kernel structure for which the matrix is computed.
% ARG x : input data matrix in the form of a design matrix.
% RETURN k : a vector containing the diagonal of the kernel matrix
% RETURN gk : evaluation of ground kernel
% RETURN kern: updated kernel structure
% computed at the given points.
%
% SEEALSO : pathKernParamInit, kernDiagCompute, kernCreate, pathKernCompute
%
% COPYRIGHT : Andrea Baisero, Carl Henrik Ek, 2013

% SHEFFIELDML

maxl=max(cellfun(@(x)size(x,1),x));
kern=pathKernUpdateWMat(kern,maxl);

num=length(x);

gk=cell(1,num);
k=zeros(1,num);
for i=1:num
    li=size(x{i},1);
    w=kern.wmat(1:li,1:li);
    w=.5*(w+w(end:-1:1,end:-1:1));

    gk{i}=kernCompute(kern.gkern,x{i});
    k(i)=sum(sum(w.*gk{i}));
end


function ssmult_demo
%SSMULT_DEMO simple demo for ssmult.
%
% Example:
%   ssmult_demo
%
% See also ssmult, ssmult_unsorted, ssmultsym, sstest, sstest2.

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

type ssmult_demo
load west0479
A = west0479 ;
B = sprand (A) ;
C = A*B ;
D = ssmult (A,B) ;
err = norm (C-D,1) / norm (C,1) ;
fprintf ('ssmult west0479 error: %g\n', err) ;


function p = TimeExcludeRanges(tInc,t)

p=[];
mdiff = diff(tInc);
tidx1 = find(mdiff==-1);
tidx2 = find(mdiff==1);

% If excluded time points are at the extremes of the time range,
% then add inflections at the beginning or end.
if tInc(1)==0
    tidx1 = [1;tidx1];
end
if tInc(end)==0
    tidx2 = [tidx2;length(tInc)];
end
% if ~isempty(tidx2) && isempty(find(tidx1<tidx2(1)))
%     tidx1 = [1; tidx1];
% end
% if ~isempty(tidx1) && isempty(find(tidx2>tidx1(end)))
%     tidx2 = [tidx2; length(tInc)];
% end

for ii=1:length(tidx1)
    if ii<=length(tidx2)
        p(ii,:) = [t(tidx1(ii)) t(tidx2(ii))];
    else
        p(ii,:) = [t(tidx1(ii)) t(end)];
    end
end


function [s,fs]=bat()
%BAT  Load the 'bat' test signal
%   Usage:  s=bat;
%
%   `bat` loads the 'bat' signal. It is a 400 samples long recording
%   of a bat chirp sampled with a sampling period of 7 microseconds.
%   This gives a sampling rate of 143 kHz.
%
%   `[sig,fs]=bat` additionally returns the sampling frequency *fs*.
%
%   The signal can be obtained from
%   `<http://dsp.rice.edu/software/bat-echolocation-chirp>`_
%
%   Please acknowledge use of this data in publications as follows:
%
%     The author wishes to thank Curtis Condon, Ken White, and Al Feng of
%     the Beckman Institute of the University of Illinois for the bat data
%     and for permission to use it in this paper.
%
%   Examples:
%   ---------
%
%   Plot of 'bat' in the time-domain:::
%
%     plot((1:400)/143000,bat);
%     xlabel('Time (seconds)');
%     ylabel('Amplitude');
%
%   Plot of 'bat' in the frequency-domain:::
%
%     plotfftreal(fftreal(bat),143000,90);
%
%   Plot of 'bat' in the time-frequency-domain:::
%
%     sgram(bat,143000,90);
%
%   See also:  batmask

%   AUTHOR : Peter L. Søndergaard
%   TESTING: TEST_SIGNALS
%   REFERENCE: OK

if nargin>0
  error('This function does not take input arguments.')
end;

f=mfilename('fullpath');

s=load('-ascii',[f,'.asc']);
fs=143000;