function [ value, t ] = r4_random ( t, n )

%*****************************************************************************80
%
%% R4_RANDOM is a portable pseudorandom number generator.
%
%  Discussion:
%
%    This random number generator is portable amoung a wide variety of
%    computers.  It generates a random number between 0.0 and 1.0
%    according to the algorithm presented by Bays and Durham.
%
%    The motivation for using this scheme, which resembles the
%    Maclaren-Marsaglia method, is to greatly increase the period of the
%    random sequence.  If the period of the basic generator is P,
%    then the expected mean period of the sequence generated by this
%    generator is given by
%
%      new mean P = sqrt ( pi * factorial ( N ) / ( 8 * P ) ),
%
%    where factorial ( N ) must be much greater than P in this
%    asymptotic formula.  Generally, N should be 16 to maybe 32.
%
%  Modified:
%
%    25 September 2011
%
%  Author:
%
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Carter Bays, Stephen Durham,
%    Improving a Poor Random Number Generator,
%    ACM Transactions on Mathematical Software,
%    Volume 2, Number 1, March 1976, pages 59-64.
%
%  Parameters:
%
%    Input, integer N.  The absolute value of N is the number
%    of random numbers in an auxiliary table.  Note though that abs(N)+1 is
%    the number of items in array T.  If N is positive and differs from its
%    value in the previous invocation, then the table is initialized for
%    the new value of N.  If N is negative, abs(N) is the number of items
%    in an auxiliary table, but the tables are now assumed already to
%    be initialized.  This option enables the user to save the table T at
%    the end of a long computer run and to restart with the same sequence.
%    Normally, this function would be called at most once with negative N.
%    Subsequent invocations would have N positive and of the correct magnitude.
%
%    Input/output, real T(abs(N)+1), an array of random numbers
%    from a previous invocation of this function.  Whenever N is positive
%    and differs from the old N, the table is initialized.  The first
%    abs(N) numbers are the table discussed in the reference, and the
%    last value is Y.  This array may be saved in order to restart a sequence.
%
%    Output, real VALUE, a random number between 0.0 and 1.0.
%
  persistent floatn
  persistent nold

  if ( isempty ( floatn ) )
    floatn = -1.0;
    nold = -1;
  end

  if ( n ~= nold )

    nold = abs ( n );
    floatn = nold;

    if ( n < 0 )

      dummy = r4_rand ( t(nold+1) );

    else

      for i = 1 : nold
        t(i) = r4_rand ( 0.0 );
      end
      t(nold+1) = r4_rand ( 0.0 );

    end

  end

  j = r4_aint ( t(nold+1) * floatn + 1.0 );
  t(nold+1) = t(j);
  r4_random = t(j);
  t(j) = r4_rand ( 0.0 );

  return
end


%% Copyright (C) 2016-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
%% @defun logint (@var{x})
%% Numerical logint function.
%%
%% Example:
%% @example
%% @group
%% logint (1.1)
%%   @result{} ans = -1.6758
%% @end group
%% @end example
%%
%% @strong{Note} this function may be slow for large numbers of inputs.
%% This is because it is not a native double-precision implementation
%% but rather the numerical evaluation of the Python @code{mpmath} function
%% @code{li}.
%%
%% Note: this file is autogenerated: if you want to edit it, you might
%% want to make changes to 'generate_functions.py' instead.
%%
%% @seealso{@@sym/logint}
%% @end defun

function y = logint (x)
  if (nargin ~= 1)
    print_usage ();
  end
  cmd = { 'L = _ins[0]'
          'A = [complex(mpmath.li(x)) for x in L]'
          'return A,' };
  c = pycall_sympy__ (cmd, num2cell (x(:)));
  y = reshape (cell2mat (c), size (x));
end

%!error logint (1, 2)

%!test
%! x = 1.1;
%! y = sym(11)/10;
%! A = logint (x);
%! B = double (logint (y));
%! assert (A, B, -4*eps);

%!test
%! y = [2 3 sym(pi); exp(sym(1)) 5 6];
%! x = double (y);
%! A = logint (x);
%! B = double (logint (y));
%! assert (A, B, -4*eps);

%!test
%! % maple:
%! % > A := [1+2*I, -2 + 5*I, 100, 10*I, -1e-4 + 1e-6*I, -20 + I];
%! % > for a in A do evalf(Li(a)) end do;
%! x = [1+2i; -2+5i; 100; 10i; -1e-4 + 1e-6*1i; -20-1i];
%! A = [  1.3876787420229375511 + 2.5087546988592328752*1i
%!        1.6987684473874802274 + 4.5936366057115204667*1i
%!        30.126141584079629926
%!        3.4936715673748995398 + 5.5260023797127391973*1i
%!        0.90264689772681592152e-5 + 3.1415953634267361942*1i
%!       -2.3996350854560916779 - 7.6971739096353664559*1i ];
%! B = logint (x);
%! assert (A, B, -eps)

%!assert (logint (inf), inf)
%!assert (isnan (logint (-inf)))


% evaluate simulated data - ICA and NMF
% V ~ WH
% V -> N_pix x N_t
% W -> N_pix x N_comp - xth pixel of the ith components
% H -> N_copm x N_t - contribution of the i-th component in the time t

function separNMFICA(sep0, offset0, path_data, path_res, prename, niter, savethis, initval, sep_how)

if ~exist('initval', 'var')
    initval = 0;
end

if ~exist('sep_how', 'var')
    sep_how = 'in';
end
ncomp = 3; %number of components to be separated + background

for rr = 1: length(offset0)
    for ll=1 : length(sep0)
        namedir = [prename num2str(100*sep0(ll)) 'offset_' num2str(offset0(rr))];
        cd ([path_data namedir])
        for mm=1:niter
            %reads the first...
            namefile = [namedir '-iter_' num2str(mm)];
            load ([namefile '.mat'])
            %cat the folowing,,,
            p.catitervec=[1];
            [dpixc, dveccr, blinkmat, p] = catsimul(namedir, p.catitervec);
            if sum(sep_how == 'i')>0 %ICA
                [icasig{mm}, A{mm}, W{mm}] = fastica (dveccr, 'numOfIC', ncomp, 'g', 'tanh');
                icapixICA{mm} = reshape(A{mm},p.nx, p.ny, ncomp);
            end

            if sum(sep_how == 'n')>0 %NMF
                if initval
                    % background estimation:
                    %[out, bg(mm), bg_im]=backgroundoffset(dpixc);
                    [out, bg(mm), bg_im]=backgroundoffset(dpixc, 'no', 5, 20, 8); %empirical values...

                    dvec_bg = ones(p.nx*p.ny, 1);
                    %                     dvec_bg = p.offset*ones(1, p.nx*p.ny); %changed for
                    %                     offset 10...

                    dvec_ind = squeeze(reshape(double(array2im(dpixc_ind)), p.nx*p.ny, 1, 2)); % vectors of resized images
%                     sum_dvec_ind = sum(dvec_ind, 1);
%                     dvec_ind = dvec_ind./repmat(sum_dvec_ind, p.nx*p.ny,1); %normlaized

                    %                     winit = [f*dvec_ind'; dvec_bg];       %original 'true' points + background
% % %                     winittmp = [dvec_ind, dvec_bg];
                    winittmp = [rand(size(dvec_ind)), dvec_bg];
                    sumw = sum(winittmp,1);
                    winit = winittmp./repmat(sumw, p.nx*p.ny, 1); %normalized to 1
                    f = mean(dveccr(:)-bg(mm))/mean(mean(winit(:, 1:2))); %ration of the data/psf
                    %                     winit = [rand(ncomp, p.nx*p.ny); dvec_bg];
                    blinkmatrand = rand(ncomp-1, p.Nt); %uniform random;
                    hinit = [f*blinkmatrand; bg(mm)*sumw(ncomp)*ones(1, p.Nt)];             %random weights will be assigned to firts two and bg fixed
% % %                     hinit = [f*blinkmat./repmat(mean(blinkmat,2),1,size(blinkmat,2)); bg(mm)*sumw(ncomp)*ones(1, p.Nt)];             %random weights will be assigned to firts two and bg fixed

                    %                    [w{mm},h{mm}, wtrace{mm},wtrace{mm}]=nmf_test(double(dveccr'),ncomp+1,1,hinit,winit, [3], [3]);
                    %                     [w{mm},h{mm}, wtrace,htrace,ddiv{mm}]=nmf_testconvD(double(dveccr'),ncomp+1,1,hinit,winit, [3], [3]);
                    [c,w{mm},h{mm}, X1,X2, dhr, minXr, miXvalr, xcovpeakr, meanabsxcr,mhdr, p]=nmf_S41(double(dveccr),ncomp,1,winit,hinit, [3], [3],p);

                    hinit = [f*blinkmat./repmat(mean(blinkmat,2),1,size(blinkmat,2)); bg(mm)*sumw(ncomp)*ones(1, p.Nt)];             %random weights will be assigned to firts two and bg fixed
                    [c,w{mm},h{mm}, X1,X2, dht, minXt, miXvalt, xcovpeakt, meanabsxct,mhdt, p]=nmf_S41(double(dveccr),ncomp,1,winit,hinit, [3], [3],p);
                    qqq=[];
                else
                    [w{mm},h{mm}]=nmf(double(dveccr'),ncomp,1);
                end
                icapixNMF{mm} = reshape(w{mm},p.nx,p.ny,ncomp);
            end

        end

        p.path_data = path_data;
        p.path_res = path_res;

        if savethis == 1
            fprintf('saving data \n');
            if ~(strcmp(path_res, path_data)) %not identical
                mkdir ([path_res namedir]);
                cd ([path_res namedir]);
            end
            %             save (p.namedir)
            save ([namedir '_separMulti'],'p', 'X1','X2','dhr','minXr', 'miXvalr','dht','minXt', 'miXvalt', 'xcovpeakr', 'meanabsxcr','mhdr', 'xcovpeakt', 'meanabsxct','mhdt')
            writedata([],[],p,[namedir '_param'])
        end
    end
end

fprintf('\n')


function [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y, ellipsoid)
%TRANMERC_INV  Inverse transverse Mercator projection
%
%   [LAT, LON] = TRANMERC_INV(LAT0, LON0, X, Y)
%   [LAT, LON, GAM, K] = TRANMERC_INV(LAT0, LON0, X, Y, ELLIPSOID)
%
%   performs the inverse transverse Mercator projection of points (X,Y) to
%   (LAT,LON) using (LAT0,LON0) as the center of projection.  These input
%   arguments can be scalars or arrays of equal size.  The ELLIPSOID vector
%   is of the form [a, e], where a is the equatorial radius in meters, e is
%   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
%   precisely, the value returned by DEFAULTELLIPSOID) is used.  GEODPROJ
%   defines the projection and gives the restrictions on the allowed ranges
%   of the arguments.  The forward projection is given by TRANMERC_FWD.
%
%   GAM and K give metric properties of the projection at (LAT,LON); GAM is
%   the meridian convergence at the point and K is the scale.
%
%   LAT0, LON0, LAT, LON, GAM are in degrees.  The projected coordinates X,
%   Y are in meters (more precisely the units used for the equatorial
%   radius).  K is dimensionless.
%
%   This implementation of the projection is based on the series method
%   described in
%
%     C. F. F. Karney, Transverse Mercator with an accuracy of a few
%     nanometers, J. Geodesy 85(8), 475-485 (Aug. 2011);
%     Addenda: http://geographiclib.sf.net/tm-addenda.html
%
%   This extends the series given by Krueger (1912) to sixth order in the
%   flattening.  This is a substantially better series than that used by
%   the MATLAB mapping toolbox.  In particular the errors in the projection
%   are less than 5 nanometers withing 3900 km of the central meridian (and
%   less than 1 mm within 7600 km of the central meridian).  The mapping
%   can be continued accurately over the poles to the opposite meridian.
%
%   This routine depends on the MATLAB File Exchange package "Geodesics on
%   an ellipsoid of revolution":
%
%     http://www.mathworks.com/matlabcentral/fileexchange/39108
%
%   See also GEODPROJ, TRANMERC_FWD, GEODRECKON, DEFAULTELLIPSOID.

% Copyright (c) Charles Karney (2012) <charles@karney.com>.
%
% This file was distributed with GeographicLib 1.29.

  if nargin < 4, error('Too few input arguments'), end
  if nargin < 5, ellipsoid = defaultellipsoid; end
  try
    Z = lat0 + lon0 + x + y;
    Z = zeros(size(Z));
  catch err
    error('lat0, lon0, x, y have incompatible sizes')
  end
  if length(ellipsoid(:)) ~= 2
    error('ellipsoid must be a vector of size 2')
  end

  degree = pi/180;
  maxpow = 6;

  a = ellipsoid(1);
  f = ecc2flat(ellipsoid(2));
  e2 = f * (2 - f);
  e2m = 1 - e2;
  cc = sqrt(e2m) * exp(e2 * atanhee(1, e2));
  n = f / (2 -f);
  bet = betf(n);
  b1 = (1 - f) * (A1m1f(n) + 1);
  a1 = b1 * a;

  if isscalar(lat0) && lat0 == 0
    y0 = 0;
  else
    [sbet0, cbet0] = SinCosNorm((1-f) * sind(lat0), cosd(lat0));
    y0 = a1 * (atan2(sbet0, cbet0) + ...
               SinCosSeries(true, sbet0, cbet0, C1f(n)));
  end
  y = y + y0;

  xi = y / a1;
  eta = x / a1;
  xisign = 1 - 2 * (xi < 0 );
  etasign = 1 - 2 * (eta < 0 );
  xi = xi .* xisign;
  eta = eta .* etasign;
  backside = xi > pi/2;
  xi(backside) = pi - xi(backside);

  c0 = cos(2 * xi); ch0 = cosh(2 * eta);
  s0 = sin(2 * xi); sh0 = sinh(2 * eta);
  ar = 2 * c0 .* ch0; ai = -2 * s0 .* sh0;
  j = maxpow;
  xip0 = Z; yr0 = Z;
  if mod(j, 2)
    xip0 = xip0 + bet(j);
    yr0 = yr0 - 2 * maxpow * bet(j);
    j = j - 1;
  end
  xip1 = Z; etap0 = Z; etap1 = Z;
  yi0 = Z; yr1 = Z; yi1 = Z;
  for j = j : -2 : 1
    xip1  = ar .* xip0 - ai .* etap0 - xip1 - bet(j);
    etap1 = ai .* xip0 + ar .* etap0 - etap1;
    yr1 = ar .* yr0 - ai .* yi0 - yr1 - 2 * j * bet(j);
    yi1 = ai .* yr0 + ar .* yi0 - yi1;
    xip0  = ar .* xip1 - ai .* etap1 - xip0 - bet(j-1);
    etap0 = ai .* xip1 + ar .* etap1 - etap0;
    yr0 = ar .* yr1 - ai .* yi1 - yr0 - 2 * (j-1) * bet(j-1);
    yi0 = ai .* yr1 + ar .* yi1 - yi0;
  end
  ar = ar/2; ai = ai/2;
  yr1 = 1 - yr1 + ar .* yr0 - ai .* yi0;
  yi1 =   - yi1 + ai .* yr0 + ar .* yi0;
  ar = s0 .* ch0; ai = c0 .* sh0;
  xip  = xi  + ar .* xip0 - ai .* etap0;
  etap = eta + ai .* xip0 + ar .* etap0;
  gam = atan2(yi1, yr1);
  k = b1 ./ hypot(yr1, yi1);
  s = sinh(etap);
  c = max(0, cos(xip));
  r = hypot(s, c);
  lam = atan2(s, c);
  taup = sin(xip)./r;
  tau = tauf(taup, e2);
  phi = atan(tau);
  gam = gam + atan(tan(xip) .* tanh(etap));
  c = r ~= 0;
  k(c) = k(c) .* sqrt(e2m + e2 * cos(phi(c)).^2) .* ...
         hypot(1, tau(c)) .* r(c);
  c = ~c;
  if any(c)
    phi(c) = pi/2;
    lam(c) = 0;
    k(c) = k(c) * cc;
  end
  lat = phi / degree .* xisign;
  lon = lam / degree;
  lon(backside) = 180 - lon(backside);
  lon = lon .* etasign;
  lon = AngNormalize(lon + AngNormalize(lon0));
  gam = gam/degree;
  gam(backside) = 180 - gam(backside);
  gam = gam .* xisign .* etasign;
end

function bet = betf(n)
  bet = zeros(1,6);
  nx = n^2;
  bet(1) = n*(n*(n*(n*(n*(384796*n-382725)-6720)+932400)-1612800)+ ...
              1209600)/2419200;
  bet(2) = nx*(n*(n*((1695744-1118711*n)*n-1174656)+258048)+80640)/ ...
           3870720;
  nx = nx * n;
  bet(3) = nx*(n*(n*(22276*n-16929)-15984)+12852)/362880;
  nx = nx * n;
  bet(4) = nx*((-830251*n-158400)*n+197865)/7257600;
  nx = nx * n;
  bet(5) = (453717-435388*n)*nx/15966720;
  nx = nx * n;
  bet(6) = 20648693*nx/638668800;
end

function tau = tauf(taup, e2)
  overflow = 1/eps^2;
  tol = 0.1 * sqrt(eps);
  numit = 5;
  e2m = 1 - e2;
  tau = taup / e2m;
  stol = tol * max(1, abs(taup));
  g = ~(abs(taup) < overflow);
  tau(g) = taup(g);
  g = ~g;
  for i = 1 : numit
    if ~any(g), break, end
    tau1 = hypot(1, tau);
    sig = sinh(e2 * atanhee( tau ./ tau1, e2 ) );
    taupa = hypot(1, sig) .* tau - sig .* tau1;
    dtau = (taup - taupa) .* (1 + e2m .* tau.^2) ./ ...
           (e2m * tau1 .* hypot(1, taupa));
    tau(g) = tau(g) + dtau(g);
    g = g & abs(dtau) >= stol;
  end
end


function LU = getbounds(F)

K.f = 0;
K.l = 0;
L = [];
U = [];
LU =  yalmip('getbounds',1:yalmip('nvars'));
F = flatten(F);
for i = 1:length(F.clauses)
    if F.clauses{i}.type == 2
        X = F.clauses{i}.data;
        AB = getbase(X);
        K.l = prod(size(X));
        variables = getvariables(X);
        [lb,ub,cand_rows] = find_lp_bounds(AB,K);
        LU(variables,1) = max([lb LU(variables,1)]')';
        LU(variables,2) = min([ub LU(variables,2)]')';
    elseif F.clauses{i}.type == 3
        % FIX : Extract from equalities and binary constraints
    end
end

binary = yalmip('binvariables');
LU(binary,1) = 0;
LU(binary,2) = 1;

% Try to bound some nonlinear terms
% FIX: complete code
[mt,variable_type] = yalmip('monomtable');
quadratic = find(variable_type == 2);
if ~isempty(quadratic)
    M = mt(quadratic,:);
    for i = 1:size(M,1)
        [ii,jj] = find(M(i,:));
        if length(ii) == 1
            LU(quadratic(i),1) = min([0 LU(jj,1)^2]);
            LU(quadratic(i),2) = max([LU(jj,1)^2 LU(jj,2)^2]);
        end
    end
end


%GOBJ_NACA Create NACA 4-series wing profile geometry object.
%
%   [ GOBJ ] = GOBJ_NACA( SERIES, P0, L, TH, N, TAG ) Creates a NACA 4-series
%   wing profile geometry object. Accepts the following input parameters.
%
%       Parameter   Value/{Default}           Description
%       -----------------------------------------------------------------------------------
%       series      string  {0012}             NACA 4-series identifier
%       p0          array   {[0,0]}            Coordinates of leading edge/point
%       l           length  {1}                Length of wing chord
%       th          scalar  {0}                Angle of attack (degrees)
%       n           integer {20}               Number of points to define shape
%       tag         string  {N1}               Geometry object tag/name

% Copyright 2013-2022 Precise Simulation, Ltd.


function PLOT_Estimator(Time, Trace_Cov, State_Error)

figure(6);
plot(Time,Trace_Cov)
title('Trace of the covariance matrix')
xlabel('Time (s)')
ylabel('Trace of Covariance')

figure(7)

subplot(4,1,1)
plot(Time, State_Error(1,:))
title('EKF Error: X position', 'FontSize',16)
xlabel('Time (s)')
ylabel('Distance (m)')

subplot(4,1,2)
plot(Time, State_Error(2,:))
title('EKF Error: Y position', 'FontSize',16)
xlabel('Time (s)')
ylabel('Distance (m)')

subplot(4,1,3)
plot(Time, State_Error(3,:))
title('EKF Error: Orientation', 'FontSize',16)
xlabel('Time (s)')
ylabel('Angle (rad)')

subplot(4,1,4)
plot(Time, State_Error(4,:))
title('EKF Error: Cab-Trailer Angle', 'FontSize',16)
xlabel('Time (s)')
ylabel('Angle (rad)')

end


function v=edge_weight_vector(As,A,varargin)
% EDGE_WEIGHT_VECTOR Returns input for the edge_weight option for a weighted
% matrix
%
% Given a structural and weighted matrix pair (As,A), this function returns
% input for the edge_weight option.  The structural matrix As can have
% arbitrary non-zero values, but the non-zero structure of A must be a
% subset of the non-zero structure of As.  In terms of graphs, think about
% it as: the weights come from A, but the edges come from As.
%
% Example:
%   n = 8; u = 1; v = 2;
%   E = [1:n 2:n 1; 2:n 1 1:n]';
%   w = [1 zeros(1,n-1) 1 zeros(1,n-1)]';
%   A = sparse(E(:,1), E(:,2), w, n, n); % create weighted sparse matrix
%   As = sparse(E(:,1), E(:,2), true, n, n); % create structural sparse matrix
%   [d pred] = shortest_paths(As,u,struct('edge_weight',edge_weight_vector(As,A)));
%   d(v)

% David Gleich
% Copyright, Stanford University, 2008

%% History
%  2008-09-24: Initial coding
%%
[trans check] = get_matlab_bgl_options(varargin{:});
if check
    check_matlab_bgl(A,struct());
    if any(size(As)~=size(A)), error('matlab_bgl:edge_weight_vector', ...
            'The structral and weight matrix must be the same size'); end
end
n = size(A,1);
if trans, [j i] = find(As');
else [i j] = find(As);
end
Ai = sparse(i,j,1:nnz(As),n,n);
inds = nonzeros(Ai.*(A~=0));
if length(inds) ~= nnz(A), error('matlab_bgl:edge_weight_vector', ...
    'The matrix A cannot have additional non-zeros not in As.'); end
v = zeros(nnz(As),1);
v(inds) = nonzeros(A);
if check && ~isequal(A,sparse(j,i,v,n,n)')
    error('matlab_bgl:edge_weight_vector','error in weight function');
end

%% Todo
% Check that is actually works with the is trans option, I'm not convinced
% the test coverage works.


function [g2vMap, distSq] = mrmMapGrayToVertices(grayNodes, vertexCoords, mmPerVox, distThresh)
%
% g2vMap = mrmMapGrayToVertices(grayNodes,vertexCoords, mmPerVox)
%
% Finds a map between all gray nodes and the mesh vertices
% To see the coordinate of a mesh node nearest to a gray node, we
% can use
%
%      initVertices(1:3,g2vMap(idx))
%
%
% HISTORY:
%  2004.03.26 ARW wade@ski.org. Based on RFD's routine mrmVerticesToGray
if notDefined('mmPerVox'), error('Voxel size (mm per vox) is required.'); end;

if notDefined('distThresh')
    if (ispref('VISTA','defaultSurfaceWMMapDist'))
        distThresh = getpref('VISTA','defaultSurfaceWMMapDist');
	else
		if prefsVerboseCheck>=1,
	       disp('No dist threhold preference set. Setting distance threshold to 2 by default');
		end
		distThresh=2;
    end

end

% The gray coordinates are in voxels in the vAnatomy file.  This scales
% them into real physical (mm) coordinates.  And transposes them.
grayCoords = grayNodes([1,2,3], :);
grayCoords = [grayCoords(1,:).*mmPerVox(1); ...
        grayCoords(2,:).*mmPerVox(2); ...
        grayCoords(3,:).*mmPerVox(3) ]';

% Transposes these mesh coordinates, which were already built in real
% physical coordinates.
% Major comments needed here.
vertexCoords = vertexCoords' + 1;

[g2vMap,distSq]=nearpoints(double(grayCoords'),vertexCoords');
badPoints=find(distSq>(distThresh.^2));
g2vMap(badPoints)=0;

g2vMap = int32(g2vMap);

return;


function pyra = project_pyramid(model, pyra)
% pyra = project_pyramid(model, pyra)
%
% Project feature pyramid pyra onto PCA eigenvectors stored
% in model.coeff.

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

for i = 1:pyra.num_levels
  pyra.feat{i} = project(pyra.feat{i}, model.pca_coeff);
end


function [yd3] = m32yd3(m3)
% Convert volume from cubic meters to cubic yards.
% Chad Greene 2012
yd3 = m3*1.3079506193;


% this program is designed to correct the monthly variability for weather
% generator generated daily precip according to the monthly precip generated
% by FFT using a simple linear relationship

function [monthly_corrected_precip]=monthly_precip_correction(filenameout)
% load WG generated data
load(filenameout)
n=size(gP,1);

% load FFT generated monthly precip
monthly_FFT=zeros(n,12);
load('Pnew1')
monthly_FFT(:,1)=Pnew';
load('Pnew2')
monthly_FFT(:,2)=Pnew';
load('Pnew3')
monthly_FFT(:,3)=Pnew';
load('Pnew4')
monthly_FFT(:,4)=Pnew';
load('Pnew5')
monthly_FFT(:,5)=Pnew';
load('Pnew6')
monthly_FFT(:,6)=Pnew';
load('Pnew7')
monthly_FFT(:,7)=Pnew';
load('Pnew8')
monthly_FFT(:,8)=Pnew';
load('Pnew9')
monthly_FFT(:,9)=Pnew';
load('Pnew10')
monthly_FFT(:,10)=Pnew';
load('Pnew11')
monthly_FFT(:,11)=Pnew';
load('Pnew12')
monthly_FFT(:,12)=Pnew';

% calculate the monthly precip for the generated data
monthly_generated=zeros(n,12);
for i=1:n
    monthly_generated(i,1)=sum(gP(i,1:31));
    monthly_generated(i,2)=sum(gP(i,32:59));
    monthly_generated(i,3)=sum(gP(i,60:90));
    monthly_generated(i,4)=sum(gP(i,91:120));
    monthly_generated(i,5)=sum(gP(i,121:151));
    monthly_generated(i,6)=sum(gP(i,152:181));
    monthly_generated(i,7)=sum(gP(i,182:212));
    monthly_generated(i,8)=sum(gP(i,213:243));
    monthly_generated(i,9)=sum(gP(i,244:273));
    monthly_generated(i,10)=sum(gP(i,274:304));
    monthly_generated(i,11)=sum(gP(i,305:334));
    monthly_generated(i,12)=sum(gP(i,335:365));
end

% calculate the ratio of FFT generated data to WG generated data (monthly ratio)
monthly_ratio=zeros(n,12);
for i=1:n
    for j=1:12
        if monthly_generated(i,j)==0
            monthly_generated(i,j)=monthly_FFT(i,j);
        else monthly_ratio(i,j)=monthly_FFT(i,j)/monthly_generated(i,j);
        end
    end
end
monthly_ratio=monthly_ratio';
monthly_ratio=reshape(monthly_ratio,[],1);

% extend the above monthly ratio to daily scale,the data in each month are the same
monthly_ratio2=zeros(365*n,1);
j=0;
for i=0:365:365*n-1
    monthly_ratio2(i+1:i+31,1)=monthly_ratio(j+1,1);
    monthly_ratio2(i+32:i+59,1)=monthly_ratio(j+2,1);
    monthly_ratio2(i+60:i+90,1)=monthly_ratio(j+3,1);
    monthly_ratio2(i+91:i+120,1)=monthly_ratio(j+4,1);
    monthly_ratio2(i+121:i+151,1)=monthly_ratio(j+5,1);
    monthly_ratio2(i+152:i+181,1)=monthly_ratio(j+6,1);
    monthly_ratio2(i+182:i+212,1)=monthly_ratio(j+7,1);
    monthly_ratio2(i+213:i+243,1)=monthly_ratio(j+8,1);
    monthly_ratio2(i+244:i+273,1)=monthly_ratio(j+9,1);
    monthly_ratio2(i+274:i+304,1)=monthly_ratio(j+10,1);
    monthly_ratio2(i+305:i+334,1)=monthly_ratio(j+11,1);
    monthly_ratio2(i+335:i+365,1)=monthly_ratio(j+12,1);
    j=j+12;
end

% generate the years, months and days
daily_generated=zeros(365*n+1,6);
for i=1:366
    daily_generated(i,:)=datevec(i);
end
% delete the 60th row because it is the Feb 29th
daily_generated(60,:)=[];
% delete the fifthly and sixthly columns
daily_generated(:,6)=[];
daily_generated(:,5)=[];
% extend the date of the first to all years
j=1;
for i=366:365:365*n
    daily_generated(i:i+365-1,:)=daily_generated(1:365,:);
    daily_generated(i:i+365-1,1)=j;
    j=j+1;
end

% correct the WG generatd data
[n,m]=size(gP);
gP=gP';
j=1;
for i=1:365:m*n
    daily_generated(i:i+364,4)=gP(:,j);
    j=j+1;
end

monthly_adjust=zeros(size(daily_generated));
monthly_adjust(:,1:3)=daily_generated(:,1:3);
for i=1:365*n
    monthly_adjust(i,4)=daily_generated(i,4)*monthly_ratio2(i,1);
end
monthly_corrected_precip=monthly_adjust;
save('monthly_corrected_precip','monthly_corrected_precip')


function eclassifier = mcmcTrainEdgeClassifier(efeatures, adjlist, imsegs, labels)

ntrees = 20;
nnodes = 8;
ndata = 50000;

% train {ground, vertical, sky} classifier
[edata, elab] = formatData(efeatures, adjlist, labels, ndata);
mean(elab==1)
eclassifier = train_boosted_dt_2c(edata, [], elab, ntrees, nnodes, 0);

function [data, lab] = formatData(features, adjlist, labels, ndata)
% concatenate data and select ndata random datapoints

nimages = numel(features);

[tmp, nvars] = size(features{1});

% count edges
ne = 0;
for f = 1:nimages
    ne = ne + size(features{f}, 1);
end

data = zeros(ne, nvars);
lab = zeros(ne, 1);

% concatenate data
c = 0;
for f = 1:nimages
    cf = size(features{f}, 1);
    data(c+1:c+cf, :) = features{f};
    s1 = adjlist{f}(:, 1);
    s2 = adjlist{f}(:, 2);
    lab(c+1:c+cf) = (labels{f}(s1)==labels{f}(s2))*2-1;
    c = c + cf;
end

% select random ndata points
if ne > ndata
    rind = randperm(ne);
    rind = rind(1:ndata);
    data = data(rind, :);
    lab = lab(rind);
end


function [ out ] = VideoToHistogramList( vidPath, s, w )
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here

video = VideoReader(vidPath);
NumberOfFramesToRead = ceil(video.NumberOfFrames/10);
HistsPerFrame = video.Height*video.Width/(s^2);
out = zeros(256/w,3,NumberOfFramesToRead*HistsPerFrame);

for i = 1:10:video.NumberOfFrames
   frame = read(video, i);
   out(:,:,(i-1)/10*HistsPerFrame+1:((i-1)/10+1)*HistsPerFrame) = Histograms1D(frame, s, w);
end

end


function [pos2, tlight] = geocen (pos1, pe)

% this function moves the origin of coordinates from the
% barycenter of the solar system to the observer (or the
% geocenter).  i.e., this function accounts for parallax
% (annual + geocentric or just annual).

% input

%  pos1 = position vector of star or planet, with respect to
%         origin at solar system barycenter, components in au

%  pe   = position vector of observer (or the geocenter),
%         with respect to origin at solar system barycenter,
%         components in au

% output

%   pos2   = position vector of star or planet, with respect to
%            origin at observer (or the geocenter), components in au

%   tlight = light-time from star or planet to observer (or the
%            geocenter) in days

% ported from NOVAS 3.1

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

% speed of light in au/day

c = astcon('c(au/day)', 1.0);

for j = 1:1:3

    pos2(j) = pos1(j) - pe(j);

end

tlight = sqrt(pos2(1)^2 + pos2(2)^2 + pos2(3)^2) / c;


% OP_CURLV_P: assemble the matrix B = [b(i,j)], b(i,j) = (coeff p_i, curl v_j), exploiting the tensor product structure.
%
%   mat = op_curlv_p_tp (spv, spp, msh, [coeff]);
%   [rows, cols, values] = op_curlv_p (spv, spp, msh, [coeff]);

% INPUT:
%
%   spv:     object that defines the vector-valued space of trial functions (see sp_vector)
%   spp:     object that defines the scalar-valued space of the multiplier (see sp_scalar)
%   msh:     object that defines the domain partition and the quadrature rule (see msh_cartesian)
%   epsilon: function handle to compute some physical coefficient (optional)
%
% OUTPUT:
%
%   mat:    assembled stiffness matrix
%   rows:   row indices of the nonzero entries
%   cols:   column indices of the nonzero entries
%   values: values of the nonzero entries
%
% Copyright (C) 2011, 2016, 2017 Rafael Vazquez
%
%    This program is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.

%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program.  If not, see <http://www.gnu.org/licenses/>.

function varargout = op_curlv_p_tp (spv, spp, msh, coeff)

  for idim = 1:msh.ndim
    size2 = size (spp.sp_univ(idim).connectivity);
    for icomp = 1:spv.ncomp_param
      size1 = size (spv.scalar_spaces{icomp}.sp_univ(idim).connectivity);
      if (size1(2) ~= size2(2) || size1(2) ~= msh.nel_dir(idim))
        error ('One of the discrete spaces is not associated to the mesh')
      end
    end
  end

  A = spalloc (spp.ndof, spv.ndof, 3*spv.ndof);

  ndim = numel (msh.qn);

  for iel = 1:msh.nel_dir(1)
    msh_col = msh_evaluate_col (msh, iel);
    spv_col = sp_evaluate_col (spv, msh_col, 'value', false, 'curl', true);
    spp_col = sp_evaluate_col (spp, msh_col);

    if (nargin == 4)
      for idim = 1:msh.rdim
        x{idim} = reshape (msh_col.geo_map(idim,:,:), msh_col.nqn, msh_col.nel);
      end
      coeffs = coeff (x{:});
    else
      coeffs = ones (msh_col.nqn, msh_col.nel);
    end

    A = A + op_curlv_p (spv_col, spp_col, msh_col, coeffs);
  end

  if (nargout == 1)
    varargout{1} = A;
  elseif (nargout == 3)
    [rows, cols, vals] = find (A);
    varargout{1} = rows;
    varargout{2} = cols;
    varargout{3} = vals;
  end

end


% StackExchange Signal Processing Q63549
% https://dsp.stackexchange.com/questions/63549
% Computationally Efficient Ways of Determining If Pixels Are Clumped
% References:
%   1.  aa
% Remarks:
%   1.  sa
% TODO:
% 	1.  ds
% Release Notes
% - 1.0.000     06/01/2020
%   *   First release.

%% General Parameters

subStreamNumberDefault = 79;

run('InitScript.m');

figureIdx           = 0; %<! Continue from Question 1
figureCounterSpec   = '%04d';

generateFigures = ON;

%% Simulation Parameters

imageFileName001 = 'Image001.png';
imageFileName002 = 'Image002.png';

%% Generate Data

mA = imread(imageFileName001);
mB = imread(imageFileName002);

mA = ~logical(mA(:, :, 1));
mB = ~logical(mB(:, :, 1));

% Removing outer frame
mA(1, :) = false;
mA(end, :) = false;
mA(:, 1) = false;
mA(:, end) = false;

mB(1, :) = false;
mB(end, :) = false;
mB(:, 1) = false;
mB(:, end) = false;

% Extracting the properties of the Connected Components
% Can use half of 'MajorAxisLength' for the Radius.
% Then from 'PixelIdxList' do the computation
%{
objValA = CalcImageObjValImgBinaryImageProps(mA);
objValB = CalcImageObjValImgBinaryImageProps(mB);
%}

% Doing the Same, just with a nice trick to get the circle parameters by
% Binray Image Distnace Transform of the inverted image.
objValA = CalcImageObjValImgBinaryImageDistanceTransform(mA);
objValB = CalcImageObjValImgBinaryImageDistanceTransform(mB);

%% Display Results

hFigure     = figure('Position', [100, 100, 280, 320]); %<! [x, y, width, height]
hAxes       = axes('Units', 'pixels', 'Position', [17, 10, 256, 256]); %<! [x, y, width, height]
hImageObj   = imagesc(mA);
set(get(hAxes, 'Title'), 'String', {['Input Image A'], ['Objective Value - ', num2str(objValA)]}, ...
    'FontSize', fontSizeTitle);
set(hAxes, 'DataAspectRatio', [1, 1, 1]);
set(hAxes, 'XTick', [], 'YTick', [], 'XTickLabel', [], 'YTickLabel', []);
% set(hAxes, 'LooseInset', get(hAxes, 'TightInset'));
set(hAxes, 'LooseInset', [0.05, 0.05, 0.05, 0.05]);

hFigure     = figure('Position', [100, 100, 280, 320]); %<! [x, y, width, height]
hAxes       = axes('Units', 'pixels', 'Position', [17, 10, 256, 256]); %<! [x, y, width, height]
hImageObj   = imagesc(mB);
set(get(hAxes, 'Title'), 'String', {['Input Image B'], ['Objective Value - ', num2str(objValB)]}, ...
    'FontSize', fontSizeTitle);
set(hAxes, 'DataAspectRatio', [1, 1, 1]);
set(hAxes, 'XTick', [], 'YTick', [], 'XTickLabel', [], 'YTickLabel', []);
% set(hAxes, 'LooseInset', get(hAxes, 'TightInset'));
set(hAxes, 'LooseInset', [0.05, 0.05, 0.05, 0.05]);

%% Restore Defaults

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


function results = vl_test_twister(varargin)
% VL_TEST_TWISTER
vl_test_init ;

function test_illegal_args()
vl_assert_exception(@() vl_twister(-1), 'vl:invalidArgument') ;
vl_assert_exception(@() vl_twister(1, -1), 'vl:invalidArgument') ;
vl_assert_exception(@() vl_twister([1, -1]), 'vl:invalidArgument') ;

function test_seed_by_scalar()
rand('twister',1) ; a = rand ;
vl_twister('state',1) ; b = vl_twister ;
vl_assert_equal(a,b,'seed by scalar + VL_TWISTER()') ;

function test_get_set_state()
rand('twister',1) ; a = rand('twister') ;
vl_twister('state',1) ; b = vl_twister('state') ;
vl_assert_equal(a,b,'read state') ;

a(1) = a(1) + 1 ;
vl_twister('state',a) ; b = vl_twister('state') ;
vl_assert_equal(a,b,'set state') ;

function test_multi_dimensions()
b = rand('twister') ;
rand('twister',b) ;
vl_twister('state',b) ;
a=rand([1 2 3 4 5]) ;
b=vl_twister([1 2 3 4 5]) ;
vl_assert_equal(a,b,'VL_TWISTER([M N P ...])') ;

function test_multi_multi_args()
rand('twister',1) ; a=rand(1, 2, 3, 4, 5) ;
vl_twister('state',1) ; b=vl_twister(1, 2, 3, 4, 5) ;
vl_assert_equal(a,b,'VL_TWISTER(M, N, P, ...)') ;

function test_square()
rand('twister',1) ; a=rand(10) ;
vl_twister('state',1) ; b=vl_twister(10) ;
vl_assert_equal(a,b,'VL_TWISTER(N)') ;


function moon_lander()
close all;

t0 = 0;
tfinal = 800;
initial_state = [0 160000 0 0 -100 0 15000]';

[t, x] = runge_kutta(@moonlander, initial_state, [t0 tfinal], 0.05);

figure, plot(x(1,:), x(2,:), '-b*')
title('Landing trajectory')

figure,
plot(t, x(3,:), 'k')
title('Attitude')

figure,
plot(t, x(5,:), 'r')
title('Landing speed')

figure,
plot(t, x(7,:), 'g')
title('Mass')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Helper function to solve a second order differential equation.
% Called from function exerciseB()
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function xd = moonlander(t, x)
%target speed and x position
vtarget = -100;
xtarget = 0;

%constants
mass_min = 8000;
g = 1.6;
J = 100000;
ce=3.0*1000;
thlmax = 1000*0.5;
thtmax = 1000*44;
% compute control actions!
Kt = 300;
Kl = -0.000001;
vy = x(5);
posx = x(1);
posy = x(2);

if posy<3000
ut = Kt*(vtarget-vy);
ul = Kl*(xtarget-posx);
ul = sat(ul, -1, 1);
ut = sat(ut, 0, 1);
else
    ut=0;
    ul=0;
end

if x(7)<=mass_min
    Fl = 0;
    Ft = 0;
else
    Fl=thlmax*ul;
    Ft=thtmax*ut;
end

xd1 = x(4);
xd2 = x(5);
xd3 = x(6);
xd4 = (1/x(7))*(Fl*cos(x(3)) - Ft*sin(x(3)));
xd5 = (1/x(7))*(Fl*sin(x(3)) + Ft*cos(x(3))) - g;
xd6 = 4*Fl/J;

if x(7)<=mass_min
    % not changing mass
    display('ran out of fuel')
    % the derivative of mass is zero
    xd7 = 0 ;
else
    xd7 = -(abs(Fl/ce)+abs(Ft/ce));
end
xd = [xd1 xd2 xd3 xd4 xd5 xd6 xd7]';
return

function u= sat(u, min_val, max_val)
if u> max_val
    u = max_val;
end
if u < min_val
    u = min_val;
end


function [irf_record,D_record,gamma_record,struct_irf_record,irf_estimates,D_estimates,gamma_estimates,strshocks_record,strshocks_estimates]=panel4irf_mean(Ymat,Xmat,beta_gibbs,sigma_gibbs,It,Bu,IRFperiods,IRFband,N,n,m,p,k,T,IRFt,signrestable,signresperiods)

% because there is only one model, there is no need to loop over units
% hence, estimate the IRFs for the model, as with a standard normal-Wishart
% first run the Gibbs sampler to obtain posterior draws
[irf_record]=bear.irf(beta_gibbs,It,Bu,IRFperiods,n,m,p,k);

% If IRFs have been set to an unrestricted VAR (IRFt=1):
if IRFt==1
% run a pseudo Gibbs sampler to obtain records for D and gamma (for the trivial SVAR)
[D_record gamma_record]=bear.irfunres(n,It,Bu,sigma_gibbs);
struct_irf_record=[];
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(irf_record,n,IRFperiods,IRFband,IRFt,[],[]);

% If IRFs have been set to an SVAR with Choleski identification (IRFt=2):
elseif IRFt==2
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record D_record gamma_record]=bear.irfchol(sigma_gibbs,irf_record,It,Bu,IRFperiods,n);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,n,IRFperiods,IRFband,IRFt,D_record,gamma_record);

% If IRFs have been set to an SVAR with triangular factorisation (IRFt=3):
elseif IRFt==3
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record D_record gamma_record]=bear.irftrig(sigma_gibbs,irf_record,It,Bu,IRFperiods,n);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,n,IRFperiods,IRFband,IRFt,D_record,gamma_record);

% if IRFs have been set to an SVAR with sign restrictions
elseif IRFt==4
%if Magres==1
%[struct_irf_record D_record gamma_record]=bear.irfres_relmagnitude_panel(beta_gibbs,sigma_gibbs,It,Bu,IRFperiods,n,m,p,k,signrestable,signresperiods,relmagrestable, relmagresperiods);
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
%end
[struct_irf_record,D_record,gamma_record]=bear.irfsignrespanel(beta_gibbs,sigma_gibbs,It,Bu,IRFperiods,n,p,m,k,signrestable,signresperiods);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,n,IRFperiods,IRFband,IRFt,D_record,gamma_record);
end

% also, if a s structural identification was implemented, compute structural shocks
strshocks_record={};
strshocks_estimates={};
if IRFt~=1
   % because shocks have to be computed for each unit, loop over units
   for ii=1:N
   % run the Gibbs sampler
   strshocks_record(:,:,ii)=bear.strshocks(beta_gibbs,D_record,Ymat(:,:,ii),Xmat(:,:,ii),n,k,It,Bu);
   % obtain point estimates and credibility intervals
   strshocks_estimates(:,:,ii)=bear.strsestimates(strshocks_record(:,:,ii),n,T,IRFband);
   end
end


function test_bug2443

% WALLTIME 00:20:00
% MEM 4gb
% DEPENDENCY ft_multiplotER

% get some data
filename = dccnpath('/home/common/matlab/fieldtrip/data/test/latest/raw/meg/preproc_neuromag306.mat');
load(filename);

data_pre  = data;
data_post = data;

cfg = [];
cfg.method = 'mtmfft';
cfg.output = 'powandcsd'; % the CSD is needed for source reconstruction
cfg.taper  = 'dpss';
cfg.foi    = 5:5:100;
cfg.tapsmofrq = 10;       % we apply plenty of frequency smoothing
freq_pre  = ft_freqanalysis(cfg, data_pre);
freq_post = ft_freqanalysis(cfg, data_post);

cfg = [];
cfg.layout      = 'neuromag306planar.lay';
cfg.parameter   = 'powspctrm';
ft_multiplotER(cfg, freq_pre, freq_post);


classdef Density < DesignVariable

    properties (Access = private)
        creatorSettings
        initCase
    end

    methods (Access = public)

        function obj = Density(cParams)
            obj.nVariables = 1;
            obj.init(cParams);
            obj.initCase = cParams.initialCase;
            obj.creatorSettings  = cParams.creatorSettings;
            obj.createValue();
        end

        function v = getVariablesToPlot(obj)
            v{1} = obj.value;
        end

        function [fun, funNames] = getFunsToPlot(obj)
            aa.mesh = obj.mesh;
            aa.fValues = obj.value;
            valFun = P1Function(aa);

            fun = {valFun};
            funNames = {'Density'};
        end

        function rho = computeVolumeFraction(obj)
            s.mesh   = obj.mesh;
            s.fValues = obj.value;
            f = P1Function(s);
            q = Quadrature.set(obj.mesh.type);
            q.computeQuadrature('CONSTANT');
            xV = q.posgp;
            rho = f.evaluate(xV);
        end

    end

    methods (Access = private)

        function createValue(obj)
            s = obj.creatorSettings;
            switch s.type
                case 'FromLevelSet'
                    s.ndim  = obj.mesh.ndim;
                    s.coord = obj.mesh.coord;
                    s.type  = obj.initCase;
                    lsCreator  = LevelSetCreator.create(s);
                    phi        = lsCreator.getValue();
                    obj.value  = 1 - heaviside(phi);
                case 'Given'
                    obj.value = s.rho0.*ones(size(obj.mesh.coord,1),1);
            end
        end

    end

end


function [N,P,M,abs_M] = readIPI(filename)
  % READIPI read ipiSofts skeleton format
  %
  % [N,P,M,abs_M] = readIPI(filename)
  %
  % Inputs:
  %   filename  path to ipiSoft file
  % Outputs:
  %   N  #B cell of bone names
  %   P  #B list of parent indices (0 means root)
  %   M  4 by 4 by #B list of relative transform matrices
  %   abs_M 4 by 4 by #B list of absolute transform matrices
  %
  fp = fopen(filename,'r');
  line = eat_comments(fp,'#');
  fscanf(fp,'\n');
  while true
    ii = 1;
    % read id number
    line = line(ii:end);
    [id,count,e,ii] = sscanf(line,'%d ',1);
    if count ~= 1
      error('Bad format');
      break;
    end

    % read name
    line = line(ii:end);
    [name,count,e,ii] = sscanf(line,'%s ',1);
    if count ~= 1
      error('Bad format');
      break;
    end
    N{id} = name;

    % read parent
    line = line(ii:end);
    [p,count,e,ii] = sscanf(line,'%d ',1);
    if count ~= 1
      error('Bad format');
      break;
    end
    P(id) = p;

    % read parent
    line = line(ii:end);
    [m,count,e,ii] = sscanf(line,'%g ',16);
    if count ~= 16
      error('Bad format');
      break;
    end
    M(:,:,id) = reshape(m,4,4)';

    line = fgets(fp);
    if line == -1
      break;
    end
  end
  fclose(fp);

  next = P;
  abs_M = M;
  while true
    % loop over bones
    for ii = 1:numel(P)
      % if not root
      if next(ii) ~= 0
        abs_M(:,:,ii) = M(:,:,next(ii)) * abs_M(:,:,ii);
        next(ii) = P(next(ii));
      end
    end
    if ~any(next)
      break;
    end
  end

  assert(all(P<=numel(P)));
end


function T = spm_type(x, arg)
% translates data type specifiers between SPM & Matlab representations
% FORMAT T = spm_type(x, arg)
% x    - specifier
% T    - type
% arg  - optional string argument, can be
%    - 'maxval'  - return maximum allowed value.
%    - 'minval'  - return minimum allowed value.
%    - 'nanrep'  - return 1 if there is a NaN representation.
%    - 'bits'    - return the number of bits per voxel.
%    - 'intt'    - return 1 if values rounded to nearest integer.
%_______________________________________________________________________
%
% Format specifiers are based on NIFTI-1.  If the input is
% a number then the corresponding matlab string is returned by default.
% If the input is a string then the appropriate TYPE is returned.
% However, if the optional arg argument is supplied then other
% information will be returned instead.
%
% With no arguments, a list of data types is returned.
%_______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% John Ashburner & Andrew Holmes
% $Id$

prec = char('uint8','int16','int32','float32','float64','int8','uint16','uint32');
types   = [    2      4      8   16   64   256    512    768];
maxval  = [2^8-1 2^15-1 2^31-1  Inf  Inf 2^7-1 2^16-1 2^32-1];
minval  = [    0  -2^15  -2^31 -Inf -Inf  -2^7      0      0];
nanrep  = [    0      0      0    1    1     0      0      0];
bits    = [    8     16     32   32   64     8     16     32];
intt    = [    1      1      1    0    0     1      1      1];

if nargin==0,
    T=types;
    return;
end;

if ischar(x),
    sel = [];
    for i=1:numel(types),
        if strcmpi(deblank(prec(i,:)),deblank(x)),
            sel = i;
            break;
        end;
    end;
else,
    sel = find(types == x);
end;
if nargin == 1,
    if ischar(x),
        if isempty(sel), T = NaN;
        else, T = types(sel); end;
    else,
        if isempty(sel), T = 'unknown';
        else, T = deblank(prec(sel,:)); end;
    end;
elseif isempty(sel),
    T = NaN;
else,
    switch lower(arg)
    case 'maxval',  T = maxval(sel);
    case 'minval',  T = minval(sel);
    case 'nanrep',  T = nanrep(sel);
    case 'bits',    T = bits(sel);
    case 'intt',    T = intt(sel);
    otherwise,      T = NaN;
    end;
end;


function test_BartholomewBiggs

  addpath('../lib') ;

  auxdata = {} ;

  options.lb = [ 1, 1, 1, 1 ] ; % Lower bound on the variables.
  options.ub = [ 5, 5, 5, 5 ] ; % Upper bound on the variables.

  % The constraint functions are bounded to zero
  options.cl = [0,   0]; %  constraints
  options.cu = [inf, 0];

  % Set up the auxiliary data.
  options.auxdata = auxdata ;

  % Set the IPOPT options.
  options.ipopt.jac_d_constant   = 'no';
  options.ipopt.hessian_constant = 'no';
  options.ipopt.mu_strategy      = 'adaptive';
  options.ipopt.max_iter         = 400;
  options.ipopt.tol              = 1e-10;
  %options.ipopt.linear_solver    = 'ma57';
  options.ipopt.linear_solver    = 'mumps';
  %options.ipopt.linear_solver    = 'pardiso';

  % The callback functions.
  funcs.objective         = @objective;
  funcs.constraints       = @constraints;
  funcs.gradient          = @gradient;
  funcs.jacobian          = @jacobian;
  funcs.jacobianstructure = @jacobianstructure;
  if true
    funcs.hessian           = @hessian;
    funcs.hessianstructure  = @hessianstructure;
    options.ipopt.derivative_test = 'second-order';
  else
    options.ipopt.hessian_approximation      = 'limited-memory';
    %options.ipopt.limited_memory_update_type = 'bfgs' ; % {bfgs}, sr1 = 6; % {6}
    %options.ipopt.limited_memory_update_type = 'sr1' ;
    options.ipopt.limited_memory_update_type = 'bfgs' ; % {bfgs}, sr1 = 6; % {6}
  end

  % Run IPOPT.
  x0 = [ 1, 5, 5, 1 ] ;

  tic
  [x, info] = ipopt_auxdata(x0,funcs,options);
  elapsed = toc ;

  info;

  x

end

%%
% map the indices with the corresponding index in the spase matrix
function f = objective( x, auxdata )
  x1 = x(1) ;
  x2 = x(2) ;
  x3 = x(3) ;
  x4 = x(4) ;
  f  = x1*x4*(x1+x2+x3) + x3 ;
end

%%
% map the indices with the corresponding index in the spase matrix
function g = gradient(x,auxdata)
  x1 = x(1) ;
  x2 = x(2) ;
  x3 = x(3) ;
  x4 = x(4) ;
  g  = [ x4*(2*x1+x2+x3), x1*x4, x1*x4 + 1, x1*(x1+x2+x3)] ;
end

function c = constraints(x,auxdata)
  x1 = x(1) ;
  x2 = x(2) ;
  x3 = x(3) ;
  x4 = x(4) ;
  c  = [ x1*x2*x3*x4 ; x1^2+x2^2+x3^2+x4^2 - 40 ] ;
end

function jac = jacobian(x,auxdata)
  x1 = x(1) ;
  x2 = x(2) ;
  x3 = x(3) ;
  x4 = x(4) ;
  jac = sparse([ x2*x3*x4, x1*x3*x4, x1*x2*x4, x1*x2*x3 ; ...
                 2*x1, 2*x2, 2*x3, 2*x4 ]) ;
end

function jac = jacobianstructure(auxdata)
  jac = sparse(ones(2,4)) ;
end

function H = hessian(x, sigma, lambda, auxdata)
  x1 = x(1) ;
  x2 = x(2) ;
  x3 = x(3) ;
  x4 = x(4) ;
  Hf = [ 2*x4,      x4,  x4, 2*x1+x2+x3 ; ...
         x4,         0,   0, x1         ; ...
         x4,         0,   0, x1         ; ...
         2*x1+x2+x3, x1, x1, x1         ] ;

  H1 = [ 0, x3*x4, x2*x4, x2*x3 ; ...
         x3*x4, 0, x1*x4, x1*x3 ; ...
         x2*x4, x1*x4, 0, x1*x2 ; ...
         x2*x3, x1*x3, x1*x2, 0 ] ;

     H2 = 2*eye(4,4) ;
  H  = tril(sparse(sigma * Hf + lambda(1)*H1 + lambda(2)*H2)) ;
end

function H = hessianstructure(auxdata)
  H = tril(sparse(ones(4,4))) ;
end


function if_smooth=filt_if_law(if_law,window_length)
%---------------------------------------------------------------------
% filter IF law by convolving with Hamming window
%---------------------------------------------------------------------
if(nargin<2 || isempty(window_length)) window_length=15; end

w=hamming( floor(window_length) ); w=w./sum(w);

if_mean=mean(if_law);
if_smooth=conv(if_law-if_mean,w,'same');
if_smooth=if_smooth+if_mean;


function k = simXsimKernDiagCompute(simKern1, simKern2, t)

% SIMXSIMKERNDIAGCOMPUTE Diagonal of a cross kernel between two SIM kernels.
% FORMAT
% DESC computes diagonal of cross kernel terms between two SIM kernels for
% the multiple output kernel.
% ARG simKern1 : the kernel structure associated with the first SIM
% kernel.
% ARG simKern2 : the kernel structure associated with the second SIM
% kernel.
% ARG t : inputs for which kernel is to be computed.
% RETURN k : block of values from the diagonal kernel matrix.
% RETURN sK : normalised diagonal(i.e. unscaled version of K not multiplied
% by sqrt(simKern1.variance), sqrt(simKern2.variance) and
% sqrt(2/simKern.inverseWidth) in the case of the un-normalised kernel).
%
% SEEALSO : multiKernParamInit, multiKernCompute, simKernParamInit
%
% COPYRIGHT : Mauricio A. Alvarez, 2010

% KERN

if size(t, 2) > 1
  error('Input can only have one column');
end

if simKern1.inverseWidth ~= simKern2.inverseWidth
  error('Kernels cannot be cross combined if they have different inverse widths.')
end

if ~isfield(simKern1, 'isNormalised')
    isSim1Normalised = false;
else
    isSim1Normalised = simKern1.isNormalised;
end

if ~isfield(simKern2, 'isNormalised')
    isSim2Normalised = false;
else
    isSim2Normalised = simKern2.isNormalised;
end

% The factor of 2 on the top is because all our derivations are in terms
% of erfs which are defined in terms of exp(-x^2) rather than exp(-0.5x^2).
sigma = sqrt(2/simKern1.inverseWidth);

if ~simKern1.isStationary
    h1 = simXsimComputeDiagH(t, simKern1.decay, simKern2.decay, ...
                     simKern1.delay, simKern2.delay, sigma);
    h2 = simXsimComputeDiagH(t, simKern2.decay, simKern1.decay, ...
                     simKern2.delay, simKern1.delay, sigma);
else
    h1 = simXsimComputeDiagHStat(t, simKern1.decay, simKern2.decay, ...
                         simKern1.delay, simKern2.delay, sigma);
    h2 = simXsimComputeDiagHStat(t, simKern2.decay, simKern1.decay, ...
                         simKern2.delay, simKern1.delay, sigma);
end

sK = 0.5 * (h1 + h2);
if (isSim1Normalised == false) || (isSim2Normalised == false)
  sK = sqrt(pi) * sigma * sK;
end

if isfield(simKern1, 'isVarS') && (simKern1.isVarS)
    k = sK;
else
    if isfield(simKern1, 'isNegativeS') && (simKern1.isNegativeS == true)
        k = simKern1.sensitivity * sK;
    else
        k = sqrt(simKern1.variance) *sK;
    end
    if isfield(simKern2, 'isNegativeS') && (simKern2.isNegativeS == true)
        k = simKern2.sensitivity * k;
    else
        k = sqrt(simKern2.variance) * k;
    end
end


function plotSpektra(psi,varargin)
% plot the Legendre coefficients of the kernel function

bw = get_option(varargin,'bandwidth',32);
bw = min(bw,length(psi.A)-1);
A = reshape(psi.A(1:bw+1),1,[]);

if check_option(varargin,'logarithmic')
  optiondraw(loglog(0:bw,abs(A)./(2*(0:bw)+1),...
    'marker','o','MarkerSize',5),varargin{:});
else
  optiondraw(semilogx(0:bw,A./(2*(0:bw)+1),...
    'marker','o','MarkerSize',5),varargin{:});
end
set(gcf,'Name',['Legendre coefficients of the kernel ',inputname(1)]);

end


classdef SSC_NN_OMP < handle
    % Implements sparse subspace clustering algorithm using OMP algorithm
    properties
        Quiet = false
    end

    properties(SetAccess=private)
        % Dimension of signal space
        N
        % Number of signals in the space
        S
        % A matrix of size NxS where each column is one signal vector
        Data
        % data vectors after normalization
        NormalizedData
        % The sparsity level or the largest dimension of the sparse subspaces
        K
        % The expected number of subspaces
        NumSubspaces
        % Labels obtained through clustering
        Labels
        % Representation matrix (each column is a representation vector for one data vector)
        Representation
        % affinities identified during sparse coding
        Affinity
        % Adjacency matrix
        Adjacency
        % The spectral clusterer used in the algorithm
        Clusterer
    end

    methods
        function self = SSC_NN_OMP(X, K, NumSubspaces)
            % Constructor
            self.Data = X;
            self.K = K;
            if nargin < 3
                NumSubspaces = -1;
            end
            self.NumSubspaces = NumSubspaces;
            [n, s] = size(X);
            self.N = n;
            self.S = s;
            self.Labels = ones(s, 1);
            % Each data vector is represented using other data vectors in same space
            self.Representation = zeros(s, s);
            self.Affinity = zeros(s, s);
        end

        function result = solve(self)
            % prepare sparse representations
            self.recover_coefficients();
            self.build_adjacency();

            % conduct spectral clustering
            options.num_clusters = self.NumSubspaces;
            result = spx.cluster.spectral.simple.normalized_symmetric(self.Adjacency, options);
            cluster_labels = result.labels;

            % We are disabling our version of spectral clustering for now.
            % clusterer = spx.cluster.spectral.Clustering(self.Adjacency);
            % keep reference for debugging purposes.
            % self.Clusterer = clusterer;
            % clusterer.NumClusters = self.NumSubspaces;
            %cluster_labels = clusterer.cluster_random_walk();

            self.Labels = cluster_labels;
            % Return the labels
            result.Labels = self.Labels;
            result.Z = self.Representation;
            result.W = self.Adjacency;

        end

    end

    methods(Access=private)

        function recover_coefficients(self)
            % Computes sparse representations of the data vectors
            data = self.Data;
            self.NormalizedData = spx.norm.normalize_l2(data);
            % Number of data vectors
            ns = self.S;
            % iterate over signals
            all_cols = 1:ns;
            for s=all_cols
                if ~self.Quiet
                    fprintf('.');
                    if mod(s, 50) == 0
                        fprintf('\n');
                    end
                end
                self.nn_omp(s);
            end
            if ~self.Quiet
                fprintf('\n');
            end
        end

        function nn_omp(self, s)
            % Apply nearest neighbor OMP on s-th vector.
            % data matrix
            X = self.NormalizedData;
            % Current vector
            x =X(:, s);
            % number of vectors
            ns = self.S;
            % Subspace dimension
            nk = self.K;
            % current residual
            r = x;
            % norm of current residual
            res_norm = norm(r);
            % ambient dimension
            nd = self.N;
            % coefficients
            z  = zeros(ns, 1);
            % affinities
            c = zeros(ns, 1);
            % selected indices
            omega = [];
            % max number of iterations
            maxIter = nk;
            MaxResNorm = 1/8;
            % maximum number of nearest neighbors
            nn = min (max(2*(nk-1), 2), round(ns/2) );
            for iter=1:maxIter
                % identify normalized inner product
                rr = r / res_norm;
                % Compute inner products with normalized residual
                inner_products = X' * rr;
                inner_products(s) = 0;
                inner_products(omega) = 0;
                inner_products = abs(inner_products);
                % Find the highest inner product
                [sorted_inner_products, indices] = sort(inner_products, 'descend');
                index = indices(1);                % Add this index to support
                omega = [omega, index];
                angles  = rad2deg(acos(sorted_inner_products(1:nn)'));
                if false
                    fprintf('%.0f ', angles);
                    fprintf('\n');
                end
                min_angle = angles(1);
                % allow for some degree leeway
                max_angle = min(min_angle + 6, 1.5 * min_angle);
                max_index = find(angles > max_angle, 1);
                if isempty(max_index)
                    % all vectors are too close by
                    max_index = nn;
                end
                % number of neighbors
                nnn = max(max_index - 1, 1);
                %fprintf('%d:%d ', nn, nnn);
                c(indices(1:nnn)) = inner_products(indices(1:nnn));
                % Solve least squares problem
                subdict = X(:, omega);
                tmp = linsolve(subdict, x);
                % Updated solution
                z(omega) = tmp;
                % Let us update the residual.
                r = x - subdict * tmp;
                res_norm = norm(r);
                if res_norm < MaxResNorm
                    break;
                end
            end
            self.Representation(:, s) = z;
            self.Affinity(:, s) = c;
        end

        function detect_outliers(self)
            % Identifies outliers in the representations
        end

        function build_adjacency(self)
            C = abs(self.Affinity);
            % Normalize the matrix by column wise maximums
            C = spx.norm.normalize_linf(C);
            % Make it symmetric
            C = C + C';
            % Keep it
            self.Adjacency = C;
        end

    end

end


function sparse_grid_composite_test01 ( dim_min, dim_max, level_max_min, ...
  level_max_max )

%*****************************************************************************80
%
%% SPARSE_GRID_COMPOSITE_TEST01 tests SPARSE_GRID_COMPOSITE_SIZE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 August 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_MIN, the minimum spatial dimension to consider.
%
%    Input, integer DIM_MAX, the maximum spatial dimension to consider.
%
%    Input, integer LEVEL_MAX_MIN, the minimum value of LEVEL_MAX to consider.
%
%    Input, integer LEVEL_MAX_MAX, the maximum value of LEVEL_MAX to consider.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPARSE_GRID_COMPOSITE_TEST01\n' );
  fprintf ( 1, '  SPARSE_GRID_COMPOSITE_SIZE returns the number of distinct\n' );
  fprintf ( 1, '  points in a composite sparse grid.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Each sparse grid is of spatial dimension DIM,\n' );
  fprintf ( 1, '  and is made up of all product grids of levels up to LEVEL_MAX.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '   DIM: ' );

  for dim_num = dim_min : dim_max
    fprintf ( 1, '  %8d', dim_num );
  end

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

  for level_max = level_max_min : level_max_max
    fprintf ( 1, '    %4d', level_max );
    for dim_num = dim_min : dim_max
      point_num = sparse_grid_composite_size ( dim_num, level_max );
      fprintf ( 1, '  %8d', point_num );
    end
    fprintf ( 1, '\n' );
  end

  return
end


function comp_unrank_grlex_test ( )

%*****************************************************************************80
%
%% COMP_UNRANK_GRLEX_TEST tests COMP_UNRANK_GRLEX.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 October 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'COMP_UNRANK_GRLEX_TEST\n' );
  fprintf ( 1, '  A COMP is a composition of an integer N into K parts.\n' );
  fprintf ( 1, '  Each part is nonnegative.  The order matters.\n' );
  fprintf ( 1, '  COMP_UNRANK_GRLEX determines the parts\n' );
  fprintf ( 1, '  of a COMP from its rank.\n' );

  kc = 3;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Rank: ->  NC       COMP\n' );
  fprintf ( 1, '  ----:     --   ------------\n' );

  for rank1 = 1 : 71

    xc = comp_unrank_grlex ( kc, rank1 );
    nc = sum ( xc(1:kc) );

    fprintf ( 1, '   %3d: ', rank1 );
    fprintf ( 1, '    %2d = ', nc );
    for j = 1 : kc - 1
      fprintf ( 1, '%2d + ', xc(j) );
    end
    fprintf ( 1, '%2d\n', xc(kc) );
%
%  When XC(1) == NC, we have completed the compositions associated with
%  a particular integer, and are about to advance to the next integer.
%
    if ( xc(1) == nc )
      fprintf ( 1, '  ----:     --   ------------\n' );
    end

  end

  return
end


function [yUpdate,PInvUpdate,innov]=cubInfoUpdate(yPred,PInvPred,z,RInv,h,xi,w,innovTrans,measAvgFun,stateDiffTrans)
%%CUBINFOUPDATE Perform the measurement update step in the cubature
%               information filter.
%
%INPUTS: yPred The xDimX1 predicted information state. The information
%              state is the inverse covariance matrix times the target
%              state.
%     PInvPred The xDimXxDim inverse of the predicted state covariance
%              matrix.
%            z The zDim X 1 vector measurement.
%         RInv The zDim X zDim inverse of the measurement covariance matrix
%              in the native coordinate system of the measurement.
%            h A function handle for the measurement function that takes
%              the state as its argument.
%           xi An xDim X numCubPoints matrix of cubature points. If this
%              and the next parameter are omitted or empty matrices are
%              passed, then fifthOrderCubPoints(xDim) is used. It is
%              suggested that xi and w be provided to avoid needless
%              recomputation of the cubature points.
%            w A numCubPoints X 1 vector of the weights associated with the
%              cubature points.
%   innovTrans An optional function handle that computes and optionally
%              transforms the value of the difference between the
%              observation and any predicted points. This is called as
%              innovTrans(a,b) and the default if omitted or an empty
%              matrix is passed is @(a,b)bsxfun(@minus,a,b). This must be
%              able to handle sets of values. For a zDimX1 measurement,
%              either of the inputs could be zDimXN in size while one of
%              the inputs could be zDimX1 in size.  This only needs to be
%              supplied when a measurement difference must be restricted
%              to a certain range. For example, the innovation between two
%              angles will be 2*pi if one angle is zero and the other
%              2*pi, even though they are the same direction. In such an
%              instance, a function handle to the
%              wrapRange(bsxfun(@minus,a,b),-pi,pi) function with the
%              appropriate parameters should be passed for innovTrans.
%   measAvgFun An optional function handle that, when given N measurement
%              values with weights, produces the weighted average. This
%              function only has to be provided if the domain of the
%              measurement is not linear. For example, when averaging
%              angular values, then the function meanAng should be used.
% stateDiffTrans An optional function handle that takes an xDimXN matrix of
%              N differences between states and transforms them however
%              might be necessary. For example, a state containing angular
%              components will generally need to be transformed so that the
%              difference between the angles is wrapped to -pi/pi.
%
%OUTPUTS: yUpdate The xDim X 1 updated (posterior) information state
%                 vector.
%      PInvUpdate The updated xDim X xDim inverse state covariance matrix.
%           innov The zDimX1 innovation. This is the difference between the
%                 measurement and the predicted measurement. This is
%                 sometimes used for gating measurements.
%
%If the function h needs additional parameters beyond the state, then the
%parameters can be passed by using an anonymous function as the function
%handle. For example, suppose that the measurement function is measFunc and
%it needs the additional parameters param1 and param2. In this instance,
%rather than using
%h=@measFunc
%one should use
%h=@(x)measFunc(x,param1,param2)
%This way, every time cubKalUpdate calls measFunc (via h) with a
%different x, those two parameters are always passed.
%
%This function is an implementation of the measurement update step of
%Algorithm 1 in [1].
%
%The optional parameters innovTrans and measAvgFun are not described in
%[1], but allow for possible modifications to the filter as
%described in [2]. The parameters have been added to allow the filter to be
%used with angular quantities. For example, if the measurement consisted of
%range and angle, z=[r;theta], then
%innovTrans=@(a,b)[bsxfun(@minus,a(1,:),b(1,:));
%                  wrapRange(bsxfun(@minus,a(2,:),b(2,:)),-pi,pi)];
%measAvgFun=@(z,w)[calcMixtureMoments(z(1,:),w);
%                  meanAng(z(2,:),w')];
%should be used to approximately deal with the circular nature of the
%measurements.
%
%REFERENCES:
%[1] K. P. B. Chandra, D.-W. Gu, and I. Postlethwaite, "Square root
%    cubature information filter," IEEE Sensors Journal, vol. 13, no. 2,
%    pp. 750-758, Feb. 2013.
%[2] D. F. Crouse, "Cubature/ unscented/ sigma point Kalman filtering with
%    angular measurement models," in Proceedings of the 18th International
%    Conference on Information Fusion, Washington, D.C., 6-9 Jul. 2015.
%
%October 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

xDim=size(yPred,1);

if(nargin<6||isempty(xi))
    [xi,w]=fifthOrderCubPoints(xDim);
end

if(nargin<8||isempty(innovTrans))
    %The function just returns the input.
    innovTrans=@(a,b)bsxfun(@minus,a,b);
end

if(nargin<9||isempty(measAvgFun))
   measAvgFun=@(zPoints,w)calcMixtureMoments(zPoints,w);
end

if(nargin<10||isempty(stateDiffTrans))
   stateDiffTrans=@(x)x;
end

zDim=size(z,1);

numCubPoints=size(xi,2);

%Extract the state
xPred=PInvPred\yPred;
%Get a square root of the inverse covariance matrix.
SPred=cholSemiDef(pinv(PInvPred),'lower');
%Predicted cubature state points
xPredPoints=bsxfun(@plus,SPred*xi,xPred);

%Predicted cubature measurement points
zPredPoints=zeros(zDim,numCubPoints);
for curP=1:numCubPoints
    zPredPoints(:,curP)=h(xPredPoints(:,curP));
end

%Measurement prediction.
zPred=measAvgFun(zPredPoints,w);

%The innovation, transformed as necessary to keep values in a desired
%range.
innov=innovTrans(z,zPred);

Pxz=zeros(xDim,zDim);
for curP=1:numCubPoints
    diff=innovTrans(zPredPoints(:,curP),zPred);
    Pxz=Pxz+w(curP)*stateDiffTrans(xPredPoints(:,curP)-xPred)*diff';
end

I=PInvPred*Pxz*RInv*Pxz'*PInvPred';
i=PInvPred*Pxz*RInv*(innov+Pxz'*PInvPred'*xPred);

yUpdate=yPred+i;
PInvUpdate=PInvPred+I;
%Ensure symmetry
PInvUpdate=(PInvUpdate+PInvUpdate')/2;
end

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


function OUT = localtopography(DEM,varargin)

%LOCALTOPOGRAPHY Local topography
%
% Syntax
%
%     H = localtopography(DEM)
%     H = localtopography(DEM,radius)
%     H = localtopography(DEM,radius,pn,pv,...)
%
% Description
%
%     localtopography quantifies local relief, e.g. the elevation range
%     within a specific radius. localtopography may take a while to
%     evaluate large DEMs with large kernels. You may speed up calculations
%     by adjusting the parameter 'N' for calculating the max, min or range
%     filter.
%
%     localtopography uses symmetric boundary padding. NaNs
%     are inpainted by nearest neighbor interpolation prior to the
%     calculation (affects only 'mean', 'median', 'prctile', 'std'). For
%     'max', 'min' and 'range', localtopography adopts the padding behavior
%     of the function imdilate and imerode.
%
%
% Input arguments
%
%     DEM    digital elevation model (GRIDobj)
%     radius radius of the moving window filter in map units. The default
%            value is 5000 (m).
%
% Parameter Name/Value (pn,pv) pairs
%
%     'type'   'range' (default), 'max', 'min', 'mean', 'median',
%              'prctile', 'std' (standard deviation)
%     'prc'    scalar between 0 and 100 [%]. Only applicable if 'prctile'
%              is chosen as 'type'.
%     'N'      enable speed improvement for 'max', 'min' and 'range'.
%              N must be 0, 4, 6,or 8. When N is greater than 0, the
%              disk-shaped structuring element is approximated by a sequence
%              of N periodic-line structuring elements. When N equals 0,
%              no approximation is used, and the structuring element members
%              consist of all pixels whose centers are no greater than R
%              away from the origin. If N is not specified, the default
%              value is 0.
%
% Output arguments
%
%     H      local topography grid (GRIDobj)
%
% Example
%
%     DEM = GRIDobj('srtm_bigtujunga30m_utm11.tif');
%     H = localtopography(DEM,500);
%     imageschs(DEM,H)
%
% See also: IMDILATE, IMERODE
%
% Author: Wolfgang Schwanghart (w.schwanghart[at]geo.uni-potsdam.de)
% Date: 28. January, 2013

narginchk(1,inf)

p = inputParser;
p.FunctionName = 'GRIDobj/localtopography';
expectedTypes = {'range','max','min','mean','median','prctile','std'};

addRequired(p,'DEM',@(x) issparse(x) || isa(x,'GRIDobj'));
addOptional(p,'radius',5000,@(x) isscalar(x) && x>DEM.cellsize);

addParamValue(p,'type','range',@(x) ischar(validatestring(x,expectedTypes)));
addParamValue(p,'N',0,@(x) isscalar(x) && ismember(x,[0 4 6 8]));
addParamValue(p,'thin',1,@(x) x>0.1 && x<=1);
addParamValue(p,'prc',90,@(x) x>0 && x<100);

parse(p,DEM,varargin{:});

dem = DEM.Z;
cs  = DEM.cellsize;

% any nans
INAN = isnan(dem);
flaginan = any(INAN(:));

% structuring element
radiuspx = ceil(p.Results.radius/cs);
SE = strel('disk',radiuspx,p.Results.N);

switch p.Results.type
    case 'max'
        % Maximum filter
        if flaginan;
            dem(INAN) = -inf;
        end
        H = imdilate(dem,SE);
    case 'min'
        % Minimum filter
        if flaginan;
            dem(INAN) = inf;
        end
        H = imerode(dem,SE);
    case 'range'
        if flaginan;
            dem(INAN) = -inf;
        end
        H1 = imdilate(dem,SE);
        if flaginan;
            dem(INAN) = inf;
        end
        H2 = imerode(dem,SE);
        H  = H1-H2;
    case {'mean','average'}
        if flaginan;
            [~,L] = bwdist(~INAN,'e');
            dem = dem(L);
        end
        H   = fspecial('disk',radiuspx);
        H   = imfilter(dem,H,'symmetric','same','conv');
    case 'median'
        if flaginan;
            [~,L] = bwdist(~INAN,'e');
            dem = dem(L);
        end
        H   = getnhood(SE);
        n   = round(sum(H(:))/2);
        H   = ordfilt2(dem,n,H,'symmetric');

    case 'prctile'
        if flaginan;
            [~,L] = bwdist(~INAN,'e');
            dem = dem(L);
        end
        H   = getnhood(SE);
        n   = round(sum(H(:))*p.Results.prc/100);
        H   = ordfilt2(dem,n,H,'symmetric');

    case 'std'
        if flaginan;
            [~,L] = bwdist(~INAN,'e');
            dem = dem(L);
        end
        H   = getnhood(SE);
        H   = stdfilt(dem,H);
end

% Handle nans
if flaginan;
    H(INAN) = nan;
end

% prepare output
OUT = DEM;
OUT.Z = H;
OUT.name = ['local topography (' p.Results.type ')'];


%% Function Serial to Parallel I/P msg and No. of Parallel Channels

function p_data = s2p(s_data,N)
    l = length(s_data);
    mode = mod(l,N);
    if mode ~= 0
        z_add = zeros(1,N-mode);
        data = [s_data z_add];
    else
        data = s_data;
    end

    M = length(data)/N;
    p_data = reshape(data,N,M);
end


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

function y = asian_bintree(S, df, p, K, type)
% pricing an american asian option using a binomial tree
n = size(S,2)-1;
v = cell(1, n+1);               % option value

tmp = repmat(1:n, length(S), 1);
average_val = cumsum(S(:,2:end), 2) ./ tmp; % average value

if type == 0
   cp = 1;
else
    cp = -1;
end

v{n+1} = max(cp*(average_val(:,end)-K), 0); % payoff at t_N

iVec = 1:length(S);

for i = n:-1:2
    Jset = 1:2:2^i;
    expected_val = p * v{i+1}(Jset) * df ...
        + (1-p) * v{i+1}(1+Jset) * df;

    iVec = iVec(1:length(iVec)/2) * 2;

    v{i} = max(cp*(average_val(iVec,i-1)-K),0);   % payoff at t_i
    v{i}=max(v{i}, expected_val);                 % option value t_i
end

y = p * v{2}(1) * df + (1-p) * v{2}(2) * df;      % option value t_0


function modelConstrained = constrainRxnListAboveBound(model, rxnList, c, d, ineqSense)
% Constrains one (weighted) sum of fluxes to be above a lower bound.
% Appends to existing inequality constraints if they are present
%
% USAGE:
%
%    modelConstrained = constrainRxnListAboveBound(model, rxnList, c, d, ineqSense)
%
% INPUTS:
%    model:               model structure
%    rxnList:             cell array of reaction names
%
% OPTIONAL INPUTS:
%    c:                   `k x 1` vector :math:`c*v \geq d`
%    d:                   `n x 1` vector :math:`c*v \geq d`
%    ineqSense:           `k x 1` inequality sense {'L','G'}
%
% OUTPUT:
%    modelConstrained:    constrained model:
%
%                           * S - Stoichiometric matrix
%                           * b - Right hand side = dx/dt
%                           * C - Inequality constraint matrix
%                           * d - Inequality constraint right hand side
%                             :math:`[S; C] * v {=, \leq, \geq } [dxdt, d]`

% EXAMPLE:
%
%    rxnList = {'PCHOLP_hs_f', 'PLA2_2_f', 'SMS_f','PCHOLP_hs_b', 'PLA2_2_b', 'SMS_b'};
%    c = [1, 1, 1, 1, 1, 1];
%    d = 10;
%    ineqSense = 'G';
%    modelConstrained = constrainRxnListAboveBound(modelIrrev, rxnList, C, d, ineqSense);

modelConstrained = addCOBRAConstraints(model, rxnList, d, 'c', c, 'dsense', ineqSense);


function plotData(x, y)
    %% PLOTDATA Plots the data points x and y into a new figure
    %   PLOTDATA(x,y) plots the data points and gives the figure axes labels of
    %   population and profit.

    % ====================== YOUR CODE HERE ======================
    % Instructions: Plot the training data into a figure using the
    %               "figure" and "plot" commands. Set the axes labels using
    %               the "xlabel" and "ylabel" commands. Assume the
    %               population and revenue data have been passed in
    %               as the x and y arguments of this function.
    %
    % Hint: You can use the 'rx' option with plot to have the markers
    %       appear as red crosses. Furthermore, you can make the
    %       markers larger by using plot(..., 'rx', 'MarkerSize', 10);

    figure; % open a new figure window
    plot(x, y, 'rx', 'MarkerSize', 10);
    ylabel('Profit in $10,000s');
    xlabel('Population of City in 10,000s');
end


function [magTS, phaseTS] = cReconBW(fName, slice)

% [magTS, phaseTS] = cReconBW(fName, slice);
%
% Perform a complex recon using Alex Wade's tstrecon code.
% Returns pair of single-slice time-series arrays of size:
% ny x nx x nFrames -- magTS is magnitude and phaseTS is
% phase. Time-duration and spatial cropping are performed,
% but no trend removal. Inputs are pFile name [fName], and
% slice index [slice]. Assumes pwd points to valid session
% directory, and uses global mrSESSION.
%
% DBR 8/00

global mrSESSION

% Do recon, extract complex time series:
cTS = tstrecon3Tb([], fName, slice, slice);
cTS = cTS{1}';

% Remove junk frames:
f0 = mrSESSION.junkFirstFrames+1;
nFrames = mrSESSION.nFrames;
fEnd = f0 + nFrames - 1;
cTS = cTS(f0:fEnd, :);

% Crop:
cTS = reshape(cTS, [nFrames, mrSESSION.fullSize]); % reshape the array to full size
x0 = mrSESSION.tseriesCrop(1, 1);
xN = mrSESSION.tseriesCrop(2, 1);
y0 = mrSESSION.tseriesCrop(1, 2);
yN = mrSESSION.tseriesCrop(2, 2);
cTS = cTS(:, y0:yN, x0:xN);

%Shuffle to standard t-series shape:
cTS = reshape(cTS, nFrames, (yN-y0+1)*(xN-x0+1));

% Get magnitude and phase:
magTS = abs(cTS);
phaseTS = angle(cTS);


classdef chebfun2 < separableApprox
%CHEBFUN2   CHEBFUN2 class for representing functions on [a,b]x[c,d].
%
%   Class for approximating functions defined on finite rectangles. The
%   functions should be smooth.
%
% CHEBFUN2(F) constructs a CHEBFUN2 object representing the function F on
% [-1,1]x[-1 1]. F can be a string, e.g., 'sin(x.*y)', a function handle, e.g.,
% @(x,y) x.*y + cos(x), or a matrix of numbers. For the first two, F should in
% most cases be "vectorized" in the sense that it may be evaluated at a matrix
% of points and returns a matrix output.
%
% CHEBFUN2(F, [A B C D]) specifies a rectangle [A B]x[C D] where the
% function is defined. A, B, C, D must all be finite.
%
% If F is a matrix, F = (f_ij), the numbers f_ij are used as function
% values at tensor Chebyshev points of the 2nd kind. CHEBFUN2(F, 'equi')
% assumes the function values f_ij come from an equispaced tensor grid.
% CHEBFUN2(F, 'equix') assumes the values come from a tensor grid that is
% equispaced in x and 2nd-kind Chebyshev in y. CHEBFUN2(F, 'equiy') assumes
% the values come from a tensor grid that is 2nd-kind Chebyshev in x and
% equispaced in y.
%
% CHEBFUN2(F, k) returns a rank k approximation to F.
%
% CHEBFUN2(F, [m n]) returns a representation of a bivariate polynomial
% with m coefficients in x and n coefficients in y. The polynomial is
% compressed in low rank form and the rank k is still determined adaptively
% (satisfying k<=min(m,n)+1).
%
% CHEBFUN2(F, k, [A B C D]) or CHEBFUN2(F, [m,n], [A B C D]) is nonadaptive in
% rank or degrees, as above, returning a chebfun2 on the domain [A B]x[C D].
%
% CHEBFUN2(F, 'coeffs') where F is a matrix uses the matrix as coefficients
% in a Chebyshev tensor expansion. CHEBFUN2(F, 'coeffsx') uses an expansion
% of coefficients in x and values in y. CHEBFUN2(F, 'coeffsy') uses an
% expansion of values in x and coefficients in y.
%
% CHEBFUN2(F, 'trig') constructs a CHEBFUN2 object representing a smooth
% and periodic function F on [-1,1]x[-1 1]. The resulting CHEBFUN2 is
% represented using a bivariate Fourier expansion. CHEBFUN2(F, 'trigx')
% constructs a CHEBFUN2 that is periodic in x only, represented as a
% bivariate Fourier-Chebyshev expansion. CHEBFUN2(F, 'trigy') constructs a
% CHEBFUN2 that is periodic in y only, represented as a bivariate
% Chebyshev-Fourier expansion.
%
% CHEBFUN2(F, 'periodic')  is the same as CHEBFUN2(F, 'trig').
% CHEBFUN2(F, 'periodicx') is the same as CHEBFUN2(F, 'trigx').
% CHEBFUN2(F, 'periodicy') is the same as CHEBFUN2(F, 'trigy').
%
% CHEBFUN2(F, pref) constructs a CHEBFUN2 object from F with the options
% determined by the CHEBFUNPREF object pref. CHEBFUN2(F, {prefx, prefy})
% uses the CHEBFUNPREF objects prefx in x and prefy in y, where one of
% prefx and prefy may be [].
%
% The Chebfun2 software system is based on:
%
% A. Townsend and L. N. Trefethen, An extension of Chebfun to two dimensions,
% SIAM J. Sci. Comput., 35 (2013), C495-C518.
%
% See also CHEBFUN, CHEBFUN2V.

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

% TODO: Improve documentation of input options.

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS CONSTRUCTOR:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function f = chebfun2(varargin)
            % The main CHEBFUN2 constructor!

            % Return an empty CHEBFUN:
            if ( (nargin == 0) || isempty(varargin{1}) )
                return
            end

            % Call the constructor, all the work is done here:
            f = constructor(f, varargin{:});

        end

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = true )

        % Convert Chebyshev coefficients to values:
        varargout = coeffs2vals(U, varargin);

        % Convert values to Chebyshev coefficients:
        varargout = vals2coeffs(U, varargin);

        % Padua points to tensor grid:
        [C, V, X, Y] = paduaVals2coeffs( F, dom );

        % Tensor product of Chebyshev points:
        [xx, yy] = chebpts2(nx, ny, domain, kind);

        % Outer-product of two chebfuns:
        F = outerProduct(f, g);

        % Fast spectrally-accurate Poisson solver:
        u = poisson(f, varargin);

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% Private Static methods implemented by CHEBFUN2 class.
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = private, Static = true )

    end

end


function [subtree, nroot_node] = min_subtree_con_nodes(jtree, root, nodes)
%min_subtree_con_nodes get the minimum subtree of tree which contains the nodes

if isempty(jtree) | isempty(nodes)
    subtree = [];
    nroot_node = [];
    return;
end

rnodes = min_subtree_nodes(jtree, nodes);
nea_node = nearest_node(jtree, root, nodes);
node_num = length(jtree);
subtree = zeros(node_num);
subtree(rnodes, rnodes) = jtree(rnodes, rnodes);
nroot_node = nea_node;

function rnodes = min_subtree_nodes(tree, nodes)
rnodes = [];
if isempty(tree) | isempty(nodes)
    return
end

rnodes = nodes(1);
newnodes = neighbors(tree, nodes(1));
while ~mysubset(nodes, rnodes)
    swapnodes = newnodes;
    newnodes = [];
    added = 0;
    for i=1:length(swapnodes)
        inode = swapnodes(i);
        tnodes = myunion(inode, rnodes);
        if mysubset(nodes, tnodes)
            added = 1;
            break;
        end
        nns = neighbors(tree, inode);
        add_nodes = mysetdiff(nns, tnodes);
        newnodes = myunion(newnodes, add_nodes);
    end
    if added
        rnodes = tnodes;
    else
        rnodes = myunion(rnodes, newnodes);
    end
end

function nea_node = nearest_node(tree, inode, nodes)
if myismember(inode, nodes)
    nea_node = inode;
    return;
end
cs = children(tree, inode);
for i = 1:length(cs)
    n = cs(i);
    nea_node = nearest_node(tree, n, nodes);
end


function [params, names] = rbfwhiteKernExtractParam(kern)

% RBFWHITEKERNEXTRACTPARAM Extract parameters from the RBF-WHITE kernel
% structure.
% FORMAT
% DESC extracts parameters from the RBF-WHITE kernel structure into a vector
% of parameters for optimisation.
% ARG kern : the kernel structure containing the parameters to be
% extracted.
% RETURN param : vector of parameters extracted from the kernel. If
% the field 'transforms' is not empty in the kernel structure, the
% parameters will be transformed before optimisation (for example
% positive only parameters could be logged before being returned).
%
% FORMAT
% DESC extracts parameters and parameter names from the RBF-WHITE kernel
% structure.
% ARG kern : the kernel structure containing the parameters to be
% extracted.
% RETURN param : vector of parameters extracted from the kernel. If the
% field 'transforms' is not empty in the kernel structure, the parameters
% will be transformed before optimisation (for example positive only
% parameters could be logged before being returned).
% RETURN names : cell array of strings containing names for each
% parameter.
%
% SEEALSO rbfwhiteKernParamInit, rbfwhiteKernExpandParam, kernExtractParam,
% scg, conjgrad
%
% COPYRIGHT : David Luengo, 2009
%
% KERN

params = [kern.inverseWidth kern.variance];
if nargout > 1
  names = {'inverse width', 'variance'};
end


classdef svm < dml.method
% SVM support vector machine.
%
% DESCRIPTION
% Linear support vector machine classifier
%
%   EXAMPLE
%   X = rand(10,20); Y = [1 1 1 1 1 2 2 2 2 2]';
%   m = dml.svm
%   m = m.train(X,Y);
%   Z = m.test(X);
%
%   DEVELOPER
%   Jason Farquhar (j.farquhar@donders.ru.nl)

  properties

    X % training data

    primal % weights in primal form

    dual % weights in dual form

    C % regularization parameter

    kernel = 'linear'; % type of kernel

    Ktrain % precomputed kernel for training data
    Ktest  % precomputed kernel for test data

    distance = false; % return distance from decision boundary instead of class label
    native   = false; % uses native Bioinformatics toolbox SVM implementation if true
    issqrtmK = false;
  end

  methods

    function obj = svm(varargin)

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

    end

    function obj = train(obj,X,Y)

      opts = {'verb' -1};

      % handle multiple datasets
      if iscell(X)
        obj = dml.ndata('method',obj);
        obj = obj.train(X,Y);
        return;
      end

      if obj.native
        obj.Ktrain = fitcsvm(X,Y);
        return
      end

      if obj.restart || isempty(obj.dual)

        obj.X      = X;
        obj.Ktrain = compKernel(X,X,obj.kernel,obj.Ktrain);
        obj.Ktest  = [];

        if isempty(obj.C)
          if obj.issqrtmK
            % the actual kernel will be K*K'
            diagK = sum(obj.Ktrain.^2,2);
            meanK = mean(reshape(obj.Ktrain*obj.Ktrain',[],1));
          else
            diagK = diag(obj.Ktrain);
            meanK = mean(obj.Ktrain(:));
          end
          obj.C = .1*(mean(diagK)-meanK);
          if obj.verbose, fprintf('using default C=%.2f\n',obj.C); end
        end

        if obj.issqrtmK
          opts = cat(2, opts, {'issqrtmK' true});
        end
        obj.dual = l2svm_cg(obj.Ktrain,2*(Y-1)-1,obj.C, opts);

      else

        % facilitate warm restarts
        obj.dual = l2svm_cg(obj.Ktrain,2*(Y-1)-1,obj.C, opts); %,'alphab',obj.dual);

      end

      obj.primal = 0;
      for j = 1:size(X,1)
        obj.primal = obj.primal + obj.dual(j)*X(j,:);
      end

    end

    function Y = test(obj,X)

      if obj.native
        C = svmclassify(obj.Ktrain,X);
        Y = zeros(size(C,1),2);
        Y(C + (0:2:(2*(size(C,1)-1)))')=1;
        return
      end

      if isempty(obj.Ktest)
        obj.Ktest = compKernel(X,obj.X,'linear');
      end

      probs = obj.Ktest * obj.dual(1:end-1) + obj.dual(end);

      Y = zeros(numel(probs),2);
      if obj.distance

        Y(probs<0,1) = abs(probs(probs<0));
        Y(probs>0,2) = abs(probs(probs>0));

      else
        % post is just the sign and does not have a probabilistic interpretation
        Y(:,1) = (probs < 0);
        Y(:,2) = (probs > 0);
      end

    end

    function m = model(obj)
    % returns
    %
    % m.primal primal form SVM parameters

      m.primal = obj.primal;

    end

  end

end


%%%  Replication files for:
%%%  ""Nowcasting", 2010, (by Marta Banbura, Domenico Giannone and Lucrezia Reichlin),
%%% in Michael P. Clements and David F. Hendry, editors, Oxford Handbook on Economic Forecasting.
%%%
%%% The software can be freely used in applications.
%%% Users are kindly requested to add acknowledgements to published work and
%%% to cite the above reference in any resulting publications
%
%Description:
%
%remNaNs    Treats NaNs in dataset for use in DFM.
%
%  Syntax:
%    [X,indNaN] = remNaNs(X,options)
%
%  Description:
%    remNaNs() processes NaNs in a data matrix X according to 5 cases (see
%    below for details). These are useful for running functions in the
%    'DFM.m' file that do not take missing value inputs.
%
%  Input parameters:
%    X (T x n): Input data where T gives time and n gives the series.
%    options: A structure with two elements:
%      options.method (numeric):
%      - 1: Replaces all missing values using filter().
%      - 2: Replaces missing values after removing trailing and leading
%           zeros (a row is 'missing' if >80% is NaN)
%      - 3: Only removes rows with leading and closing zeros
%      - 4: Replaces missing values after removing trailing and leading
%           zeros (a row is 'missing' if all are NaN)
%      - 5: Replaces missing values with spline() then runs filter().
%
%      options.k (numeric): remNaNs() relies on MATLAB's filter function
%      for the 1-D filter. k controls the rational transfer function
%      argument's numerator (the denominator is set to 1). More
%      specifically, the numerator takes the form 'ones(2*k+1,1)/(2*k+1)'
%      For additional help, see MATLAB's documentation for filter().
%
%  Output parameters:
%    X: Outputted data.
%    indNaN: A matrix indicating the location for missing values (1 for NaN).

function [X,indNaN] = remNaNs_spline(X,options)
[T,N]=size(X);    % Gives dimensions for data input
k=options.k;      % Inputted options
indNaN=isnan(X);  % Returns location of NaNs

switch options.method
    case 1  % replace all the missing values
        for i = 1:N  % loop through columns
            x = X(:,i);
            x(indNaN(:,i))= nan_median(x);  % Replace missing values series median
            x_MA =filter (ones(2*k+1,1)/(2*k+1), 1, [x(1)*ones(k,1);x;x(end)*ones(k,1)]);
            x_MA=x_MA(2*k+1:end);  % Match dimensions
            % Replace missing observations with filtered values
            x(indNaN(:,i))=x_MA(indNaN(:,i));
            X(:,i)=x;  % Replace vector
        end
    case 2 %replace missing values after removing leading and closing zeros

        % Returns row sum for NaN values. Marks true for rows with more
        % than 80% NaN
        rem1=(sum(indNaN,2)>N*0.8);
        nanLead =(cumsum(rem1)==(1:T)');
        nanEnd =(cumsum(rem1(end:-1:1))==(1:T)');
        nanEnd = nanEnd(end:-1:1);  % Reverses nanEnd
        nanLE = (nanLead | nanEnd);

        % Subsets X for for
        X(nanLE,:) = [];
        indNaN = isnan(X);  % Index for missing values
        % Loop for each series
        for i = 1:N
            x = X(:,i);
            isnanx = isnan(x);
            t1 = min(find(~isnanx));  % First non-NaN entry
            t2 = max(find(~isnanx));  % Last non-NaN entry
            % Interpolates without NaN entries in beginning and end
            x(t1:t2) = spline(find(~isnanx),x(~isnanx),(t1:t2)');
            isnanx = isnan(x);
            % replace NaN observations with median
            x(isnanx) = median(x,'omitnan');
            % Apply filter
            x_MA = filter (ones(2*k+1,1)/(2*k+1),1,[x(1)*ones(k,1);x;x(end)*ones(k,1)]);
            x_MA = x_MA(2*k+1:end);
            % Replace nanx with filtered observations
            x(isnanx) = x_MA(isnanx);
            X(:,i) = x;
        end
    case 3 %only remove rows with leading and closing zeros
        rem1=(sum(indNaN,2)==N);
        nanLead=(cumsum(rem1)==(1:T)');
        nanEnd=(cumsum(rem1(end:-1:1))==(1:T)');
        nanEnd=nanEnd(end:-1:1);
        nanLE=(nanLead | nanEnd);
        X(nanLE,:)=[];
        indNaN = isnan(X);
    case 4  %remove rows with leading and closing zeros & replace missing values
        rem1=(sum(indNaN,2)==N);
        nanLead=(cumsum(rem1)==(1:T)');
        nanEnd=(cumsum(rem1(end:-1:1))==(1:T)');
        nanEnd=nanEnd(end:-1:1);
        nanLE=(nanLead | nanEnd);
        X(nanLE,:)=[];
        indNaN=isnan(X);
        for i = 1:N
            x = X(:,i);
            isnanx = isnan(x);
            t1 = min(find(~isnanx));
            t2 = max(find(~isnanx));
            x(t1:t2) = spline(find(~isnanx),x(~isnanx),(t1:t2)');
            isnanx = isnan(x);
            x(isnanx)=nan_median(x);
            x_MA =filter (ones(2*k+1,1)/(2*k+1),1,[x(1)*ones(k,1);x;x(end)*ones(k,1)]);
            x_MA=x_MA(2*k+1:end);
            x(isnanx)=x_MA(isnanx);
            X(:,i)=x;
        end
    case 5 %replace missing values
        indNaN=isnan(X);
        for i = 1:N
            x = X(:,i);
            isnanx = isnan(x);
            t1 = min(find(~isnanx));
            t2 = max(find(~isnanx));
            x(t1:t2) = spline(find(~isnanx),x(~isnanx),(t1:t2)');
            isnanx = isnan(x);
            x(isnanx)=nan_median(x);
            x_MA =filter (ones(2*k+1,1)/(2*k+1),1,[x(1)*ones(k,1);x;x(end)*ones(k,1)]);
            x_MA=x_MA(2*k+1:end);
            x(isnanx)=x_MA(isnanx);
            X(:,i)=x;
        end
end


function tests = test_spm_dcm_loo
% Unit Tests for test_spm_dcm_peb
%__________________________________________________________________________
% Copyright (C) 2016 Wellcome Trust Centre for Neuroimaging

% $Id: test_spm_dcm_loo.m 7102 2017-06-08 12:56:06Z peter $

tests = functiontests(localfunctions);

% -------------------------------------------------------------------------
function test_loo_group(testCase)
% Tests LOO cross-validation in the presence of a binary group effect

data_path = get_data_path();

% Reduce number of subjects to increase performance
s = [1:6 24:30];

% Load first level DCMs
GCM = load(fullfile(data_path,'models','GCM_simulated.mat'));
GCM = GCM.GCM(s,:);

% Prepare group level design matrix
X  = load(fullfile(data_path,'design_matrix.mat'));
X  = X.X(s,:);
ns = size(X,1);
X  = [ones(ns,1) X];

% Run
M.X = X;
[qE,qC,Q] = spm_dcm_loo(GCM(:,2),M,{'B'});

% Test that classical p-value is significant
[T,df] = spm_ancova(M.X(:,1:2),[],qE(:),[0;1]);
p = 1 - spm_Tcdf(T,df(2));
testCase.assertTrue(p < 0.05);

% -------------------------------------------------------------------------
function test_loo_group_null(testCase)
% Tests LOO cross-validation in the absence of a binary group effect

data_path = get_data_path();

% Reduce number of subjects to increase performance
s = [1:6 24:30];

% Load first level DCMs
GCM = load(fullfile(data_path,'models','GCM_simulated.mat'));
GCM = GCM.GCM(s,:);

% Prepare group level design matrix
X  = load(fullfile(data_path,'design_matrix.mat'));
X  = X.X(s,:);
ns = size(X,1);
X  = [ones(ns,1) X];

% Run
M.X = X;
[qE,qC,Q] = spm_dcm_loo(GCM(:,2),M,{'A'});

% Test that classical p-value is significant
[T,df] = spm_ancova(M.X(:,1:2),[],qE(:),[0;1]);
p = 1 - spm_Tcdf(T,df(2));
testCase.assertTrue(p > 0.05);

% -------------------------------------------------------------------------
function test_loo_continuous_null(testCase)
% Tests LOO cross-validation in the absence of a continuous group effect

data_path = get_data_path();

% Reduce number of subjects to increase performance
s = [1:6 24:30];

% Load first level DCMs
GCM = load(fullfile(data_path,'models','GCM_simulated.mat'));
GCM = GCM.GCM(s,:);

% Prepare group level design matrix
X  = load(fullfile(data_path,'design_matrix.mat'));
X  = X.X(s,:);
ns = size(X,1);
X  = [ones(ns,1) X];

% Re-order to test random age covariate
X = X(:,[1 3 2]);

% Run
M.X = X;
[qE,qC,Q] = spm_dcm_loo(GCM(:,2),M,{'B'});

% Test that classical p-value is significant
[T,df] = spm_ancova(M.X(:,1:2),[],qE(:),[0;1]);
p = 1 - spm_Tcdf(T,df(2));
testCase.assertTrue(p >= 0.05);

% -------------------------------------------------------------------------
function data_path = get_data_path()

data_path = fullfile( spm('Dir'), 'tests', ...
    'data', 'fMRI', 'simulated_2region');


function varargout = pm_pad(varargin)
% Pads a (partially) unwrapped phasemap such that the phase
% at a non-unwrapped location is a weighted average of unwrapped
% neighbouring phase-values.
% FORMAT [pm,wmap] = pm_pad(pm,wmap,kernel)
%
% Input:
% pm     : 2 or 3D phasemap where some voxels have been unwrapped
%          and some not.
% wmap   : Wrap-map, where a non-zero value indicates corresponding
%          phase-value in pm has been unwrapped.
% kernel : kernel used to generate a weighted average of surrounding
%          voxels.
%
% Output:
% pm     : Same as pm in, but where some previously unwrapped
%          phase-values have now been replaced.
% wmap   : Same as wmap in, but where values that was replaced
%          by weighted average in pm have now been set.
%__________________________________________________________________________
% Copyright (C) 2008-2015 Wellcome Trust Centre for Neuroimaging

% Jesper Andersson
% $Id: pm_pad.m 6501 2015-07-17 14:32:09Z spm $

error('mex-function pm_pad.c not compiled');