function y = vl_nnloss(x,c,varargin)
%VL_NNLOSS CNN categorical or attribute loss.
%   Y = VL_NNLOSS(X, C) computes the loss incurred by the prediction
%   scores X given the categorical labels C.
%
%   The prediction scores X are organised as a field of prediction
%   vectors, represented by a H x W x D x N array. The first two
%   dimensions, H and W, are spatial and correspond to the height and
%   width of the field; the third dimension D is the number of
%   categories or classes; finally, the dimension N is the number of
%   data items (images) packed in the array.
%
%   While often one has H = W = 1, the case W, H > 1 is useful in
%   dense labelling problems such as image segmentation. In the latter
%   case, the loss is summed across pixels (contributions can be
%   weighed using the `InstanceWeights` option described below).
%
%   The array C contains the categorical labels. In the simplest case,
%   C is an array of integers in the range [1, D] with N elements
%   specifying one label for each of the N images. If H, W > 1, the
%   same label is implicitly applied to all spatial locations.
%
%   In the second form, C has dimension H x W x 1 x N and specifies a
%   categorical label for each spatial location.
%
%   In the third form, C has dimension H x W x D x N and specifies
%   attributes rather than categories. Here elements in C are either
%   +1 or -1 and C, where +1 denotes that an attribute is present and
%   -1 that it is not. The key difference is that multiple attributes
%   can be active at the same time, while categories are mutually
%   exclusive. By default, the loss is *summed* across attributes
%   (unless otherwise specified using the `InstanceWeights` option
%   described below).
%
%   DZDX = VL_NNLOSS(X, C, DZDY) computes the derivative of the block
%   projected onto the output derivative DZDY. DZDX and DZDY have the
%   same dimensions as X and Y respectively.
%
%   VL_NNLOSS() supports several loss functions, which can be selected
%   by using the option `type` described below. When each scalar c in
%   C is interpreted as a categorical label (first two forms above),
%   the following losses can be used:
%
%   Classification error:: `classerror`
%     L(X,c) = (argmax_q X(q) ~= c). Note that the classification
%     error derivative is flat; therefore this loss is useful for
%     assessment, but not for training a model.
%
%   Top-K classification error:: `topkerror`
%     L(X,c) = (rank X(c) in X <= K). The top rank is the one with
%     highest score. For K=1, this is the same as the
%     classification error. K is controlled by the `topK` option.
%
%   Log loss:: `log`
%     L(X,c) = - log(X(c)). This function assumes that X(c) is the
%     predicted probability of class c (hence the vector X must be non
%     negative and sum to one).
%
%   Softmax log loss (multinomial logistic loss):: `softmaxlog`
%     L(X,c) = - log(P(c)) where P(c) = exp(X(c)) / sum_q exp(X(q)).
%     This is the same as the `log` loss, but renormalizes the
%     predictions using the softmax function.
%
%   Multiclass hinge loss:: `mhinge`
%     L(X,c) = max{0, 1 - X(c)}. This function assumes that X(c) is
%     the score margin for class c against the other classes.  See
%     also the `mmhinge` loss below.
%
%   Multiclass structured hinge loss:: `mshinge`
%     L(X,c) = max{0, 1 - M(c)} where M(c) = X(c) - max_{q ~= c}
%     X(q). This is the same as the `mhinge` loss, but computes the
%     margin between the prediction scores first. This is also known
%     the Crammer-Singer loss, an example of a structured prediction
%     loss.
%
%   When C is a vector of binary attribures c in (+1,-1), each scalar
%   prediction score x is interpreted as voting for the presence or
%   absence of a particular attribute. The following losses can be
%   used:
%
%   Binary classification error:: `binaryerror`
%     L(x,c) = (sign(x - t) ~= c). t is a threshold that can be
%     specified using the `threshold` option and defaults to zero. If
%     x is a probability, it should be set to 0.5.
%
%   Binary log loss:: `binarylog`
%     L(x,c) = - log(c(x-0.5) + 0.5). x is assumed to be the
%     probability that the attribute is active (c=+1). Hence x must be
%     a number in the range [0,1]. This is the binary version of the
%     `log` loss.
%
%   Logistic log loss:: `logistic`
%     L(x,c) = log(1 + exp(- cx)). This is the same as the `binarylog`
%     loss, but implicitly normalizes the score x into a probability
%     using the logistic (sigmoid) function: p = sigmoid(x) = 1 / (1 +
%     exp(-x)). This is also equivalent to `softmaxlog` loss where
%     class c=+1 is assigned score x and class c=-1 is assigned score
%     0.
%
%   Hinge loss:: `hinge`
%     L(x,c) = max{0, 1 - cx}. This is the standard hinge loss for
%     binary classification. This is equivalent to the `mshinge` loss
%     if class c=+1 is assigned score x and class c=-1 is assigned
%     score 0.
%
%   VL_NNLOSS(...,'OPT', VALUE, ...) supports these additionals
%   options:
%
%   InstanceWeights:: []
%     Allows to weight the loss as L'(x,c) = WGT L(x,c), where WGT is
%     a per-instance weight extracted from the array
%     `InstanceWeights`. For categorical losses, this is either a H x
%     W x 1 or a H x W x 1 x N array. For attribute losses, this is
%     either a H x W x D or a H x W x D x N array.
%
%   TopK:: 5
%     Top-K value for the top-K error. Note that K should not
%     exceed the number of labels.
%
%   See also: VL_NNSOFTMAX().

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

if ~isempty(varargin) && ~ischar(varargin{1})  % passed in dzdy
  dzdy = varargin{1} ;
  varargin(1) = [] ;
else
  dzdy = [] ;
end

opts.instanceWeights = [] ;
opts.classWeights = [] ;
opts.threshold = 0 ;
opts.loss = 'softmaxlog' ;
opts.topK = 5 ;
opts = vl_argparse(opts, varargin, 'nonrecursive') ;

inputSize = [size(x,1) size(x,2) size(x,3) size(x,4)] ;

% Form 1: C has one label per image. In this case, get C in form 2 or
% form 3.
c = gather(c) ;
if numel(c) == inputSize(4)
  c = reshape(c, [1 1 1 inputSize(4)]) ;
  c = repmat(c, inputSize(1:2)) ;
end

hasIgnoreLabel = any(c(:) == 0);

% --------------------------------------------------------------------
% Spatial weighting
% --------------------------------------------------------------------

% work around a bug in MATLAB, where native cast() would slow
% progressively
if isa(x, 'gpuArray')
  switch classUnderlying(x) ;
    case 'single', cast = @(z) single(z) ;
    case 'double', cast = @(z) double(z) ;
  end
else
  switch class(x)
    case 'single', cast = @(z) single(z) ;
    case 'double', cast = @(z) double(z) ;
  end
end

labelSize = [size(c,1) size(c,2) size(c,3) size(c,4)] ;
assert(isequal(labelSize(1:2), inputSize(1:2))) ;
assert(labelSize(4) == inputSize(4)) ;
instanceWeights = [] ;
switch lower(opts.loss)
  case {'classerror', 'topkerror', 'log', 'softmaxlog', 'mhinge', 'mshinge'}
    % there must be one categorical label per prediction vector
    assert(labelSize(3) == 1) ;

    if hasIgnoreLabel
      % null labels denote instances that should be skipped
      instanceWeights = cast(c(:,:,1,:) ~= 0) ;
    end

  case {'binaryerror', 'binarylog', 'logistic', 'hinge'}

    % there must be one categorical label per prediction scalar
    assert(labelSize(3) == inputSize(3)) ;

    if hasIgnoreLabel
      % null labels denote instances that should be skipped
      instanceWeights = cast(c ~= 0) ;
    end

  otherwise
    error('Unknown loss ''%s''.', opts.loss) ;
end

if ~isempty(opts.instanceWeights)
  % important: this code needs to broadcast opts.instanceWeights to
  % an array of the same size as c
  if isempty(instanceWeights)
    instanceWeights = bsxfun(@times, onesLike(c), opts.instanceWeights) ;
  else
    instanceWeights = bsxfun(@times, instanceWeights, opts.instanceWeights);
  end
end

% --------------------------------------------------------------------
% Do the work
% --------------------------------------------------------------------

switch lower(opts.loss)
  case {'log', 'softmaxlog', 'mhinge', 'mshinge'}
    % from category labels to indexes
    numPixelsPerImage = prod(inputSize(1:2)) ;
    numPixels = numPixelsPerImage * inputSize(4) ;
    imageVolume = numPixelsPerImage * inputSize(3) ;

    n = reshape(0:numPixels-1,labelSize) ;
    offset = 1 + mod(n, numPixelsPerImage) + ...
             imageVolume * fix(n / numPixelsPerImage) ;
    ci = offset + numPixelsPerImage * max(c - 1,0) ;
end

if nargin <= 2 || isempty(dzdy)
  switch lower(opts.loss)
    case 'classerror'
      [~,chat] = max(x,[],3) ;
      t = cast(c ~= chat) ;
    case 'topkerror'
      [~,predictions] = sort(x,3,'descend') ;
      t = 1 - sum(bsxfun(@eq, c, predictions(:,:,1:opts.topK,:)), 3) ;
    case 'log'
      t = - log(x(ci)) ;
    case 'softmaxlog'
      Xmax = max(x,[],3) ;
      ex = exp(bsxfun(@minus, x, Xmax)) ;
      t = Xmax + log(sum(ex,3)) - x(ci) ;
    case 'mhinge'
      t = max(0, 1 - x(ci)) ;
    case 'mshinge'
      Q = x ;
      Q(ci) = -inf ;
      t = max(0, 1 - x(ci) + max(Q,[],3)) ;
    case 'binaryerror'
      t = cast(sign(x - opts.threshold) ~= c) ;
    case 'binarylog'
      t = -log(c.*(x-0.5) + 0.5) ;
    case 'logistic'
      %t = log(1 + exp(-c.*X)) ;
      a = -c.*x ;
      b = max(0, a) ;
      t = b + log(exp(-b) + exp(a-b)) ;
    case 'hinge'
      t = max(0, 1 - c.*x) ;
  end
  if ~isempty(instanceWeights)
    y = instanceWeights(:)' * t(:) ;
  else
    y = sum(t(:));
  end
else
  if ~isempty(instanceWeights)
    dzdy = dzdy * instanceWeights ;
  end
  switch lower(opts.loss)
    case {'classerror', 'topkerror'}
      y = zerosLike(x) ;
    case 'log'
      y = zerosLike(x) ;
      y(ci) = - dzdy ./ max(x(ci), 1e-8) ;
    case 'softmaxlog'
      Xmax = max(x,[],3) ;
      ex = exp(bsxfun(@minus, x, Xmax)) ;
      y = bsxfun(@rdivide, ex, sum(ex,3)) ;
      y(ci) = y(ci) - 1 ;
      y = bsxfun(@times, dzdy, y) ;
    case 'mhinge'
      y = zerosLike(x) ;
      y(ci) = - dzdy .* (x(ci) < 1) ;
    case 'mshinge'
      Q = x ;
      Q(ci) = -inf ;
      [~, q] = max(Q,[],3) ;
      qi = offset + numPixelsPerImage * (q - 1) ;
      W = dzdy .* (x(ci) - x(qi) < 1) ;
      y = zerosLike(x) ;
      y(ci) = - W ;
      y(qi) = + W ;
    case 'binaryerror'
      y = zerosLike(x) ;
    case 'binarylog'
      y = - dzdy ./ (x + (c-1)*0.5) ;
    case 'logistic'
      % t = exp(-Y.*X) / (1 + exp(-Y.*X)) .* (-Y)
      % t = 1 / (1 + exp(Y.*X)) .* (-Y)
      y = - dzdy .* c ./ (1 + exp(c.*x)) ;
    case 'hinge'
      y = - dzdy .* c .* (c.*x < 1) ;
  end
end

% --------------------------------------------------------------------
function y = zerosLike(x)
% --------------------------------------------------------------------
if isa(x,'gpuArray')
  y = gpuArray.zeros(size(x),classUnderlying(x)) ;
else
  y = zeros(size(x),'like',x) ;
end

% --------------------------------------------------------------------
function y = onesLike(x)
% --------------------------------------------------------------------
if isa(x,'gpuArray')
  y = gpuArray.ones(size(x),classUnderlying(x)) ;
else
  y = ones(size(x),'like',x) ;
end


function cae = caenumgradcheck(cae, x, y)
    epsilon = 1e-4;
    er = 1e-6;
    disp('performing numerical gradient checking...')
    for i = 1 : numel(cae.o)
        p_cae = cae; p_cae.c{i} = p_cae.c{i} + epsilon;
        m_cae = cae; m_cae.c{i} = m_cae.c{i} - epsilon;

        [m_cae, p_cae] = caerun(m_cae, p_cae, x, y);
        d = (p_cae.L - m_cae.L) / (2 * epsilon);

        e = abs(d - cae.dc{i});
        if e > er
            disp('OUTPUT BIAS numerical gradient checking failed');
            disp(e);
            disp(d / cae.dc{i});
            keyboard
        end
    end

    for a = 1 : numel(cae.a)

        p_cae = cae; p_cae.b{a} = p_cae.b{a} + epsilon;
        m_cae = cae; m_cae.b{a} = m_cae.b{a} - epsilon;

        [m_cae, p_cae] = caerun(m_cae, p_cae, x, y);
        d = (p_cae.L - m_cae.L) / (2 * epsilon);
%        cae.dok{i}{a}(u) = d;
        e = abs(d - cae.db{a});
        if e > er
            disp('BIAS numerical gradient checking failed');
            disp(e);
            disp(d / cae.db{a});
            keyboard
        end

        for i = 1 : numel(cae.o)
            for u = 1 : numel(cae.ok{i}{a})
                p_cae = cae; p_cae.ok{i}{a}(u) = p_cae.ok{i}{a}(u) + epsilon;
                m_cae = cae; m_cae.ok{i}{a}(u) = m_cae.ok{i}{a}(u) - epsilon;

                [m_cae, p_cae] = caerun(m_cae, p_cae, x, y);
                d = (p_cae.L - m_cae.L) / (2 * epsilon);
%                cae.dok{i}{a}(u) = d;
                e = abs(d - cae.dok{i}{a}(u));
                if e > er
                    disp('OUTPUT KERNEL numerical gradient checking failed');
                    disp(e);
                    disp(d / cae.dok{i}{a}(u));
%                    keyboard
                end
            end
        end

        for i = 1 : numel(cae.i)
            for u = 1 : numel(cae.ik{i}{a})
                p_cae = cae;
                m_cae = cae;
                p_cae.ik{i}{a}(u) = p_cae.ik{i}{a}(u) + epsilon;
                m_cae.ik{i}{a}(u) = m_cae.ik{i}{a}(u) - epsilon;
                [m_cae, p_cae] = caerun(m_cae, p_cae, x, y);
                d = (p_cae.L - m_cae.L) / (2 * epsilon);
%                cae.dik{i}{a}(u) = d;
                e = abs(d - cae.dik{i}{a}(u));
                if e > er
                    disp('INPUT KERNEL numerical gradient checking failed');
                    disp(e);
                    disp(d / cae.dik{i}{a}(u));
                end
            end
        end
    end

    disp('done')

end

function [m_cae, p_cae] = caerun(m_cae, p_cae, x, y)
    m_cae = caeup(m_cae, x); m_cae = caedown(m_cae); m_cae = caebp(m_cae, y);
    p_cae = caeup(p_cae, x); p_cae = caedown(p_cae); p_cae = caebp(p_cae, y);
end

%function checknumgrad(cae,what,x,y)
%    epsilon = 1e-4;
%    er = 1e-9;
%
%    for i = 1 : numel(eval(what))
%        if iscell(eval(['cae.' what]))
%            checknumgrad(cae,[what '{' num2str(i) '}'], x, y)
%        else
%            p_cae = cae;
%            m_cae = cae;
%            eval(['p_cae.' what '(' num2str(i) ')']) = eval([what '(' num2str(i) ')']) + epsilon;
%            eval(['m_cae.' what '(' num2str(i) ')']) = eval([what '(' num2str(i) ')']) - epsilon;
%
%            m_cae = caeff(m_cae, x); m_cae = caedown(m_cae); m_cae = caebp(m_cae, y);
%            p_cae = caeff(p_cae, x); p_cae = caedown(p_cae); p_cae = caebp(p_cae, y);
%
%            d = (p_cae.L - m_cae.L) / (2 * epsilon);
%            e = abs(d - eval(['cae.d' what '(' num2str(i) ')']));
%            if e > er
%                error('numerical gradient checking failed');
%            end
%         end
%     end
%
% end


function val=wavelet_coeff(data,fs)
num_layers=7;
num_coeffs=8;
[h,g,rh,rg]=daub(num_coeffs);

wav_res=wt(data,h,g,num_layers);
pos=sub_pos(length(data),num_layers);
bands=extract_subbands(wav_res,pos);

%MEAN OF COEFFICIENTS AND ABSOLUTE ENERGY
for j=1:length(bands)
    mean_coeffs(j)=mean(abs(bands{j}));
end
val=mean_coeffs(5);


function wn=dn(w,type);
w = w*length(w);
w = double(w);
D=sum(abs(w),2)+eps;

if type == 'ave'
    D=1./D;
    D=sparse(1:length(D),1:length(D),D);
    wn=D*w;
elseif type == 'gph'
    D=1./sqrt(D);
    D=sparse(1:length(D),1:length(D),D);
    wn=D*(w*D);
end


function [K] = ku1u1(x, xp, hyp, i)

logsigmau = hyp(1);
logthetau = hyp(2);
logsigmav = hyp(3);
logthetav = hyp(4);

n_x = size(x,1);
n_xp = size(xp,1);

x = repmat(x,1,n_xp);
xp = repmat(xp',n_x,1);

switch i

case 0

K=exp(1).^(logsigmau+(-1/2).*exp(1).^((-1).*logthetau).*(x+(-1).*xp).^2); ...

case 1 % logsigmau

K=exp(1).^(logsigmau+(-1/2).*exp(1).^((-1).*logthetau).*(x+(-1).*xp).^2); ...

case 2 % logthetau

K=(1/2).*exp(1).^(logsigmau+(-1).*logthetau+(-1/2).*exp(1).^((-1).* ...
  logthetau).*(x+(-1).*xp).^2).*(x+(-1).*xp).^2;

case 3 % logsigmav

K=0;

case 4 % logthetav

K=0;

otherwise

        K = zeros(n_x, n_xp);
end

if K == 0

    K = zeros(n_x, n_xp);

end

end


function that = spm_swarp(this,def,M)
% Warp surface
% FORMAT that = spm_swarp(this,def)
% this - a gifti object
% def  - a deformation (nifti object or filename)
% that - the warped gifti object
%
% FORMAT that = spm_swarp(this,def,M)
% this - a gifti object
% def  - a deformation field (nx*ny*nz*1*3)
% M    - mapping from voxels to world, for deformation field
% that - the warped gifti object
%
%__________________________________________________________________________
% Copyright (C) 2009-2015 Wellcome Trust Centre for Neuroimaging

% John Ashburner
% $Id: spm_swarp.m 6349 2015-02-26 12:15:06Z guillaume $

%-Input arguments
%--------------------------------------------------------------------------
this = gifti(this);

if nargin<2, that = this; return; end

if ischar(def) || isa(def,'nifti')
    if ischar(def)
        def = nifti(def);
    end
    y   = def(1).dat(:,:,:,:,:);
    M   = def(1).mat;
else
    y = def;
    if nargin<3, M = eye(4); end
end

%-Apply deformation to vertices
%--------------------------------------------------------------------------
v   = double(this.vertices);
iM  = inv(M);
v   = iM(1:3,1:4) * this.mat * [v'; ones(1,size(v,1))];
xyz = {v(1,:)',v(2,:)',v(3,:)'};
v   = [spm_bsplins(y(:,:,:,1,1), xyz{:}, [1 1 1 0 0 0]),...
       spm_bsplins(y(:,:,:,1,2), xyz{:}, [1 1 1 0 0 0]),...
       spm_bsplins(y(:,:,:,1,3), xyz{:}, [1 1 1 0 0 0])];

% Much of the surface data is likely to fall outside the FOV of the
% deformation field.  For this reason, the following code attempts to
% extrapolate the surfaces outside this FOV by replacing NaNs in the
% vertice coordinates by some smooth mesh.
%--------------------------------------------------------------------------
if isfield(this, 'faces')
    f = double(this.faces);
    m = size(v,1);

    % Gradients
    b = double([v(:,1); v(:,2); v(:,3)]);
    w = isfinite(b);
    b(~w) = 0;

    % Hessian
    A = spdiags(w,0,m*3,m*3);
    W = sparse(f(:,1),f(:,1),1,m,m) + sparse(f(:,2),f(:,2),1,m,m) + sparse(f(:,3),f(:,3),1,m,m)...
        - sparse(f(:,1),f(:,2),1,m,m) - sparse(f(:,2),f(:,3),1,m,m) - sparse(f(:,3),f(:,1),1,m,m);
    W = (W'*W + 0.25*W)*1e-2;
    Z = sparse([],[],[],m,m);
    A = A + [W Z Z; Z W Z; Z Z W];

    % Solution to simple linear model
    v = full(reshape(A\b,m,3));
end

%-Generate the gifti structure for the warped data
%--------------------------------------------------------------------------
that = this;
that.vertices = v;
that.mat = eye(4); % this.mat already applied to v


classdef ARMOEA < ALGORITHM
% <multi/many> <real/integer/label/binary/permutation> <constrained/none>
% Adaptive reference points based multi-objective evolutionary algorithm

%------------------------------- Reference --------------------------------
% Y. Tian, R. Cheng, X. Zhang, and Y. Jin, An indicator-based
% multiobjective evolutionary algorithm with reference point adaptation for
% better versatility, IEEE Transactions on Evolutionary Computation, 2018,
% 22(4): 609-622.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    methods
        function main(Algorithm,Problem)
            %% Generate the sampling points and random population
            Population = Problem.Initialization();
            W          = UniformPoint(Problem.N,Problem.M);
            [Archive,RefPoint,Range] = UpdateRefPoint(Population(all(Population.cons<=0,2)).objs,W,[]);

            %% Optimization
            while Algorithm.NotTerminated(Population)
                MatingPool = MatingSelection(Population,RefPoint,Range);
                Offspring  = OperatorGA(Problem,Population(MatingPool));
                [Archive,RefPoint,Range] = UpdateRefPoint([Archive;Offspring(all(Offspring.cons<=0,2)).objs],W,Range);
                [Population,Range]       = EnvironmentalSelection([Population,Offspring],RefPoint,Range,Problem.N);
            end
        end
    end
end


%==============================================================================
% This code is part of the Matlab-based toolbox
% LagLDDDM - A Lagrangian Gauss--Newton--Krylov Solver for Mass- and
%                        Intensity-Preserving Diffeomorphic Image Registration
%
% For details and license info see
% - https://github.com/C4IR/FAIR.m/tree/master/add-ons/LagLDDMM
%
% function [yc,dy,para] = getTrafoFromInstationaryVelocityRK4(vc,yc,varargin)
%
% compute transformation yc by integrating velocity field in time using a
% Runge-Kutta 4 method with fixed time steps. Velocity is time dependent
% here and assumed to be nodal in time. For stationary velocities, use
% getTrafoFromVelocityRK4.m
%
% For more details see Sec. 3 of the paper:
%
% @article{MangRuthotto2017,
%   Title = {A {L}agrangian {G}auss--{N}ewton--{K}rylov solver for mass- and intensity-preserving diffeomorphic image registration},
%   Year = {2017},
%   Journal = {SIAM Journal on Scientific Computing},
%   Author = {A. Mang, L. Ruthotto},
% }
%
% Input:
%  vc   - discrete velocity field (nodal, cell-centered, or staggered in space / nodal in time)
%  yc   - particle positions
%
% Additional REQUIRED Input (provided through varargin)
%
%  omega        - spatial domain (required!)
%  m            - number of cells in each direction (required!)
%
% Optional Input (provided through varargin)
%
%  doDerivative - compute derivative w.r.t. velocity
%  tspan        - time interval (default: [0 1])
%  N            - number of time steps (default: 5)
%  nt           - number of time points for velocity (default: compute from input)
%  storeInter   - store intermediate transformation (e.g., for visualization)
%
% Output:
%
%  yc           - end point of characteristics
%  dy           - derivative w.r.t. vc
%  para         - struct containing info
%
% =========================================================================
function [yc,dy,para] = getTrafoFromInstationaryVelocityRK4(vc,yc,varargin)

if nargin==0,
    runMinimalExample
    return;
end
doDerivative = (nargout>1);
omega = [];
m     = [];
tspan = [0,1];
N     = 5;
nt    = [];
storeInter = false;
for k=1:2:length(varargin)     % overwrites default parameter
    eval([varargin{k},'=varargin{',int2str(k+1),'};']);
end;
if isempty(omega) || isempty(m)
    error('%s - omega and m must be provided through varargin or trafo(''set'',''omega'',omega,''m'',m')
end
dim = numel(omega)/2;
if isempty(nt) % roughly estimate nt
    nt = round(numel(vc)/(prod(m)*dim))-1;
end
ht    = (tspan(2)-tspan(1))/nt;
tspan = (linspace(tspan(1),tspan(2),N)-min(tspan))/abs(ht)+1; % map to nodal indices
dt    = diff(tspan);
dt    = dt(1);
dy    = [];
if doDerivative
    dy = cell(nt+1,1);
    for j=1:nt+1, dy{j} = sparse(numel(yc),prod(m)*dim); end;
    dyi = dy;
end

para = struct('dt',dt,'N',N,'nt',nt,'omega',omega,'m',m);
if storeInter
    para.YC = zeros(numel(yc),N);
    para.YC(:,1) = yc;
end

vc = reshape(vc,[],nt+1);
for k=1:N-1
    % get v1 = v(yc,t(k));
    tk = tspan(k);
    p  = floor(tk); x = tk-p;  % split x into integer/remainder
    dvi      = zeros(nt+1,1);
    dvi(p)   = 1-x;
    if p<nt+1, dvi(p+1) = x; end
    vt = vc*dvi;
    [vi,dydvi] = linearInterGrid(vt,omega,m,yc,'doDerivative',doDerivative);
    if doDerivative
        Ty = getLinearInterGridMatrix(omega,m,yc);
        for j=1:nt+1
           dyi{j} = dvi(j)*Ty + dydvi*dy{j};
        end
        dytemp  = dyi;
    end
    yi = yc + .5*dt*vi;
	ytemp = vi;

    % get v2 = v(y1,.5*(t(k+1)+t(k)));
    tk1 = (tspan(k+1)+tspan(k))/2;
    p  = floor(tk1); x = tk1-p;  % split x into integer/remainder
    dvi      = zeros(nt+1,1);
    dvi(p)   = 1-x;
    if p<nt+1, dvi(p+1) = x; end
    vt = vc*dvi;
    [vi,dydvi] = linearInterGrid(vt,omega,m,yi,'doDerivative',doDerivative);
    if doDerivative
        Ty = getLinearInterGridMatrix(omega,m,yi);
        for j=1:nt+1
            dyi{j}    = dvi(j)*Ty + dydvi*(dy{j}+.5*dt*dyi{j});
            dytemp{j} = dytemp{j} + 2*dyi{j};
        end
    end
    yi = yc + .5*dt*vi;
	ytemp = ytemp + 2*vi;

    % get v3 = v(y2,.5*(t(k+1)+t(k)));
    [vi,dydvi] = linearInterGrid(vt,omega,m,yi,'doDerivative',doDerivative);
    if doDerivative
        Ty = getLinearInterGridMatrix(omega,m,yi);
        for j=1:nt+1
            dyi{j}    = dvi(j)*Ty + dydvi*(dy{j}+.5*dt*dyi{j});
            dytemp{j} = dytemp{j} + 2*dyi{j};
        end
    end
    yi  = yc + dt*vi;
	ytemp = ytemp + 2*vi;

    % get v4 = v(y3,t(k+1)));
    tk1 = tspan(k+1);
    p  = floor(tk1); x = tk1-p;  % split x into integer/remainder
    dvi      = zeros(nt+1,1);
    dvi(p)   = 1-x;
    if p<nt+1, dvi(p+1) = x; end
    vt = vc*dvi;
    [vi,dydvi] = linearInterGrid(vt,omega,m,yi,'doDerivative',doDerivative);
    if doDerivative
        Ty = getLinearInterGridMatrix(omega,m,yi);
        for j=1:nt+1
            dyi{j} = dvi(j)*Ty + dydvi*(dy{j}+dt*dyi{j});
            dytemp{j} = dytemp{j} + dyi{j};
            dy{j}  = dy{j} + (dt/6)*dytemp{j};
        end
    end
    ytemp = ytemp + vi;
    yc    = yc + (dt/6)*ytemp;
    if storeInter, para.YC(:,k+1) = yc; end
end
if doDerivative, dy = horzcat(dy{:}); end;

function runMinimalExample

omegaV = [-1 1 -1 1];
omega = .1*omegaV;
m     = [32 32];
tspan     = [8 0];
N     = 20;
yc    = getNodalGrid(omega,m)+.0002;

%
% % test cell-centered grid
regularizer('set','regularizer','mbCurvature','alpha',1)
xc      = reshape(getCellCenteredGrid(omegaV,m),[],2);
v0      = [.3*sign(xc(:,1)).*xc(:,1).^2; sin(pi*xc(:,2))];
vc      = v0*[1,1.1,1.5,2];
fctn    = @(vc) getTrafoFromInstationaryVelocityRK4(vc(:),yc,'omega',omegaV,'m',m,'T',tspan,'N',N);
checkDerivative(fctn,vc(:))


% PAC - compute phase-amplitude coupling (power of first input
%         correlation with phase of second). There is no graphical output
%         to this function.
%
% Usage:
%   >> pac(x,y,srate);
%   >> [coh,timesout,freqsout1,freqsout2,cohboot] ...
%                     = pac(x,y,srate,'key1', 'val1', 'key2', val2' ...);
% Inputs:
%    x       = [float array] 2-D data array of size (times,trials) or
%              3-D (1,times,trials)
%    y       = [float array] 2-D or 3-d data array
%    srate   = data sampling rate (Hz)
%
%    Most important optional inputs
%       'method'    = ['mod'|'corrsin'|'corrcos'|'latphase'] modulation
%                     method or correlation of amplitude with sine or cosine of
%                     angle (see ref). 'laphase' compute the phase
%                     histogram at a specific time and requires the
%                     'powerlat' option to be set.
%       'freqs'     = [min max] frequency limits. Default [minfreq 50],
%                     minfreq being determined by the number of data points,
%                     cycles and sampling frequency. Use 0 for minimum frequency
%                     to compute default minfreq. You may also enter an
%                     array of frequencies for the spectral decomposition
%                     (for FFT, closest computed frequency will be returned; use
%                     'padratio' to change FFT freq. resolution).
%       'freqs2'    = [float array] array of frequencies for the second
%                     argument. 'freqs' is used for the first argument.
%                     By default it is the same as 'freqs'.
%       'wavelet'   = 0  -> Use FFTs (with constant window length) { Default }
%                   = >0 -> Number of cycles in each analysis wavelet
%                   = [cycles expfactor] -> if 0 < expfactor < 1,  the number
%                     of wavelet cycles expands with frequency from cycles
%                     If expfactor = 1, no expansion; if = 0, constant
%                     window length (as in FFT)            {default wavelet: 0}
%                   = [cycles array] -> cycle for each frequency. Size of array
%                      must be the same as the number of frequencies
%                     {default cycles: 0}
%       'wavelet2'  = same as 'wavelet' for the second argument. Default is
%                     same as cycles. Note that if the lowest frequency for X
%                     and Y are different and cycle is [cycles expfactor], it
%                     may result in discrepancies in the number of cycles at
%                     the same frequencies for X and Y.
%       'ntimesout' = Number of output times (int<frames-winframes). Enter a
%                     negative value [-S] to subsample original time by S.
%       'timesout'  = Enter an array to obtain spectral decomposition at
%                     specific time values (note: algorithm find closest time
%                     point in data and this might result in an unevenly spaced
%                     time array). Overwrite 'ntimesout'. {def: automatic}
%       'powerlat'  = [float] latency in ms at which to compute phase
%                     histogram
%       'tlimits'   = [min max] time limits in ms.
%
%    Optional Detrending:
%       'detrend'   = ['on'|'off'], Linearly detrend each data epoch   {'off'}
%       'rmerp'     = ['on'|'off'], Remove epoch mean from data epochs {'off'}
%
%    Optional FFT/DFT Parameters:
%       'winsize'   = If cycles==0: data subwindow length (fastest, 2^n<frames);
%                     If cycles >0: *longest* window length to use. This
%                     determines the lowest output frequency. Note that this
%                     parameter is overwritten if the minimum frequency has been set
%                     manually and requires a longer time window {~frames/8}
%       'padratio'  = FFT-length/winframes (2^k)                    {2}
%                     Multiplies the number of output frequencies by dividing
%                     their spacing (standard FFT padding). When cycles~=0,
%                     frequency spacing is divided by padratio.
%       'nfreqs'    = number of output frequencies. For FFT, closest computed
%                     frequency will be returned. Overwrite 'padratio' effects
%                     for wavelets. Default: use 'padratio'.
%       'freqscale' = ['log'|'linear'] frequency scale. Default is 'linear'.
%                     Note that for obtaining 'log' spaced freqs using FFT,
%                     closest correspondent frequencies in the 'linear' space
%                     are returned.
%       'subitc'    = ['on'|'off'] subtract stimulus locked Inter-Trial Coherence
%                    (ITC) from x and y. This computes the  'intrinsic' coherence
%                     x and y not arising from common synchronization to
%                     experimental events. See notes. {default: 'off'}
%       'itctype'   = ['coher'|'phasecoher'] For use with 'subitc', see TIMEF
%                     for more details {default: 'phasecoher'}.
%       'subwin'    = [min max] sub time window in ms (this windowing is
%                     performed after the spectral decomposition).
%
% Outputs:
%        pac         = Matrix (nfreqs1,nfreqs2,timesout) of coherence (complex).
%                      Use 20*log(abs(crossfcoh)) to visualize log spectral diffs.
%        timesout    = Vector of output times (window centers) (ms).
%        freqsout1   = Vector of frequency bin centers for first argument (Hz).
%        freqsout2   = Vector of frequency bin centers for second argument (Hz).
%        alltfX      = single trial spectral decomposition of X
%        alltfY      = single trial spectral decomposition of Y
%
% Author: Arnaud Delorme, SCCN/INC, UCSD 2005-
%
% Ref: Testing for Nested Oscilations (2008) J Neuro Methods 174(1):50-61
%
% See also: TIMEFREQ, CROSSF

% Copyright (C) 2002 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function [crossfcoh, timesout1, freqs1, freqs2, crossfcohall, alltfX, alltfY] = pac(X, Y, srate, varargin);

if nargin < 1
    help pac;
    return;
end

% deal with 3-D inputs
% --------------------
if ndims(X) == 3, X = reshape(X, size(X,2), size(X,3)); end
if ndims(Y) == 3, Y = reshape(Y, size(Y,2), size(Y,3)); end
frame = size(X,2);

g = finputcheck(varargin, ...
                { 'alpha'         'real'     [0 0.2]                  [];
                  'baseboot'      'float'    []                       0;
                  'boottype'      'string'   {'times','trials','timestrials'}  'timestrials';
                  'detrend'       'string'   {'on','off'}              'off';
                  'freqs'         'real'     [0 Inf]                  [0 srate/2];
                  'freqs2'        'real'     [0 Inf]                  [];
                  'freqscale'     'string'   { 'linear','log' }       'linear';
                  'itctype'       'string'   {'phasecoher','phasecoher2','coher'}  'phasecoher';
                  'nfreqs'        'integer'  [0 Inf]                  [];
                  'lowmem'        'string'   {'on','off'}              'off';
                  'method'        'string'   { 'mod','corrsin','corrcos','latphase' }         'mod';
                  'naccu'         'integer'  [1 Inf]                   250;
                  'newfig'        'string'   {'on','off'}              'on';
                  'padratio'      'integer'  [1 Inf]                   2;
                  'rmerp'         'string'   {'on','off'}              'off';
                  'rboot'         'real'     []                        [];
                  'subitc'        'string'   {'on','off'}              'off';
                  'subwin'        'real'     []                        []; ...
                  'gammapowerlim' 'real'     []                        []; ...
                  'powerlim'      'real'     []                        []; ...
                  'powerlat'      'real'     []                        []; ...
                  'gammabase'     'real'     []                        []; ...
                  'timesout'      'real'     []                        []; ...
                  'ntimesout'     'integer'  []                        200; ...
                  'tlimits'       'real'     []                        [0 frame/srate];
                  'title'         'string'   []                        '';
                  'vert'          { 'real','cell' }  []                [];
                  'wavelet'       'real'     [0 Inf]                   0;
                  'wavelet2'      'real'     [0 Inf]                   [];
                  'winsize'       'integer'  [0 Inf]                   max(pow2(nextpow2(frame)-3),4) }, 'pac');

if ischar(g), error(g); end

% more defaults
% -------------
if isempty(g.wavelet2), g.wavelet2 = g.wavelet; end
if isempty(g.freqs2),   g.freqs2   = g.freqs;   end

% remove ERP if necessary
% -----------------------
X = squeeze(X);
Y = squeeze(Y);X = squeeze(X);
trials = size(X,2);
if strcmpi(g.rmerp, 'on')
    X = X - repmat(mean(X,2), [1 trials]);
    Y = Y - repmat(mean(Y,2), [1 trials]);
end

% perform timefreq decomposition
% ------------------------------
[alltfX freqs1 timesout1] = timefreq(X, srate, 'ntimesout',  g.ntimesout, 'timesout',  g.timesout,  'winsize',  g.winsize, ...
                                'tlimits', g.tlimits, 'detrend',   g.detrend,   'itctype',  g.itctype, ...
                                'subitc',  g.subitc,  'wavelet',   g.wavelet,   'padratio', g.padratio, ...
                                'freqs',   g.freqs,   'freqscale', g.freqscale, 'nfreqs',   g.nfreqs);
[alltfY freqs2 timesout2] = timefreq(Y, srate, 'ntimesout',  g.ntimesout, 'timesout',  g.timesout,  'winsize',  g.winsize, ...
                                'tlimits', g.tlimits, 'detrend',   g.detrend,   'itctype',  g.itctype, ...
                                'subitc',  g.subitc,  'wavelet',   g.wavelet2,  'padratio', g.padratio, ...
                                'freqs',   g.freqs2,  'freqscale', g.freqscale, 'nfreqs',   g.nfreqs);

% check time limits
% -----------------
if ~isempty(g.subwin)
    ind1      = find(timesout1 > g.subwin(1) & timesout1 < g.subwin(2));
    ind2      = find(timesout2 > g.subwin(1) & timesout2 < g.subwin(2));
    alltfX    = alltfX(:, ind1, :);
    alltfY    = alltfY(:, ind2, :);
    timesout1 = timesout1(ind1);
    timesout2 = timesout2(ind2);
end
if length(timesout1) ~= length(timesout2) || any( timesout1 ~= timesout2)
    disp('Warning: Time points are different for X and Y. Use ''timesout'' to specify common time points');
    [vals ind1 ind2 ] = intersect_bc(timesout1, timesout2);
    fprintf('Searching for common time points: %d found\n', length(vals));
    if length(vals) < 10, error('Less than 10 common data points'); end
    timesout1 = vals;
    timesout2 = vals;
    alltfX = alltfX(:, ind1, :);
    alltfY = alltfY(:, ind2, :);
end

% scan across frequency and time
% -------------------------------
%if isempty(g.alpha)
%    disp('Warning: if significance mask is not applied, result might be slightly')
%    disp('different (since angle is not made uniform and amplitude interpolated)')
%end

cohboot =[];
if ~strcmpi(g.method, 'latphase')
    for find1 = 1:length(freqs1)
        for find2 = 1:length(freqs2)
            for ti = 1:length(timesout1)

                % get data
                % --------
                tmpalltfx = squeeze(alltfX(find1,ti,:));
                tmpalltfy = squeeze(alltfY(find2,ti,:));

                %if ~isempty(g.alpha)
                %    tmpalltfy = angle(tmpalltfy);
                %    tmpalltfx = abs(  tmpalltfx);
                %    [ tmp cohboot(find1,find2,ti,:) newamp newangle ] = ...
                %        bootcircle(tmpalltfx, tmpalltfy, 'naccu', g.naccu);
                %    crossfcoh(find1,find2,ti) = sum ( newamp .* exp(j*newangle) );
                %else
                tmpalltfy = angle(tmpalltfy);
                tmpalltfx = abs(  tmpalltfx);
                if strcmpi(g.method, 'mod')
                    crossfcoh(find1,find2,ti) = sum( tmpalltfx .* exp(j*tmpalltfy) );
                elseif strcmpi(g.method, 'corrsin')
                    tmp = corrcoef( sin(tmpalltfy), tmpalltfx);
                    crossfcoh(find1,find2,ti) = tmp(2);
                else
                    tmp = corrcoef( cos(tmpalltfy), tmpalltfx);
                    crossfcoh(find1,find2,ti) = tmp(2);
                end
            end
        end
    end
elseif 1
    % this option computes power at a given latency
    % then computes the same as above (vectors)

    %if isempty(g.powerlat)
    %    error('You need to specify a latency for the ''powerlat'' option');
    %end

    gammapower = mean(10*log10(alltfX(:,:,:).*conj(alltfX)),1); % average all frequencies for power
    if isempty(g.gammapowerlim)
        g.gammapowerlim = [ min(gammapower(:)) max(gammapower(:)) ];
    end
    fprintf('Gamma power limits: %3.2f to %3.2f\n', g.gammapowerlim(1), g.gammapowerlim(2));
    power = 10*log10(alltfY(:,:,:).*conj(alltfY));
    if isempty(g.powerlim)
        for freq = 1:size(power,1)
            g.powerlim(freq,:) = [ min(power(freq,:)) max(power(freq,:)) ];
        end
    end
    for freq = 1:size(power,1)
        fprintf('Freq %d power limits: %3.2f to %3.2f\n', freqs2(freq), g.powerlim(freq,1), g.powerlim(freq,2));
    end

    % power plot
    %figure; plot(timesout2/1000, (mean(power(9,:,:),3)-mean(power(9,:)))/50);
    %hold on; plot(linspace(0, length(Y)/srate, length(Y)), mean(Y'), 'g');

    % phase with power
    % figure; plot(timesout2/1000, (mean(phaseangle(9,:,:),3)-mean(phaseangle(9,:)))/50);
    % hold on; plot(timesout1/1000, (mean(gammapower,3)-mean(gammapower(:)))/100, 'r');
    %figure; plot((mean(phaseangle(9,:,:),3)-mean(phaseangle(9,:)))/50+j*(mean(gammapower,3)-mean(gammapower(:)))/100, '.');

    matsize               = 32;
    matcenter             = (matsize-1)/2+1;
    matrixfinalgammapower = zeros(size(alltfY,1),size(alltfX,3),matsize,matsize);
    matrixfinalcount      = zeros(size(alltfY,1),size(alltfX,3),matsize,matsize);

    % get power indices
    if isempty(g.gammabase)
        g.gammabase = mean(gammapower(:));
    end
    fprintf('Gamma power average: %3.2f\n', g.gammabase);
    gammapoweradd  = gammapower-g.gammabase;
    gammapower     = floor((gammapower-g.gammapowerlim(1))/(g.gammapowerlim(2)-g.gammapowerlim(1))*(matsize-2))+1;
    phaseangle     = angle(alltfY);
    posx           = zeros(size(power));
    posy           = zeros(size(power));
    for freq = 1:length(freqs2)
        fprintf('Processing frequency %3.2f\n', freqs2(freq));
        power(freq,:,:) = (power(freq,:,:)-g.powerlim(freq,1))/(g.powerlim(freq,2)-g.powerlim(freq,1))*(matsize-3)/2+1;
        complexval      = power(freq,:,:).*exp(j*phaseangle(freq,:,:));
        posx(freq,:,:)  = round(real(complexval)+matcenter);
        posy(freq,:,:)  = round(imag(complexval)+matcenter);
        for trial = 1:size(alltfX,3) % scan trials
            for time = 1:size(alltfX,2)
                %matrixfinal(freq,posx(freq,time,trial),posy(freq,time,trial),gammapower(1,time,trial)) = ...
                %    matrixfinal(freq,posx(freq,time,trial),posy(freq,time,trial),gammapower(1,time,trial))+1;
                matrixfinalgammapower(freq,trial,posx(freq,time,trial),posy(freq,time,trial)) = ...
                    matrixfinalgammapower(freq,trial,posx(freq,time,trial),posy(freq,time,trial))+gammapoweradd(1,time,trial);
                matrixfinalcount(freq,trial,posx(freq,time,trial),posy(freq,time,trial)) = ...
                    matrixfinalcount(freq,trial,posx(freq,time,trial),posy(freq,time,trial))+1;
            end
        end
        %matrixfinal(freq,:,:,:) = convn(squeeze(matrixfinal(freq,:,:,:)), gs, 'same');
        %tmpmat = posx(index,:)+(posy(index,:)-1)*64+(gammapower(:)-1)*64*64;
        matrixfinalcount(freq, find(matrixfinalcount(freq,:) == 0)) = 1;
        matrixfinalgammapower(freq,:,:,:) = matrixfinalgammapower(freq,:,:,:)./matrixfinalcount(freq,:,:,:);
    end

    % average and smooth
    matrixfinalgammapowermean = squeeze(mean(matrixfinalgammapower,2));
    for freq = 1:length(freqs2)
        matrixfinalgammapowermean(freq,:,:) = conv2(squeeze(matrixfinalgammapowermean(freq,:,:)), gauss2d(5,5), 'same');
    end
    %matrixfinalgammapower = matrixfinalgammapower/size(alltfX,3)/size(alltfX,2);

    %vect = linspace(-pi,pi,50);
    %for f = 1:length(freqs2)
    %    crossfcoh(f,:) = hist(tmpalltfy(f,:), vect);
    %end

    % smoothing of output image
    % -------------------------
    %gs = gauss2d(6, 6, 6);
    %crossfcoh = convn(crossfcoh, gs, 'same');
    %freqs1    = freqs2;
    %timesout1 = linspace(-180, 180, size(crossfcoh,2));

    crossfcoh    = matrixfinalgammapowermean;
    crossfcohall = matrixfinalgammapower;

else
    % this option computes power at a given latency
    % then computes the same as above (vectors)

    %if isempty(g.powerlat)
    %    error('You need to specify a latency for the ''powerlat'' option');
    %end

    gammapower = mean(10*log10(alltfX(:,:,:).*conj(alltfX)),1); % average all frequencies for power
    if isempty(g.gammapowerlim)
        g.gammapowerlim = [ min(gammapower(:)) max(gammapower(:)) ];
    end
    power = 10*log10(alltfY(:,:,:).*conj(alltfY));
    if isempty(g.powerlim)
        for freq = 1:size(power,1)
            g.powerlim(freq,:) = [ min(power(freq,:)) max(power(freq,:)) ];
        end
    end

    % power plot
    %figure; plot(timesout2/1000, (mean(power(9,:,:),3)-mean(power(9,:)))/50);
    %hold on; plot(linspace(0, length(Y)/srate, length(Y)), mean(Y'), 'g');

    % phase with power
    % figure; plot(timesout2/1000, (mean(phaseangle(9,:,:),3)-mean(phaseangle(9,:)))/50);
    % hold on; plot(timesout1/1000, (mean(gammapower,3)-mean(gammapower(:)))/100, 'r');
    %figure; plot((mean(phaseangle(9,:,:),3)-mean(phaseangle(9,:)))/50+j*(mean(gammapower,3)-mean(gammapower(:)))/100, '.');

    matsize               = 64;
    matcenter             = (matsize-1)/2+1;
    matrixfinal           = zeros(size(alltfY,1),64,64,64);
    matrixfinalgammapower = zeros(size(alltfY,1),matsize,matsize);
    matrixfinalcount      = zeros(size(alltfY,1),matsize,matsize);

    % get power indices
    gammapoweradd  = gammapower-mean(gammapower(:));
    gammapower     = floor((gammapower-g.gammapowerlim(1))/(g.gammapowerlim(2)-g.gammapowerlim(1))*(matsize-1))+1;
    phaseangle     = angle(alltfY);
    posx           = zeros(size(power));
    posy           = zeros(size(power));
    gs             = gauss3d(6, 6, 6);
    for freq = 1:size(alltfY)
        fprintf('Processing frequency %3.2f\n', freqs2(freq));
        power(freq,:,:) = (power(freq,:,:)-g.powerlim(freq,1))/(g.powerlim(freq,2)-g.powerlim(freq,1))*(matsize-2)/2;
        complexval      = power(freq,:,:).*exp(j*phaseangle(freq,:,:));
        posx(freq,:,:)  = round(real(complexval)+matcenter);
        posy(freq,:,:)  = round(imag(complexval)+matcenter);
        for trial = 1:size(alltfX,3) % scan trials
            for time = 1:size(alltfX,2)
                %matrixfinal(freq,posx(freq,time,trial),posy(freq,time,trial),gammapower(1,time,trial)) = ...
                %    matrixfinal(freq,posx(freq,time,trial),posy(freq,time,trial),gammapower(1,time,trial))+1;
                matrixfinalgammapower(freq,posx(freq,time,trial),posy(freq,time,trial)) = ...
                    matrixfinalgammapower(freq,posx(freq,time,trial),posy(freq,time,trial))+gammapoweradd(1,time,trial);
                matrixfinalcount(freq,posx(freq,time,trial),posy(freq,time,trial)) = ...
                    matrixfinalcount(freq,posx(freq,time,trial),posy(freq,time,trial))+1;
            end
        end
        %matrixfinal(freq,:,:,:) = convn(squeeze(matrixfinal(freq,:,:,:)), gs, 'same');
        %tmpmat = posx(index,:)+(posy(index,:)-1)*64+(gammapower(:)-1)*64*64;
        matrixfinalcount(freq, find(matrixfinalcount(freq,:) == 0)) = 1;
        matrixfinalgammapower(freq,:,:) = matrixfinalgammapower(freq,:,:)./matrixfinalcount(freq, :,:);
        matrixfinalgammapower(freq,:,:) = conv2(squeeze(matrixfinalgammapower(freq,:,:)), gauss2d(5,5), 'same');
    end
    %matrixfinalgammapower = matrixfinalgammapower/size(alltfX,3)/size(alltfX,2);

    %vect = linspace(-pi,pi,50);
    %for f = 1:length(freqs2)
    %    crossfcoh(f,:) = hist(tmpalltfy(f,:), vect);
    %end

    % smoothing of output image
    % -------------------------
    %gs = gauss2d(6, 6, 6);
    %crossfcoh = convn(crossfcoh, gs, 'same');
    %freqs1    = freqs2;
    %timesout1 = linspace(-180, 180, size(crossfcoh,2));

    crossfcoh = matrixfinalgammapower;

end

% 7/31/2014 Ramon: crossfcohall sometimes does not exist depending on choice of input options
if ~exist('crossfcohall', 'var')
    crossfcohall = [];
end


% LAPPLOT -  Compute the discrete laplacian of EEG scalp distribution(s)
%
% Usage:
%   >> laplace = lapplot(map,eloc_file,draw)
%
% Inputs:
%    map        - Activity levels, size (nelectrodes,nmaps)
%    eloc_file	- Electrode location filename (.loc file)
%                 For format, see  >> topoplot example
%    draw       - If defined, draw the map(s) {default: no}
%
% Output:
%    laplace    - Laplacian map, size (nelectrodes,nmaps)
%
% Note: uses DEL2
%
% Author: Scott Makeig, SCCN/INC/UCSD, La Jolla, 1998
%
% See also: TOPOPLOT, GRADPLOT

% Copyright (C) Scott Makeig, SCCN/INC/UCSD, La Jolla, 1998
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

% 01-25-02 reformated help & license, added links -ad

function [laplac] = lapplot(map,filename,draw)

if nargin < 2
	help lapplot;
	return;
end

MAXCHANS = size(map,1);
GRID_SCALE = 2*MAXCHANS+5;
MAX_RADIUS = 0.5;

% ---------------------
% Read the channel file
% ---------------------
if ischar( filename )
	fid = fopen(filename);
	locations = fscanf(fid,'%d %f %f %s',[7 MAXCHANS]);
	fclose(fid);
	locations = locations';
	Th = pi/180*locations(:,2);   % convert degrees to rads
	Rd = locations(:,3);
	ii = find(Rd <= MAX_RADIUS); % interpolate on-scalp channels only
	Th = Th(ii);
	Rd = Rd(ii);
	[x,y] = pol2cart(Th,Rd);
else
	x = real(filename);
	y = imag(filename);
end;

% ---------------------------------------------------
% Locate nearest position of an electrode in the grid
% ---------------------------------------------------
xi = linspace(-0.5,0.5,GRID_SCALE);   % x-axis description (row vector)
yi = linspace(-0.5,0.5,GRID_SCALE);   % y-axis description (row vector)
for i=1:MAXCHANS
   [useless_var horizidx(i)] = min(abs(y(i) - xi));    % find pointers to electrode
   [useless_var vertidx(i)] = min(abs(x(i) - yi));     % positions in Zi
end

% -----------------
% Compute laplacian
% -----------------
for i=1:size(map,2)
   	[Xi,Yi,Zi] = griddata(y,x,map(:,i),yi',xi, 'v4');   % interpolate data

   	laplac2D = del2(Zi);
	positions = horizidx + (vertidx-1)*GRID_SCALE;
	laplac(:,i) = laplac2D(positions(:));

	% ------------------
	% Draw laplacian map
	% ------------------
	if exist('draw');
        mask = (sqrt(Xi.^2+Yi.^2) <= MAX_RADIUS);
        laplac2D(find(mask==0)) = NaN;

		subplot(ceil(sqrt(size(map,2))), ceil(sqrt(size(map,2))), i);
		contour(laplac2D);
		title( int2str(i) );

% %%% Draw Head %%%%
ax = axis;
width = ax(2)-ax(1);
axis([ax(1)-width/3 ax(2)+width/3 ax(3)-width/3 ax(4)+width/3])
steps = 0:2*pi/100:2*pi;
basex = .18*MAX_RADIUS;
tip = MAX_RADIUS*1.15;
base = MAX_RADIUS-.004;
EarX = [.497 .510 .518 .5299 .5419 .54 .547 .532 .510 .489];
EarY = [.0555 .0775 .0783 .0746 .0555 -.0055 -.0932 -.1313 -.1384 -.1199];

HCOLOR = 'k';
HLINEWIDTH = 1.8;

% Plot Head, Ears, Nose
hold on
plot(1+width/2+cos(steps).*MAX_RADIUS*width,...
     1+width/2+sin(steps).*MAX_RADIUS*width,...
    'color',HCOLOR,'Linestyle','-','LineWidth',HLINEWIDTH); % head

plot(1+width/2+[.18*MAX_RADIUS*width;0;-.18*MAX_RADIUS*width],...
     1+width/2+[base;tip;base]*width,...
    'Color',HCOLOR,'LineWidth',HLINEWIDTH);                 % nose

plot(1+width/2+EarX*width,...
     1+width/2+EarY*width,...
           'color',HCOLOR,'LineWidth',HLINEWIDTH)           % l ear
plot(1+width/2-EarX*width,...
     1+width/2+EarY*width,...
           'color',HCOLOR,'LineWidth',HLINEWIDTH)           % r ear

hold off
axis off

	end
end;

return;


function SO3F = norm(SO3VF)
% pointwise norm of the vector field
%
% Syntax
%   SO3F = norm(SO3VF)
%
% Input
%  SO3VF - @SO3VectorField
%
% Output
%  SO3F - @SO3FunHarmonic
%

SO3F = SO3FunHarmonic.quadrature(@(rot) norm(SO3VF.eval(rot)),SO3VF.CS,SO3VF.SS);

end


% GP_LEARN_PSEUDO - Learns the hyperparameters of a Gaussian process
%                   using pseudo inputs.
%
% Usage:
%
%   [THETA_F, THETA_NOISE, LOGLIKELIHOOD] = ...
%     GP_LEARN_PSEUDO(Y, COVFUNC_PSEUDO, THETA0_F, COVFUNC_NOISE, THETA0_NOISE)
%
% Y              : Nx1 vector of observations
% COVFUNC_PSEUDO : A special covariance function, see GP_COV_PSEUDO
% THETA0_F       : Initial parameter values for COVFUNC_PSEUDO
% COVFUNC_NOISE  : A diagonal noise covariance function
% THETA0_NOISE   : Initial parameter values for COVFUNC_NOISE
%
% THETA_F       : Optimized parameter values for COVFUNC_PSEUDO
% THETA_NOISE   : Optimized parameter values for COVFUNC_NOISE
% LOGLIKELIHOOD : The loglikelihood lower bound at the optimum
%
% Optional parameters can be given as
%
%   [...] = GP_LEARN_PSEUDO(..., 'PARAMETER', VALUE)
%
% where the possible parameters are
%
% 'MAXITER' : Maximum number of iterations (default: 100)
% 'CHECKGRAD' : Numerical check of the gradients (default: false)
%
% See also GP_PREDICT_PSEUDO, GP_LEARN, GP_COV_PSEUDO,
% GP_LOGLIKELIHOOD_PSEUDO.

% Last modified 2010-01-27
% Copyright (c) Jaakko Luttinen (jaakko.luttinen@tkk.fi)

function [theta_f, theta_noise, loglikelihood] = gp_learn_pseudo(y, ...
                                                  covfunc_pseudo, ...
                                                  theta_f, ...
                                                  covfunc_noise, ...
                                                  theta_noise, ...
                                                  varargin)

options = struct('maxiter', 100, ...
                 'checkgrad', false);
[options, errmsg] = argparse(options, varargin{:});
error(errmsg);

n_theta_f = numel(theta_f);
theta = [theta_f(:); theta_noise(:)];

if options.checkgrad
  mycheckgrad(@cost, log(theta), 1e-6);
end

[logtheta, logpdfs] = minimize(log(theta), @cost, options.maxiter);
loglikelihood = -min(logpdfs);
theta = exp(logtheta);

  function [c, dc] = cost(logtheta)
  theta = exp(logtheta);
  theta_f = theta(1:n_theta_f);
  theta_noise = theta((n_theta_f+1):end);
  [c, dc_f, dc_noise] = gp_loglikelihood_pseudo(y, covfunc_pseudo, theta_f, ...
                                                covfunc_noise, theta_noise);
  c = -c;
  dc = -[dc_f; dc_noise] .* theta;
  end

end


function L=sqrtpsdinv(X)

   [u,d]=schur(X);
   d=diag(d);
   d(d<=0)=inf;
   L=u*diag(1./sqrt(d))*u';
end


function xf_detect = spike_detection_filter(x, par)
%this function filter the signal, using the detection filter. Is used in the
%readInData class.

sr = par.sr;
fmin_detect = par.detect_fmin;
fmax_detect = par.detect_fmax;

% HIGH-PASS FILTER OF THE DATA
if par.detect_order>0
    if exist('ellip','file')                         %Checks for the signal processing toolbox
        [b,a] = ellip(par.detect_order,0.1,40,[fmin_detect fmax_detect]*2/sr);
        if exist('FiltFiltM','file')
            xf_detect = FiltFiltM(b, a, x);
        else
            xf_detect = filtfilt(b, a, x);
        end
    else
        xf_detect = fix_filter(x);                   %Does a bandpass filtering between [300 3000] without the toolbox.
    end
else
    xf_detect = x;
end


%P = vgg_P_from_F(F)  Compute cameras from fundamental matrix.
%   F has size (3,3), P has size (3,4).
%
%   If x2'*F*x1 = 0 for any pair of image points x1 and x2,
%   then the camera matrices of the image pair are
%   P1 = eye(3,4) and P2 = vgg_P_from_F(F), up to a scene homography.

% Tomas Werner, Oct 2001

function P = vgg_P_from_F(F)

[U,S,V] = svd(F);
e = U(:,3);
P = [-vgg_contreps(e)*F e];

return


% evaluate simulated data - ICA and NMF
function separ(sep0, offset0, path_data, path_res, prename, niter, savethis, hint, sep_how)
% sep_how: string i - ica, n - nmf -> method for separation
if ~exist('hint', 'var')
    hint = 0;
end

if ~exist('sep_how', 'var')
    sep_how = 'in';
end

fprintf('Separation of components... \n')
for rr = 1: length(offset0)
    fprintf('\n%g: ',rr)
    for ll=1 : length(sep0)
        fprintf('.')
        p.namedir = [prename num2str(100*sep0(ll)) 'offset_' num2str(offset0(rr))];
        cd ([path_data p.namedir])
        for mm=1:niter

            namefile = [p.namedir '-iter_' num2str(mm)];
            load ([namefile '.mat'])
            %         ims(psf);
            %         SaveImageFULL('psf', 'pf');

            if sum(sep_how == 'i')>0 %ICA
                [icasig{mm}, A{mm}, W{mm}] = fastica (dveccr, 'numOfIC', 2, 'g', 'tanh');
                icapixICA{mm} = reshape(A{mm},32, 32, 2);
            end
            if sum(sep_how == 'n')>0 %NMF
                ncomp = 2; %number of components to be separated
                if hint
                    dvec_ind = double(squeeze(reshape(array2im(dpixc_ind), p.nx*p.ny, 1, 2))); % vectors of resized images
                    %                     [out, bg(mm), bg_im]=backgroundoffset(dpixc);
                    [out, bg(mm), bg_im]=backgroundoffset(dpixc, 'no', 5, 20, 8); %empirical values...
                    dvec_bg = bg(mm)*ones(1, p.nx*p.ny);
                    %                     dvec_bg = p.offset*ones(1, p.nx*p.ny); %changed for offset 10...

                    % % %                     blinkmatrand = rand(p.Nt, ncomp);
                    blinkmatrand = blinkmat';
                    winit = [blinkmatrand,ones(p.Nt,1)];             %random weights will be assigned to firts two and bg fixed

                    hinit = [dvec_ind; dvec_bg];       %original 'true' points + background
% % %                     hinit = [rand(ncomp, p.nx*p.ny); dvec_bg];
                    ncomp = ncomp+1; %background added
                    [w{mm},h{mm}]=nmf(double(dveccr'),ncomp+1,1,winit,hinit, [3], [1 2 3]);

                else
                    [w{mm},h{mm}]=nmf(double(dveccr'),ncomp,1);
                end
                icapixNMF{mm} = shiftdim(reshape(h{mm},ncomp,32,32), 1);
            end
            %             imstiled(icapixICA{mm});
            %             SaveImageFULL([p.namedir 'ICA_' num2str(mm)], 'p');
            %             imstiled(icapixNMF{mm});
            %             SaveImageFULL([p.namedir 'NMF_' num2str(mm)], 'p');
            close all

        end

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

        if savethis == 1
            fprintf('saving data \n');
            if ~(strcmp('p.path', 'p.path_data')) %not identical
                mkdir ([p.path p.namedir]);
                cd ([p.path p.namedir]);
            end
            save ([p.namedir '_separ'])
            writedata([],[],p,[p.namedir '_param'])
        end
    end
end

fprintf('\n')


function [dtdx,dtrp,vart]=trop_model_prec(time,pos,azel,x)

zhd=tropmodel(pi/2,pos,0); %zenith hydrostatic delay

[mh,mw]=tropmapf(time,pos,azel); %hydrostatic and wet projection coefficient

if azel(2)>0
    %equation: m_w=m_0+m_0*cot(el)*(Gn*cos(az)+Ge*sin(az))
    cotz=1.0/tan(azel(2));
    grad_n=mw*cotz*cos(azel(1)); %north wet projection coefficient
    grad_e=mw*cotz*sin(azel(1)); %east wet projection coefficient
    mw=mw+grad_n*x(2)+grad_e*x(3); %total wet projection coefficient
    dtdx(2)=grad_n*(x(1)-zhd); %north wet delay
    dtdx(3)=grad_e*(x(1)-zhd); %east wet delay
end

dtdx(1)=mw;
dtrp=mh*zhd+mw*(x(1)-zhd);
vart=0.01^2;

return;


%imu model parameter should be defined in cont. time
function [STM Qd]=mdl_ned_dcm(pos_n, vel_n, Cbn, acc, Aimu, Qimu, Cimu, Rimu, dt)

%continious model
[Anav N]=sys_ned_dcm_v000(pos_n, vel_n, Cbn, acc, 0, []);
nst_imu=size(Aimu,1);
nst=9+nst_imu;
Ac=[Anav N*Cimu;zeros(nst_imu,9) Aimu];
Qc=[N*Rimu*N' zeros(9,nst_imu);zeros(nst_imu,9) Qimu];

%Discretize the model
mx_a = dt*[-Ac,Qc;zeros(nst),Ac'];
mx_b = expm(mx_a);
STM = mx_b(nst+1:2*nst,nst+1:2*nst)';
Qd = STM*mx_b(1:nst,nst+1:2*nst);


function [yc] = checkCosts(obj, x, output_file,permission)
    % Check the value of const function

    if nargin > 2
        % print to the file
        if nargin < 4
            permission = 'w';
        else
            validatestring(permission, {'a','w'});
        end
        f_id = fopen(output_file, permission);
    else
        % print on the screen
        f_id = 1;
    end

    fprintf(f_id, '**************************************************\n');
    fprintf(f_id, 'Checking cost value of %s:\n', obj.Name);

    cost_table = obj.CostTable;
    [n_node, n_cost] = size(cost_table);
    yc = zeros(1,n_cost);
    fprintf(f_id, '**************************************************\n');
    fprintf(f_id,'%12s \t %12s\n','Cost','Value');

    for j=1:n_cost
        cost_name = obj.CostTable.Properties.VariableNames{j};
        cost_array = obj.CostTable.(cost_name);
        fprintf(f_id, 'Cost: %s \n', cost_name);
        for k=1:n_node
            cost = cost_array(k);
            if cost.Dimension ~=0
                dep_constr = getSummands(cost);
                for ll = 1:numel(dep_constr)
                    dep_var = dep_constr(ll).DepVariables;
                    var = arrayfun(@(v)x(v.Indices(:)),dep_var,'UniformOutput',false); % dependent variables
                    if isempty(dep_constr(ll).AuxData)
                        yc(j) = yc(j) + feval(dep_constr(ll).Funcs.Func, var{:});
                    else
                        yc(j) = yc(j) + feval(dep_constr(ll).Funcs.Func, var{:}, dep_constr(ll).AuxData{:});
                    end

                end
            end
        end
        fprintf(f_id,'%12s \t %12.8E\n',cost_name,yc(j));
    end
    fprintf(f_id, '**************************************************\n');

    if f_id ~= 1
        fclose(f_id);
    end
end


 function mac = xray_atten_interp(kev, mac, kev_in, varargin)
%function mac = xray_atten_interp(kev, mac, kev_in, [options])
%|
%| Interpolate mass attenuation coefficients (mac) onto desired energies.
%|
%| in
%|	kev	[M,1]
%|	mac	[M,1]
%|	kev_in	[N,1]		desired energies [in keV]
%|
%| option
%|	'interp' {}		default {'pchip', 'extrap'}
%| out
%|	mac	[N,1]		mass attenuation coefficients [cm^2/g],
%|
%| Copyright 2004-05-1, Jeff Fessler, University of Michigan

% default is to show example
if nargin < 1, ir_usage, end
if nargin == 1 && streq(kev, 'test'), xray_atten_interp_test, return, end

% = {'linear', 'extrap'};
% = {'spline', 'extrap'};
arg.interp = {'pchip', 'extrap'};
arg = vararg_pair(arg, varargin);

% trick: allow for the k-edge jumps!
mac = log(mac); % interpolate on a log scale
mac = interp1_jump(kev, mac, kev_in, arg.interp{:});
mac = exp(mac);

% xray_atten_interp_test()
% example usage, cf Fig. 3.4 of Macovski 1983
function xray_atten_interp_test
mtype = 'water'; ax = 10.^[1 3 -2 1.];
mtype = 'lead'; ax = 10.^[1 3 -1 2.5];
[mac kev] = xray_read_atten(mtype);
kev1 = logspace(1,3,1+2^9);
mac1 = xray_atten_interp(kev, mac, kev1);
if im
	clf, loglog(kev, mac, '.', kev1, mac1, '-')
	xlabel 'KeV', ylabel 'mass attenuation coefficient [cm^2/g]'
	axis(ax)
	texts(0.7, 0.7, mtype)
	if streq(mtype, 'lead')
		text(14, 40, 'L edge', 'horizontalalignment', 'center')
		text(88, 1., 'K edge', 'horizontalalignment', 'center')
	end
end
% ir_savefig(['fig_atten_' mtype])


% Use is m.file to test the frequency calculater function for that you will
% need the Angle.mat file which contain a real measured signal with
% freuqncy changing between 50 Hz to 55% in three differnt ways:
% 1- A jump (step change) of the frequency
% 2- ramp change of the freuqnecy with 10 Hz/s
% 3- ramp change of the frequency with 20 Hz/s
% for using this file you will need the: "Frequency_Calculation_Function"
% Author: Aubai Al Khatib datum: 19.09.2013
clear
clc
if 1 == 0
    Sample = 10000;%Hz
    f_test = 50;%Hz
    t = 0:1/Sample:1;
    y = sin(2*pi*f_test*t);
    [f,f_time] = Frequency_Calculation_Function(y,t);
    figure(1);
    subplot(1,1,2);
    plot(f_time,f);ylim([49,56]);grid on;xlim([80,120]);xlabel('Time in S');ylabel('Frequency in Hz');
    subplot(1,2,2);
    plot(t,y);grid on;xlabel('Time in S');ylabel('Amplitude in V');
else
    load('Angle.mat')
    [f,f_time] = Frequency_Calculation_Function(U1,U1_time);
    figure(1);
    subplot(2,1,1);
    plot(f_time,f);ylim([49,56]);grid on;xlim([80,120]);xlabel('Time in S');ylabel('Frequency in Hz');
    subplot(2,1,2);
    plot(U1_time,U1);grid on;xlim([80,120]);xlabel('Time in S');ylabel('Amplitude in V');
    figure(2);
    subplot(2,1,1);
    plot(f_time,f);ylim([49,56]);grid on;xlim([104.5,108.5]);xlabel('Time in S');ylabel('Frequency in Hz');
    subplot(2,1,2);
    plot(U1_time,U1);grid on;xlim([104.5,108.5]);xlabel('Time in S');ylabel('Amplitude in V');
end


function im = ifftc(d)
% Function performs a centered ifft
im = ifftshift(ifft(ifftshift(d)));


%convert images to double and grayscale
I1 = impyramid( imInit('car1.png'), 'reduce' );
I2 = impyramid( imInit('car2.png'), 'reduce' );

%%

[flowHor flowVer] = pyramidFlow(I1, I2, 5, 3, 3);  %pyramidFlow( I1, I2, winSize, ITER_NO, PYRE_NO )

%show the output flows
imS(flowHor,1,[-10 10])
imS(flowVer,2,[-10 10])

%%
%show the warped image to check the quality of registration
Iw = imWarp(flowHor, flowVer, I2);
imS(I1,10)
imS(Iw,11)
imS(I2,12)


function F = initBPHMMSamplerFromScratch_FeatureMatrix( data_struct, initParams,outParams)
%  Features can be initialized in a few ways
%    1) unique set for each obj
%    2) unique set for each category
%    3) shared set for all objects
%           either from IBP prior
%                    or given specific number K of features to use

nObj = length( data_struct );

if isfield( initParams.F, 'nTotal' )
    K =  initParams.F.nTotal;
    F = ones( nObj, K );

    if outParams.doPrintHeaderInfo
        fprintf( '\t F : %d global features shared by all objects \n', K );
    end

elseif isfield( initParams.F, 'nUniquePerObj' )
    Kii = initParams.F.nUniquePerObj;
    F = zeros( nObj, Kii * nObj );

    for ii = 1:nObj
        F(ii, (ii-1)*Kii + [1:Kii] ) = 1;
    end
    if outParams.doPrintHeaderInfo
        fprintf( '\t F : each obj. assigned %d unique features \n', Kii );
    end

end


function [nmps2] = ftps22nmps2(ftps2)
% Convert acceleration from feet per square-second to nanometers per second
% squared.
% Chad A. Greene 2012
nmps2 = ftps2*304800000;
end


function onoff = emgonoff(rawemg, fs, ws, sd)
% EMGONOFF - Find on/off times and indicies of raw EMG data.
% Calculate average(mean) value of resting EMG
% Define "on" EMG as the sample where average value of EMG in a given window
% range around the sample is a given # of std. dev. above avg. resting EMG.
%
% onoff = emgonoff(rawemg, fs, ws, sd)
%
% Use the mouse to select two ranges of "resting" EMG from a graph of the
% full-wave rectified EMG data.  Click four times: start and end of 1st
% resting range, and start and end of 2nd resting range.  Mouse clicks need
% to be consecutive and in order of increasing time (i.e. left-to-right on
% the graph).  The first range should precede the EMG burst associated with
% the muscle contraction under consideration.  The sedond range should be
% the resting EMG data immediately following the EMG burst.
%
% rawemg = input file raw emg data (1-column vector)
% fs = sampling rate of raw EMG data in Hz
% ws = window size in milliseconds (50ms @ 2400Hz = 120 samples)
% sd = number of std. deviations above resting rms emg to trigger an "ON"
% Default values:
%   ws = 50ms
%   sd = 1

% Algorythm for EMG onset & offset taken from
% Hodges, P.W. and B.H. Bui, _A comparison of computer-based methods for
% the determination of onset of muscle contraction using electromyography._
% Electroencephalography & Clinical Neurophysiology, 1996. 101(6): p. 511-9
%
% Created by: Kieran A. Coghlan, BSME, MSES
% SUNY at Buffalo, New York
% <kc_news@sonic.net>
% Last modified: 1 May, 2006

%% Check inputs for defaults
if nargin < 2, error('Not enough inputs. Type "help emgonoff" for help.'); end
if nargin < 3, ws = 50; end
if nargin < 4, sd = 1; end;
%% Full-Wave-Rectify the raw data
fwlo = abs(rawemg(:,1));
%% prepare for loop
% Get two ranges for resting emg (before & after burst) using ginput
R = input('\nUse the mouse to select FOUR points to define the begining and \nend of two data ranges that will be used to calculate average\nresting EMG values before and after the EMG burst (muscle contraction)\nPress [RETURN] to begin: ');
clear R;
f1 = figure;
plot(fwlo);
[x y] = ginput(4); %click four times: two for start/end of resting emg before burst two for resting emg after burst
x = round(x);
clear y;
%close(f1);clear f1; % Leave commented if you want to keep EMG graph up to
%                    % do a visual QA of on/off results.
%% preallocate arrays
mvgav = zeros(x(4)-x(1),1);
onoff(1,1) = 0;
i=0;
restav = mean(fwlo(x(1):x(2))); %average value of rest EMG before ON
reststd = std(fwlo(x(1):x(2))); %std. dev. of rest EMG before ON
restav2 = mean(fwlo(x(3):x(4))); %average value of rest EMG after OFF
reststd2 = std(fwlo(x(3):x(4))); %std. dev. of rest EMG after OFF
%% window size (in samples) = ws*fs e.g. 50ms*2400Hz = 120 samples
sws2 = fs*(0.001*ws);
sws = 0.5*(sws2);
sws = round(sws);
%% find "ON" index:
% for xi, change from x(1) to x(2) if you want to ignore any "blips"
% within the resting range.
%xi = x(1);
xi = x(2);
xi = round(xi);
for n = 2:length(mvgav);
    mvgav(n,1) = mean(fwlo((xi-sws):(xi+sws)));
    if mvgav(n) > restav+sd*reststd;
        i = i+1;
        onoff(i,1) = xi;
        break
    end
    xi = xi+1;
end
%% find "OFF" index:
clear n xi i
mvgav2=zeros(x(4)-x(1),1);
i=0;
xi=onoff(1,1)+(1/2)*(x(3)-onoff(1,1)); %start OFF search approx. 1/2 way through ON burst.
%% OFF loop:
xi=round(xi);
for n=2:length(mvgav2);
    mvgav2(n,1)=mean(fwlo((xi-sws):(xi+sws)));
    if mvgav2(n)<restav2+sd*reststd2;
        i=i+1;
        onoff(i,2)=xi;
        break
    end
    xi=xi+1;
end


function PBI = CalPBI(PopObj,W,Region,Z,Sub)
% Calculate the PBI value between each solution and its associated weight
% vector

%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    Z   = repmat(Z,sum(Sub),1);
    NormW = sqrt(sum(W(Region(Sub),:).^2,2));
    d1  = abs(sum((PopObj(Sub,:)-Z).*W(Region(Sub),:),2))./NormW;
    d2  = sqrt(sum((PopObj(Sub,:)-(Z+W(Region(Sub),:).*repmat(d1./NormW,1,size(W,2)))).^2,2));
    PBI = zeros(1,size(PopObj,1));
    PBI(Sub) = d1 + 5*d2;
end


function [R,SS] = fit_rotations(S,varargin)
  % FIT_ROTATIONS Given an input mesh and new positions find rotations for
  % every vertex that best maps its one ring to the new one ring
  %
  % R = fit_rotations(S,'ParamName',ParamValue)
  %
  % Inputs:
  %   S  dim by dim by #rotations list of covariance matrices to fit rotations
  %     to
  %   Optional parameters
  %     'AllowFlips'  optionally followed by true or false, find best fitting
  %       rotation OR reflection
  %     'SinglePrecision'  use single precision if available.
  % Outputs:
  %   R  dim by dim by #F list of rotations
  %   SS  dim by dim by #rotations list of svd diagonals
  %

  dim = size(S,1);
  assert(dim == size(S,2));
  nr = size(S,3);
  allow_flips = false;
  use_mex = true;

  single_precision = true;
  % default values
  % Map of parameter names to variable names
  params_to_variables = containers.Map( {'AllowFlips','SinglePrecision','Mex'}, ...
    {'allow_flips','single_precision','use_mex'});
  v = 1;
  while v <= numel(varargin)
    param_name = varargin{v};
    if isKey(params_to_variables,param_name)
      assert(v+1<=numel(varargin));
      v = v+1;
      % Trick: use feval on anonymous function to use assignin to this workspace
      feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
    else
      error('Unsupported parameter: %s',varargin{v});
    end
    v=v+1;
  end

  % Even faster way to check if mex exists
  if use_mex && fit_rotations_mex && ~allow_flips
    nr = size(S,3);
    dim = size(S,1);
    SS = reshape(permute(S,[3 1 2]),[nr*dim dim]);
    R = fit_rotations_mex(SS,varargin{:});
    R = reshape(R,[dim dim nr]);
    return;
  end

  %R = cellfun(@fit_rotation,S,'UniformOutput',false);
  %R = reshape(cell2mat(R'),[dim dim nr]);
  % For loop is faster
  R = zeros([dim dim nr]);
  SS = zeros([dim dim nr]);
  for ii = 1:nr
    % svd
    [su,ss,sv]=svd(S(:,:,ii));
    Ri = sv*su';
    SS(:,:,ii) = ss;
    % if reflection then flip last column
    if(~allow_flips && det(Ri) < 0 )
      su(:,end) = -su(:,end);
      Ri = sv*su';
    end
    % should definitely be rotation now
    %assert( det(Ri) >= 0 );
    R(:,:,ii) = Ri;
  end

  function D = det3(M)
    % DET3 compute the determinant of a 3x3 matrix
    % Input:
    %   M  3 by 3 matrix
    % Output:
    %   D  determinant
    %
    % http://en.wikipedia.org/wiki/Determinant#3-by-3_matrices
    D = ...
      M(1,1) * M(2,2) * M(3,3) + ...
      M(1,2) * M(2,3) * M(3,1) + ...
      M(1,3) * M(2,1) * M(3,2) - ...
      M(1,3) * M(2,2) * M(3,1) - ...
      M(1,2) * M(2,1) * M(3,3) - ...
      M(1,1) * M(2,3) * M(3,2);
  end

end


% BilinearClPooling is the dagnn wapper of vl_nnbilinearclpool which
% computes outer product of outputs of two layers and pool the features
% across all locations

% Copyright (C) 2015 Tsung-Yu Lin, Aruni RoyChowdhury, Subhransu Maji.
% All rights reserved.
%
% This file is part of the BCNN and is made available under
% the terms of the BSD license (see the COPYING file).

classdef BilinearClPooling < dagnn.Filter
  properties
    method = 'sum'
    normalizeGradients = false;
  end

  methods
    function outputs = forward(obj, inputs, params)
      outputs{1} = vl_nnbilinearclpool(inputs{1}, inputs{2});
    end

    function [derInputs, derParams] = backward(obj, inputs, params, derOutputs)
      [derInputs{1}, derInputs{2}] = vl_nnbilinearclpool(inputs{1}, inputs{2}, derOutputs{1});
      if obj.normalizeGradients
        gradNorm = sum(abs(derInputs{1}(:))) + 1e-8;
        derInputs{1} = derInputs{1}/gradNorm;

        gradNorm = sum(abs(derInputs{2}(:))) + 1e-8;
        derInputs{2} = derInputs{2}/gradNorm;
      end
      derParams = {} ;
    end

    function rfs = getReceptiveFields(obj)
      rfs(1,1).size = [NaN NaN] ;
      rfs(1,1).stride = [NaN NaN] ;
      rfs(1,1).offset = [NaN NaN] ;
      rfs(2,1) = rfs(1,1) ;
    end

    function obj = BilinearClPooling(varargin)
      obj.load(varargin) ;
    end
  end
end


function [Sc,Cmat,Ctot,Cvec,Cent,f]=CrossSpecMat(data,win,params)
%
%
% Multi-taper cross-spectral matrix - another routine, this one allows for multiple trials and channels
% but does not do confidence intervals. Also this routine always averages over trials - continuous process
%
% Usage:
%
% [Sc,Cmat,Ctot,Cvec,Cent,f]=CrossSpecMat(data,win,params)
% Input:
% Note units have to be consistent. See chronux.m for more information.
%       data (in form samples x channels x trials)
%       win  (duration of non-overlapping window)
%       params: structure with fields tapers, pad, Fs, fpass
%       - optional
%           tapers (precalculated tapers from dpss, or in the form [NW K] e.g [3 5]) -- optional.
%                                                 If not specified, use [NW K]=[3 5]
%	        pad		    (padding factor for the FFT) - optional. Defaults to 0.
%			      	 e.g. For N = 500, if PAD = 0, we pad the FFT
%			      	 to 512 points; if PAD = 2, we pad the FFT
%			      	 to 2048 points, etc.
%           Fs   (sampling frequency) - optional. Default 1.
%           fpass    (frequency band to be used in the calculation in the form
%                                   [fmin fmax])- optional.
%                                   Default all frequencies between 0 and Fs/2
% Output:
%       Sc (cross spectral matrix frequency x channels x channels)
%       Cmat Coherence matrix frequency x channels x channels
%       Ctot Total coherence: SV(1)^2/sum(SV^2) (frequency)
%       Cvec leading Eigenvector (frequency x channels)
%       Cent A different measure of total coherence: GM/AM of SV^2s
%       f (frequencies)
d=ndims(data);
if d<2, error('Need multidimensional array'); end
if d==2, [N,C]=size(data); end;
if d==3, [N,C,Ntr]=size(data); end;
if nargin < 3; params=[]; end;
[tapers,pad,Fs,fpass,err,trialave,params]=getparams(params);
clear err trialave params
nwin=round(win*Fs); nfft=2^(nextpow2(nwin)+pad);
[f,findx]=getfgrid(Fs,nfft,fpass);
tapers=dpsschk(tapers,nwin,Fs); % check tapers
Sc=zeros(length(findx),C,C);

Nwins=floor(N/nwin);

if d==3, % If there are multiple trials
for iwin=1:Nwins,
    for i=1:Ntr,
        data1=squeeze(data(1+(iwin-1)*nwin:iwin*nwin,:,i));
        J1=mtfftc(detrend(data1),tapers,nfft,Fs);
        J1=J1(findx,:,:);
        for k=1:C,
            for l=1:C,
                spec=squeeze(mean(conj(J1(:,:,k)).*J1(:,:,l),2));
            Sc(:,k,l)=Sc(:,k,l)+spec;
            end
        end
    end
end
Sc=Sc/(Nwins*Ntr);
end

if d==2, % only one trial
for iwin=1:Nwins,
        data1=squeeze(data(1+(iwin-1)*nwin:iwin*nwin,:));
        J1=mtfftc(data1,tapers,nfft,Fs);
        J1=J1(findx,:,:);
        for k=1:C,
            for l=1:C,
            Sc(:,k,l)=Sc(:,k,l)+squeeze(mean(conj(J1(:,:,k)).*J1(:,:,l),2));
            end
        end
end
Sc=Sc/Nwins;
end

Cmat=Sc;
Sdiag=zeros(length(findx),C);
for k=1:C,
    Sdiag(:,k)=squeeze(Sc(:,k,k));
end

for k=1:C,
    for l=1:C,
        Cmat(:,k,l)=Sc(:,k,l)./sqrt(abs(Sdiag(:,k).*Sdiag(:,l)));
    end
end

Ctot=zeros(length(findx),1); Cent=Ctot;
Cvec=zeros(length(findx),C);
for i=1:length(findx),
    [u s]=svd(squeeze(Sc(i,:,:)));s=diag(s);
    Ctot(i)=s(1).^2/sum(s.^2); Cent(i)=exp(mean(log(s.^2)))/mean(s.^2);
    Cvec(i,:)=transpose(u(:,1));

end


classdef RWMOP35 < PROBLEM
% <multi> <real> <constrained>
% Synchronous pptimal pulse-width modulation of 13-level inverters

%------------------------------- Reference --------------------------------
% A. Kumar, G. Wu, M. Ali, Q. Luo, R. Mallipeddi, P. Suganthan, and S. Das,
% A benchmark-suite of real-world constrained multi-objective optimization
% problems and some baseline results, Swarm and Evolutionary Computation,
% 2021, 67: 100961.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    methods
        %% Initialization
        function Setting(obj)
            obj.M        = 2;
            obj.D        = 30;
            obj.lower    = zeros(1,30);
            obj.upper    = 90*ones(1,30);
            obj.encoding = ones(1,obj.D);
        end
        %% Evaluate multiple solutions
        function Population = Evaluation(obj,varargin)
            x = varargin{1};
            m = 0.32;
            s = [1,1,1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,-1,1,-1,1,-1,1,1,1,1,-1,-1,-1,1,-1,1];
            k = [5,7,11,13,17,19,23,25,29,31,35,37,41,43,47,49,53,55,59,61,65,67,71,73,77,79,83,85,91,95,97];
            % Objective function
            for i = 1 : size(x,1)
                su = 0;
                for j = 1 : 31
                    su2 = 0;
                    for l = 1 : size(x,2)
                        su2 = su2 + s(l).*cos(k(j).*x(i,l)*pi/180);
                    end
                    su = su + su2.^2./k(j).^4;
                end
                f(i,1) = (su).^0.5./(sum(1./k.^4)).^0.5;
            end
            f(:,2) = (sum(s.*cos(x*pi/180),2)-m).^2;
            % Constraints
            for i = 1 : size(x,2)-1
                g(:,i) = x(:,i)-x(:,i+1)+1e-6;
            end
            Population = SOLUTION(varargin{1},f,g,varargin{2:end});
            obj.FE     = obj.FE + length(Population);
        end
        %% Generate a point for hypervolume calculation
        function R = GetOptimum(obj,~)
            R = [1.9499692e+00   1.1076986e+01];
        end
    end
end


function [hr] = us2hr(us)
% Convert time from microseconds to hours.
% Chad Greene 2012
hr = us*2.777777777778e-10 ;


function [w, infos] = sd(problem, in_options)
% Full steepest descent gradient algorithm.
%
% Inputs:
%       problem     function (cost/grad/hess)
%       in_options  options
% Output:
%       w           solution of w
%       infos       information
%
% This file is part of GDLibrary and SGDLibrary.
%
% Created by H.Kasai on Feb. 15, 2016
% Modified by H.Kasai on Mar. 23, 2018
% Modified by H.Kasai on Oct. 20, 2020

    % set dimensions and samples
    d = problem.dim;
    n = problem.samples;

    % set local options
    local_options = [];
    local_options.algorithm = 'SD';
    local_options.sub_mode = 'STANDARD';

    % merge options
    options = mergeOptions(get_default_options(d), local_options);
    options = mergeOptions(options, in_options);

    % initialise
    iter = 0;
    grad_calc_count = 0;
    w = options.w_init;
    w_old = w;
    prev_step = options.step_init;

    if ~isfield(options, 'S')
        if strcmp(options.step_alg, 'exact')
            options.S = eye(d);
        end
    else
        %
    end

    % initialize by BB step-size
    if strcmp(options.step_init_alg, 'bb_init')
        options.step_init = bb_init(problem, w);
    end

    % store first infos
    clear infos;
    [infos, f_val, optgap, grad, gnorm] = store_infos(problem, w, options, [], iter, grad_calc_count, 0);
    grad_old = grad;

    % display info
    if options.verbose
        if ~problem.prox_flag
            fprintf('SD: Iter = %03d, cost = %.24e, gnorm = %.4e, optgap = %.4e\n', iter, f_val, gnorm, optgap);
        else
            fprintf('PG: Iter = %03d, cost = %.24e, gnorm = %.4e, optgap = %.4e\n', iter, f_val, gnorm, optgap);
        end
    end

    % set start time
    start_time = tic();

    % main loop
    while (optgap > options.tol_optgap) && (gnorm > options.tol_gnorm) && (iter < options.max_epoch)

        options.iter = iter;
        [step, ~] = options.linesearchfun(options.step_alg, problem, w, w_old, grad, grad_old, prev_step, options);

        prev_step = step;
        w_old = w;
        if strcmp(options.sub_mode, 'SCALING')
            % diagonal scaling
            if isempty(options.S)
                h = problem.full_hess(w);
                options.S = diag(1./diag(h));
            end

            % update w
            w = w - step * options.S * grad;
        else
            % update w
            w = w - step * grad;
        end

        % proximal operator
        if problem.prox_flag
            w = problem.prox(w, step);
        end

        % store gradient
        grad_old = grad;

        % measure elapsed time
        elapsed_time = toc(start_time);

        % count gradient evaluations
        grad_calc_count = grad_calc_count + n;

        % update iter
        iter = iter + 1;

        % store infos
        [infos, f_val, optgap, grad, gnorm] = store_infos(problem, w, options, infos, iter, grad_calc_count, elapsed_time);

        % display infos
        if options.verbose
            if ~problem.prox_flag
                fprintf('SD: Iter = %03d, cost = %.24e, gnorm = %.4e, optgap = %.4e\n', iter, f_val, gnorm, optgap);
            else
                fprintf('PG: Iter = %03d, cost = %.24e, gnorm = %.4e, optgap = %.4e\n', iter, f_val, gnorm, optgap);
            end
        end
    end

    if gnorm < options.tol_gnorm
        fprintf('Gradient norm tolerance reached: tol_gnorm = %g\n', options.tol_gnorm);
    elseif optgap < options.tol_optgap
        fprintf('Optimality gap tolerance reached: tol_optgap = %g\n', options.tol_optgap);
    elseif iter == options.max_epoch
        fprintf('Max iter reached: max_epoch = %g\n', options.max_epoch);
    end

end


clear
clc
close all
addpath('./tensor_fit/');
addpath('./RiceOptVST/');
addpath('./GL-HOSVD/');
addpath('./HOSVD/');
addpath('./data/in_vivo_data/');

load '6dir_b1000_NSA10.mat';
load 'bvalue.mat'
load 'gradient.mat'
load 'mask_slice_4th.mat'
[N1,N2,numDWI] = size(im_r);

 % ---- noise estimation ---- %
idata  = im_r.^2; % assumption of the rician distribution
tdata  = idata(1:30,1:30,2:end);
for i  = 1:numDWI-1
    tbg = tdata(:,:,i);
    sigmas(i) = sqrt(mean(tbg(:))/2);
end
sigmah = mean(sigmas(2:end)); % estimate of sigma

 % ---- Setting up parameters ---- %
kglobal=0.4;
klocal=0.5; %the denoising effect can be improved by adjusting the parameter klocal

% ---- start image denoising---- %
rimavst = riceVST(im_r,sigmah,'A');
ims_denoised =glhosvd(rimavst,1,kglobal,klocal);
ims_denoised = riceVST_EUI(ims_denoised ,sigmah,'A');

% ---- FA estimation---- %
display   = 0; bVal=bvalue';   bacq      = bvalue(2);
[FA_denoised, RGB_denoised, tensors_denoised, MD_denoised] = tensor_est(ims_denoised,gradientDirections,bVal,bacq,display,mask);
[FA_noisy, RGB_noisy, tensors_noisy,MD_noisy] = tensor_est(im_r,gradientDirections,bVal,bacq,display,mask);
[FA_reference, RGB_reference, tensors_reference,MD_reference] = tensor_est(im_ref,gradientDirections,bVal,bacq,display,mask);

% ---- Display results---- %
figure,imshow(FA_noisy,[0 1]);figure,imshow(FA_denoised,[0 1]);figure,imshow(FA_reference,[0 1])
figure,imshow(RGB_noisy,[]);figure,imshow(RGB_denoised,[]);figure,imshow(RGB_reference,[])
figure,imshow(im_r(:,:,5),[]);figure,imshow(ims_denoised(:,:,5),[]);figure,imshow(im_ref(:,:,5),[])


classdef RWMOP25 < PROBLEM
% <multi> <real> <constrained>
% Process synthesis problem

%------------------------------- Reference --------------------------------
% A. Kumar, G. Wu, M. Ali, Q. Luo, R. Mallipeddi, P. Suganthan, and S. Das,
% A benchmark-suite of real-world constrained multi-objective optimization
% problems and some baseline results, Swarm and Evolutionary Computation,
% 2021, 67: 100961.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    methods
        %% Initialization
        function Setting(obj)
            obj.M        = 2;
            obj.D        = 2;
            obj.lower    = [0,-0.49];
            obj.upper    = [1.6,1.49];
            obj.encoding = ones(1,obj.D);
        end
        %% Evaluate multiple solutions
        function Population = Evaluation(obj,varargin)
            x  = varargin{1};
            x1 = x(:,1); x2 = round(x(:,2));
            % Objective function
            f(:,1) = x2 + 2*x1;
            f(:,2) = -x1.^2 -x2;
            % Constraints
            g(:,1) = f(:,2) +1.25;
            g(:,2) = x1 + x2 -1.6;
            Population = SOLUTION(varargin{1},f,g,varargin{2:end});
            obj.FE     = obj.FE + length(Population);
        end
        %% Generate a point for hypervolume calculation
        function R = GetOptimum(obj,~)
            R = [3.2000000e+00  -1.2500000e+00];
        end
    end
end


%Image Compression

%compdct.m:
%main code to compress an image we only run compdct.m
%decompdct.m:
% to decompress an image we only run compdct.m
%resize.m:
%here we give an esample: if we have value big than  65792 like 19071001 in
%8 bits we can not save it so we use resize:
%X=19071001;
%Y=resize(X)
%>>Y
%1 35 0 25
%here X=1*256^3+35*256^2+0*256^1+25*256^0
%proba.m:
%like hist.m
%zigzag.m:
%zigzag scan for bloc [8 8]
%zigzaginv.m:
%inverse zigzag scan for bloc [8 8]
%zigzag16.m:
%zigzag scan for bloc [16 16]
%zigzinv16.m:
%inverse zigzag scan for bloc [16 16]
%zigzag32.m:
%zigzag scan for bloc [32 32]
%zigzinv32.m:
%inverse zigzag scan for bloc [32 32]
%rle.m:
%Run length encoding
%irle.m:
% Inverse Run length encoding
%abais.m:
%here we give an esample: if we have value big than 255 like 275 in
%8 bits we can not save it so we use resize:
%X=275;
%Y=resize(X)
%>>Y
%1 19
%here X=1*256^1+19*256^0
%Iabais.m:
%X=Iabais(y);


% REORIENT_FACETS Reorient faces of a triangle mesh (V,F) so that the left-hand
% rule normal of each face (consistently) points outward.
%
% [FF,I] = reorient_facets(V,F)
% [FF,I] = reorient_facets(V,F,'ParameterName',ParameterValue, ...)
%
% Inputs:
%   V  #V by 3 list of vertex positions
%   F  #F by 3 list of triangle indicies into V
%   Optional:
%     'NumRays'  followed by total number of rays {#F*100}
%     'MinRays'  followed by minimum number of rays per patch/face {10}
%     'Facetwise'  followed by whether each facet should be considered
%       independently, could lead to inconsistent orientation of manifoldly
%       neighboring facets {false}
%     'UseParity'  Whether to use parity(?) {false}
% Outputs:
%   FF   #F by 3 list of reoriented facets
%   I  #F list of whether each face was flipped
%


function [out] = interception_3(p1,In)
%interception_3

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Interception excess after a fraction is intercepted
% Constraints:  -
% @(Inputs):    p1   - fraction throughfall [-]
%               In   - incoming flux [mm/d]

out = p1.*In;

end


function [ a, b ] = p08_lim ( dim_num )

%*****************************************************************************80
%
%% P08_LIM returns the integration limits for problem 08.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the argument.
%
%    Output, real A(DIM_NUM), B(DIM_NUM), the lower and upper
%    limits of integration.
%
  a(1:dim_num) = 0.0;
  b(1:dim_num) = 1.0;

  return
end