function [ SimilarityMatrix ] = similarityNeighbor( x, n, ~)
%similarityNeighbor Create a link for the n'th neighbour

    sz = size(x,1);
    SimilarityMatrix = eye(sz);

    i = 1:sz-n;
    SimilarityMatrix(sub2ind([sz, sz], i+n,i)) = 1;
    SimilarityMatrix(sub2ind([sz, sz], i,i+n)) = 1;

    DiagMask = ones(size(x, 1)) - eye(size(x,1));
    SimilarityMatrix = SimilarityMatrix .* DiagMask;
    SimilarityMatrix = SimilarityMatrix + eye(size(x, 1));

end


function plot_continuous_samples(SAMPLES,Y)

% plot results of MCMC sampler
% The mean calcium sample, spike sampler raster plot and samples for
% amplitude, number of spikes, discrete time constants, noise variance,
% baseline and initial concentration are generated, together with their
% autocorrelation functions. If the marginalized flag was used, then the
% posterior pdfs of baseline and initial concentration are plotted.

% Inputs:
% SAMPLES:  structure with SAMPLES obtained from cont_ca_sampler.m
% Y:        inpurt fluorescence trace

% Author: Eftychios A. Pnevmatikakis, 2016, Simons Foundation

T = length(Y);
N = length(SAMPLES.ns);
show_gamma = 1;
P = SAMPLES.params;
P.f = 1;
g = P.g(:);
p = min(length(g),2);
Dt = 1/P.f;                                     % length of time bin
if ~isfield(SAMPLES,'g');
    show_gamma = 0;
    SAMPLES.g = ones(N,1)*g';
end

if p == 1
    tau_1 = 0;
    tau_2 = -Dt/log(g);                         % continuous time constant
    G1 = speye(T);
    G2 = spdiags(ones(T,1)*[-g,1],[-1:0],T,T);
    ge = P.g.^((0:T-1)');
elseif p == 2
    gr = roots([1,-g']);
    p1_continuous = log(min(gr))/Dt;
    p2_continuous = log(max(gr))/Dt;
    tau_1 = -1/p1_continuous;                   %tau h - smaller (tau_d * tau_r)/(tau_d + tau_r)
    tau_2 = -1/p2_continuous;                   %tau decay - larger
    G1 = spdiags(ones(T,1)*[-min(gr),1],[-1:0],T,T);
    G2 = spdiags(ones(T,1)*[-max(gr),1],[-1:0],T,T);
    ge = G2\[1;zeros(T-1,1)];
else
    error('This order of the AR process is currently not supported');
end

if length(SAMPLES.Cb) == 2
    marg = 1;       % marginalized sampler
else
    marg = 0;       % full sampler
end

C_rec = zeros(N,T);
for rep = 1:N
    %trunc_spikes = ceil(SAMPLES.ss{rep}/Dt);
    tau = SAMPLES.g(rep,:);
    gr = exp(-1./tau);
    ge = max(gr).^(0:T-1)';
    s_1 =   sparse(ceil(SAMPLES.ss{rep}/Dt),1,exp((SAMPLES.ss{rep} - Dt*ceil(SAMPLES.ss{rep}/Dt))/tau(1)),T,1);
    s_2 =   sparse(ceil(SAMPLES.ss{rep}/Dt),1,exp((SAMPLES.ss{rep} - Dt*ceil(SAMPLES.ss{rep}/Dt))/tau(2)),T,1);
    if gr(1) == 0
        G1 = sparse(1:T,1:T,Inf*ones(T,1)); G1sp = zeros(T,1);
    else
        G1 = spdiags(ones(T,1)*[-min(gr),1],[-1:0],T,T); G1sp = G1\s_1(:);
    end
    G2 = spdiags(ones(T,1)*[-max(gr),1],[-1:0],T,T);
    Gs = (-G1sp+ G2\s_2(:))/diff(gr);
    if marg
        %C_rec(rep,:) = SAMPLES.Cb(1) + SAMPLES.Am(rep)*filter(1,[1,-SAMPLES.g(rep,:)],full(s_)+[SAMPLES.Cin(:,1)',zeros(1,T-p)]);
        C_rec(rep,:) = SAMPLES.Cb(1) + SAMPLES.Am(rep)*Gs + (ge*SAMPLES.Cin(:,1));
    else
        %C_rec(rep,:) = SAMPLES.Cb(rep) + SAMPLES.Am(rep)*filter(1,[1,-SAMPLES.g(rep,:)],full(s_)+[SAMPLES.Cin(rep,:),zeros(1,T-p)]);
        C_rec(rep,:) = SAMPLES.Cb(rep) + SAMPLES.Am(rep)*Gs + (ge*SAMPLES.Cin(rep,:)');
    end
end
Nc = 60;

if marg
    rows = 4;
else
    rows = 5;
end

figure;
    set(gcf, 'PaperUnits', 'inches','Units', 'inches')
    set(gcf, 'PaperPositionMode', 'manual')
    set(gcf, 'PaperPosition',[0,0, 14, 15])
    set(gcf, 'Position',[2,2, 14, 15])
    ha(1) = subplot(rows,4,[1:4]);plot(Dt*(1:T),Y); hold all; plot(Dt*(1:T),mean(C_rec,1),'linewidth',2);
        title('Calcium traces','fontweight','bold','fontsize',14)
        legend('Raw data','Mean sample');
    ha(2) = subplot(rows,4,[5:8]); imagesc((1:T)*Dt,1:N,samples_cell2mat(SAMPLES.ss,T));
        title('Spike raster plot','fontweight','bold','fontsize',14)
        linkaxes(ha,'x');
    subplot(rows,4,4+5); plot(1:N,SAMPLES.ns); title('# of spikes','fontweight','bold','fontsize',14)
    subplot(rows,4,4+6); plot(-Nc:Nc,xcov(SAMPLES.ns,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc]);
        title('Autocorrelation','fontweight','bold','fontsize',14)

    if ~show_gamma
        subplot(rows,4,4+7); plot(1:N,SAMPLES.ld); title('Firing Rate','fontweight','bold','fontsize',14)
        subplot(rows,4,4+8); plot(-Nc:Nc,xcov(SAMPLES.ld,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
        title('Autocorrelation','fontweight','bold','fontsize',14)
    else
        if gr(1) == 0
            subplot(rows,4,4+7);  plot(1:N,exp(-1./SAMPLES.g(:,2))); title('Decay Time Constant','fontweight','bold','fontsize',14);
            subplot(rows,4,4+8);  plot(-Nc:Nc,xcov(exp(-1./SAMPLES.g(:,2)),Nc,'coeff')); title('Autocorrelation','fontweight','bold','fontsize',14);
            set(gca,'XLim',[-Nc,Nc])
        else
            subplot(rows,4,4+7);  plot(1:N,exp(-1./SAMPLES.g)); title('Decay Time Constants','fontweight','bold','fontsize',14);
            g_cov = xcov(exp(-1./SAMPLES.g),Nc,'coeff');
            subplot(rows,4,4+8);  plot(-Nc:Nc,g_cov(:,[1,4])); title('Autocorrelation','fontweight','bold','fontsize',14);
            set(gca,'XLim',[-Nc,Nc])
        end
    end

    subplot(rows,4,4+9); plot(1:N,SAMPLES.Am); title('Spike Amplitude','fontweight','bold','fontsize',14)
    subplot(rows,4,4+10); plot(-Nc:Nc,xcov(SAMPLES.Am,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
        title('Autocorrelation','fontweight','bold','fontsize',14)
    if marg
        xx = SAMPLES.Cb(1) + linspace(-4*SAMPLES.Cb(2),4*SAMPLES.Cb(2));
        subplot(4,4,15); plot(xx,normpdf(xx,SAMPLES.Cb(1),SAMPLES.Cb(2)));
            set(gca,'XLim',[xx(1),xx(end)])
            title('Marg. post. of baseline','fontweight','bold','fontsize',14)

        xx = SAMPLES.Cin(1) + linspace(-4*SAMPLES.Cin(2),4*SAMPLES.Cin(2));
        subplot(4,4,16); plot(xx,normpdf(xx,SAMPLES.Cin(1),SAMPLES.Cin(2)));
            set(gca,'XLim',[xx(1),xx(end)])
            title('Marg. post. of initial con','fontweight','bold','fontsize',14)
    else
        subplot(5,4,4+11); plot(1:N,SAMPLES.Cb); title('Baseline','fontweight','bold','fontsize',14)
        subplot(5,4,4+12); plot(-Nc:Nc,xcov(SAMPLES.Cb,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
            title('Autocorrelation','fontweight','bold','fontsize',14)
        subplot(5,4,4+13); plot(1:N,SAMPLES.Cin); title('Initial Concentration','fontweight','bold','fontsize',14)
        xcov_Cin = xcov(SAMPLES.Cin,Nc,'coeff');
        subplot(5,4,4+14); plot(-Nc:Nc,xcov_Cin); set(gca,'XLim',[-Nc,Nc])
            title('Autocorrelation','fontweight','bold','fontsize',14)
        subplot(5,4,4+15); plot(1:N,SAMPLES.sn2); title('Noise variance','fontweight','bold','fontsize',14)
        subplot(5,4,4+16); plot(-Nc:Nc,xcov(SAMPLES.sn2,Nc,'coeff')); set(gca,'XLim',[-Nc,Nc])
            title('Autocorrelation','fontweight','bold','fontsize',14)
    end
    drawnow;


function [dS,f]=mtdspectrumc(data,phi,params)
% Multi-taper frequency derivative of the spectrum - continuous process
%
% Usage:
%
% [dS,f]=mtdspectrumc(data,phi,params)
% Input:
%   Note that all times can be in arbitrary units. But the units have to be
%   consistent. So, if E is in secs, win, t have to be in secs, and Fs has to
%   be Hz. If E is in samples, so are win and t, and Fs=1. In case of spike
%   times, the units have to be consistent with the units of data as well.
%       data        (in form samples x channels/trials or a single vector) -- required
%       phi         (angle for evaluation of derivative) -- required.
%                       e.g. phi=[0,pi/2] gives the time and frequency derivatives
%       params: structure with fields tapers, pad, Fs, fpass, trialave
%       - optional
%           tapers : precalculated tapers from dpss or in the one of the following
%                    forms:
%                   (1) A numeric vector [TW K] where TW is the
%                       time-bandwidth product and K is the number of
%                       tapers to be used (less than or equal to
%                       2TW-1).
%                   (2) A numeric vector [W T p] where W is the
%                       bandwidth, T is the duration of the data and p
%                       is an integer such that 2TW-p tapers are used. In
%                       this form there is no default i.e. to specify
%                       the bandwidth, you have to specify T and p as
%                       well. Note that the units of W and T have to be
%                       consistent: if W is in Hz, T must be in seconds
%                       and vice versa. Note that these units must also
%                       be consistent with the units of params.Fs: W can
%                       be in Hz if and only if params.Fs is in Hz.
%                       The default is to use form 1 with TW=3 and K=5
%
%	        pad		    (padding factor for the FFT) - optional (can take values -1,0,1,2...).
%                    -1 corresponds to no padding, 0 corresponds to padding
%                    to the next highest power of 2 etc.
%			      	 e.g. For N = 500, if PAD = -1, we do not pad; if PAD = 0, we pad the FFT
%			      	 to 512 points, if pad=1, we pad to 1024 points etc.
%			      	 Defaults to 0.
%           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
%           trialave (average over trials/channels when 1, don't average when 0) - optional. Default 0
% Output:
%       dS       (spectral derivative in form phi x frequency x channels/trials if trialave=0 or
%                in form phi x frequency if trialave=1)
%       f        (frequencies)

if nargin < 2; error('Need data and angle'); end;
if nargin < 3; params=[]; end;
[tapers,pad,Fs,fpass,err,trialave,params]=getparams(params);
clear err params
data=change_row_to_column(data);
N=size(data,1);
nfft=max(2^(nextpow2(N)+pad),N);
[f,findx]=getfgrid(Fs,nfft,fpass);
tapers=dpsschk(tapers,N,Fs); % check tapers
K=size(tapers,2);
J=mtfftc(data,tapers,nfft,Fs);
J=J(findx,:,:);
A=sqrt(1:K-1);
A=repmat(A,[size(J,1) 1]);
A=repmat(A,[1 1 size(J,3)]);
S=squeeze(mean(J(:,1:K-1,:).*A.*conj(J(:,2:K,:)),2));
if trialave; S=squeeze(mean(S,2));end;
nphi=length(phi);
for p=1:nphi;
    dS(p,:,:)=real(exp(i*phi(p))*S);
end;
dS=squeeze(dS);
dS=change_row_to_column(dS);


function [F,V]=mesh2tri(X,Y,Z,tri_type)

% function [F,V]=mesh2tri(X,Y,Z,tri_type)
% ------------------------------------------------------------------------
%
% This function converts a regular mesh defined by X,Y and Z into a regular
% triangulation. The output is patch data (triangles) in the faces �F� and
% vertices �V� format. The quadrilateral mesh faces are converted to
% triangles by splitting the faces into triangles according to the setting
% tri_type:
%   tri_type ='f' -> forward slash division of quadrilateral
%   tri_type ='b' -> back slash division of quadrilateral
%   tri_type ='x' -> Cross division of quadrilateral
%
% The output coordinates "V" are in the form of V=[X(:),Y(:),Z(:)];
% For forward and back slash subdivision no extra coordinates are
% introduced and therefore the original meshgrid formatted coordinates can
% still be used for plotting, see examples below.
% For cross division extra points are created at the centre of each
% quadrilateral face using the mean of the input coordinates. The extra
% coordinates are the last prod(size(X)-1) points (e.g.
% V((numel(X)+1):end,:) )and can therefore be replaced by interpolated
% coordinates if desired, see example.
%
%
% %% EXAMPLE
% clear all; close all; clc;
%
% [X,Y] = meshgrid(linspace(-10,10,25));
% Z = sinc(sqrt((X/pi).^2+(Y/pi).^2));
%
% figure('units','normalized','Position',[0 0 1 1],'Color','w'); colordef('white');
% subplot(2,2,1);
% surf(X,Y,Z); hold on;
% axis tight; axis square; grid on; axis off; view(3); view(-30,70);
% title('Meshgrid','FontSize',20);
%
% [F,V]=mesh2tri(X,Y,Z,'f');
% C=V(:,3); C=mean(C(F),2);
% subplot(2,2,2);
% patch('Faces',F,'Vertices',V,'FaceColor','flat','CData',C); hold on;
% axis tight; axis square; grid on; axis off; view(3); view(-30,70);
% title('Forward slash','FontSize',20);
%
% [F,V]=mesh2tri(X,Y,Z,'b');
% C=V(:,3); C=mean(C(F),2);
% subplot(2,2,3);
% Example of using original meshgrid coordinates instead
% trisurf(F,X,Y,Z);
% axis tight; axis square; grid on; axis off; axis off; view(3); view(-30,70);
% title('Back slash','FontSize',20);
%
% [F,V]=mesh2tri(X,Y,Z,'x');
% Replace Z-coordinates of added points by interpolated values if desired
% IND=(numel(X)+1):size(V,1);
% ZI = interp2(X,Y,Z,V(IND,1),V(IND,2),'cubic');
% V(IND,3)=ZI;
%
% C=V(:,3); C=mean(C(F),2);
% subplot(2,2,4);
% patch('Faces',F,'Vertices',V,'FaceColor','flat','CData',C); hold on;
% axis tight; axis square; grid on; axis off; view(3); view(-30,70);
% title('Crossed','FontSize',20);
%
%
% Kevin Mattheus Moerman
% gibbon.toolbox@gmail.com
%
% 15/07/2010
%------------------------------------------------------------------------

[J,I]=meshgrid(1:1:size(X,2)-1,1:1:size(X,1)-1);

switch tri_type
    case 'f'%Forward slash
        TRI_I=[I(:),I(:)+1,I(:)+1;  I(:),I(:),I(:)+1];
        TRI_J=[J(:),J(:)+1,J(:);   J(:),J(:)+1,J(:)+1];
        F = sub2ind(size(X),TRI_I,TRI_J);
    case 'b'%Back slash
        TRI_I=[I(:),I(:)+1,I(:);  I(:)+1,I(:)+1,I(:)];
        TRI_J=[J(:)+1,J(:),J(:);   J(:)+1,J(:),J(:)+1];
        F = sub2ind(size(X),TRI_I,TRI_J);
    case 'x'%Cross
        TRI_I=[I(:)+1,I(:);  I(:)+1,I(:)+1;  I(:),I(:)+1;    I(:),I(:)];
        TRI_J=[J(:),J(:);    J(:)+1,J(:);    J(:)+1,J(:)+1;  J(:),J(:)+1];
        IND=((numel(X)+1):numel(X)+prod(size(X)-1))';
        F = sub2ind(size(X),TRI_I,TRI_J);
        F(:,3)=repmat(IND,[4,1]);
        Fe_I=[I(:),I(:)+1,I(:)+1,I(:)]; Fe_J=[J(:),J(:),J(:)+1,J(:)+1];
        Fe = sub2ind(size(X),Fe_I,Fe_J);
        Xe=mean(X(Fe),2); Ye=mean(Y(Fe),2);  Ze=mean(Z(Fe),2);
        X=[X(:);Xe(:)]; Y=[Y(:);Ye(:)]; Z=[Z(:);Ze(:)];
end

V=[X(:),Y(:),Z(:)];

end

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


function [ objects] = room3DFromHyp( points, floor_height )
%ROOM3DFROMHYP Popup room layout hypothesis to 3D
%   points: room corner in sequence in room layout
%   floor_height: assumed floor height, e.g. -160

% uv = xyz2uvN(points);
% high_height = floor_height * tan(uv(1:4,2))./tan(uv(5:8,2));
% ceil_height = mean(high_height);
%
% point3D = zeros(8,3);
% for i = 5:8
%     point3D(i,:) = LineFaceIntersection([0 0 floor_height], [0 0 1], [0 0 0], points(i,:));
% end
COUNTER_CLOCKWISE = true;
FITTINGRULES;

[pt I] = sortXYZ(points(1:4,:));
pd = points(5:8,:); pd = pd(I,:);
sort_points = [pd;pt];
ann_points = sort_points(POINTMAPPING{3},:);

objects = struct('out_points_w',[],'name',[],'type',[],'points',[],'x_w',[]);
[ out_point, x, fval, succ ] = initial_cuboid_3D( ann_points, 3, floor_height, 3, true );

objects.points = ann_points;
objects.type = 3;
objects.name = 'room';
objects.out_points_w = out_point;
objects.x_w = x;

end


function out = echo_enc_mirror(signal, text, d0, d1, alpha, L)
%ECHO_ENC_MIRRORED Echo Hiding with Mirrored Echo Kernels
%
%   INPUT VARIABLES
%       signal : Cover signal
%       text   : Message to hide
%       d0     : Delay rate for bit0
%       d1     : Delay rate for bit1
%       alpha  : Echo amplitude
%       L      : Length of frames
%
%   OUTPUT VARIABLES
%       out    : Stego signal
%
%   Kadir Tekeli (kadir.tekeli@outlook.com)

if nargin < 4
	d0 = 150;     %Delay rate for bit0
	d1 = 200;     %Delay rate for bit1
end

if nargin < 5
	alpha = 0.5;  %Echo amplitude
end

if nargin < 6
	L = 8*1024;   %Length of frames
end

[s.len, s.ch] = size(signal);
bit = getBits(text);
nframe = floor(s.len/L);
N = nframe - mod(nframe,8);      %Number of frames (for 8 bit)

if (length(bit) > N)
	warning('Message is too long, being cropped!');
	bits = bit(1:N);
else
	warning('Message is being zero padded...');
	bits = [bit, num2str(zeros(N-length(bit), 1))'];
end

[echo_zro,echo_one] = mirror_echo(signal,d0,d1,alpha);  %Echo signals
mix = mixer(L,bits,0,1,256)*ones(1, s.ch);              %Mixer signal

%%%%%%%%%%%%%%%%%%%%%%% EMBEDDING MESSAGE... %%%%%%%%%%%%%%%%%%%%%%%
out = signal(1:N*L, :) + echo_zro(1:N*L, :) .* abs(mix-1) ...
                       + echo_one(1:N*L, :) .* mix;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
out = [out; signal(N*L+1:s.len, :)];   %Rest of the signal
end


% RSFIT - find p value for a given value in a given distribution
%             using Ramberg-Schmeiser distribution
%
% Usage: >> p = rsfit(x, val)
%        >> [p c l chi2] = rsfit(x, val, plot)
%
% Input:
%   x    - [float array] accumulation values
%   val  - [float] value to test
%   plot - [0|1|2] plot fit. Using 2, the function avoids creating
%          a new figure. Default: 0.
%
% Output:
%   p    - p value
%   c    - [mean var skewness kurtosis] distribution cumulants
%   l    - [4x float vector] Ramberg-Schmeiser distribution best fit
%          parameters.
%   chi2 - [float] chi2 for goodness of fit (based on 12 bins).
%          Fit is significantly different from data histogram if
%          chi2 > 19 (5%)
%
% Author: Arnaud Delorme, SCCN, 2003
%
% See also: RSADJUST, RSGET, RSPDFSOLV, RSPFUNC
%
% Reference: Ramberg, J.S., Tadikamalla, P.R., Dudewicz E.J., Mykkytka, E.F.
%            A probability distribution and its uses in fitting data.
%            Technimetrics, 1979, 21: 201-214.

% Copyright (C) 2003 Arnaud Delorme, SCCN, 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 [p, c, l, res] = rsfit(x, val, plotflag)

    if nargin < 2
        help rsfit;
        return;
    end
    if nargin < 3
        plotflag  = 0;
    end

    % moments
    % -------
    m1  = mean(x);
    m2  = sum((x-m1).^2)/length(x);
    m3  = sum((x-m1).^3)/length(x);
    m4  = sum((x-m1).^4)/length(x);

    xmean = m1;
    xvar  = m2;
    xskew = m3/(m2^1.5);
    xkurt = m4/(m2^2);
    c     = [ xmean xvar xskew xkurt ];

    if xkurt < 0
        disp('rsfit error: Can not fit negative kurtosis');
        save('/home/arno/temp/dattmp.mat', '-mat', 'x');
        disp('data saved to disk in /home/arno/temp/dattmp.mat');
    end

    % find fit
    % --------
    try,
        [sol tmp exitcode] = fminsearch('rspdfsolv', [0.1 0.1], optimset('TolX',1e-12, 'MaxFunEvals', 100000000), abs(xskew), xkurt);
    catch, exitcode = 0; % did not converge
    end
    if ~exitcode
        try, [sol tmp exitcode] = fminsearch('rspdfsolv', -[0.1 0.1], optimset('TolX',1e-12, 'MaxFunEvals', 100000000), abs(xskew), xkurt);
        catch, exitcode = 0; end
    end
    if ~exitcode,           error('No convergence'); end
    if sol(2)*sol(1) == -1, error('Wrong sign for convergence'); end
    %fprintf('          l-val:%f\n', sol);

    res = rspdfsolv(sol, abs(xskew), xkurt);
    l3 = sol(1);
    l4 = sol(2);

    %load res;
    %[tmp indalpha3] = min( abs(rangealpha3 - xskew) );
    %[tmp indalpha4] = min( abs(rangealpha4 - xkurt) );
    %l3  = res(indalpha3,indalpha4,1);
    %l4  = res(indalpha3,indalpha4,2);
    %res = res(indalpha3,indalpha4,3);

    % adjust fit
    % ----------
    [l1 l2 l3 l4] = rsadjust(l3, l4, xmean, xvar, xskew);
    l = [l1 l2 l3 l4];
    p = rsget(l, val);

    % compute goodness of fit
    % -----------------------
    if nargout > 3 || plotflag

        % histogram of value 12 bins
        % --------------------------
        [N X] = hist(x, 25);
        interval = X(2)-X(1);
        X = [X-interval/2 X(end)+interval/2]; % borders

        % regroup bin with less than 5 values
        % -----------------------------------
        indices2rm = [];
        for index = 1:length(N)-1
            if N(index) < 5
                N(index+1) = N(index+1) + N(index);
                indices2rm = [ indices2rm index];
            end
        end
        N(indices2rm)   = [];
        X(indices2rm+1) = [];
        indices2rm = [];
        for index = length(N):-1:2
            if N(index) < 5
                N(index-1) = N(index-1) + N(index);
                indices2rm = [ indices2rm index];
            end
        end
        N(indices2rm)   = [];
        X(indices2rm)   = [];

        % compute expected values
        % -----------------------
        for index = 1:length(X)-1
            p1 = rsget( l, X(index+1));
            p2 = rsget( l, X(index  ));
            expect(index) = length(x)*(p1-p2);
        end

        % value of X2
        % -----------
        res = sum(((expect - N).^2)./expect);

        % plot fit
        % --------
        if plotflag
            if plotflag ~= 2, figure('paperpositionmode', 'auto'); end
            hist(x, 10);

            % plot fit
            % --------
            xdiff = X(end)-X(1);
            abscisia   = linspace(X(1)-0.2*xdiff, X(end)+0.2*xdiff, 100);
            %abscisia  = (X(1:end-1)+X(2:end))/2;
            expectplot = zeros(1,length(abscisia)-1);
            for index = 2:length(abscisia);
                p1 = rsget( l, abscisia(index-1));
                p2 = rsget( l, abscisia(index  ));
                expectplot(index-1) = length(x)*(p2-p1);
                % have to do this subtraction since this a cumulate density distribution
            end
            abscisia = (abscisia(2:end)+abscisia(1:end-1))/2;
            hold on; plot(abscisia, expectplot, 'r');

            % plot PDF
            % ----------
            pval = linspace(0,1, 102); pval(1) = []; pval(end) = [];
            rp   = l(1) + (pval.^l(3) - (1-pval).^l(4))/l(2);
            fp   = l(2)*1./(l(3).*(pval.^(l(3)-1)) + l(4).*((1-pval).^(l(4)-1)));
            [maxval index]  = max(expect);
            [tmp closestind] = min(abs(rp - abscisia(index)));
            fp = fp./fp(closestind)*maxval;
            plot(rp, fp, 'g');
            legend('Chi2 fit (some bins have been grouped)', 'Pdf', 'Data histogram'  );
            xlabel('Bins');
            ylabel('# of data point per bin');
            title (sprintf('Fit of distribution using Ramberg-Schmeiser distribution (Chi2 = %2.4g)', res));
        end
    end
    return


function [N, eta, sigma_g] = scd_noise_fit_histo(data,varargin)
% [N, eta, sigma_g] = scd_noise_fit_histo(data)
% [N, eta, sigma_g] = scd_noise_fit_histo(__,Name,Value)

data=data(:);
p=inputParser;
addRequired(p,'data',@isnumeric)
addOptional(p,'nbins',max(15,sqrt(length(data))));
[~, xmax] = range_outlier(data);
addOptional(p,'maxval',xmax);
addOptional(p,'maxy',0);
addOptional(p,'color',[0 0 1],@isnumeric);
addOptional(p,'fig',1,@isnumeric);
addOptional(p,'plotfit',0,@isnumeric);
addOptional(p,'distrib','Non-central Chi',@(x) any(validatestring(x,{'Non-central Chi','Rician'})));

if logical(exist('OCTAVE_VERSION', 'builtin'))
    in.fig = varargin{2};
    in.distrib = varargin{4};
    in.nbins = max(15,sqrt(length(data)));
    [~, in.maxval] = range_outlier(data);
    in.maxy = 0;
    in.color = [0 0 1];
    in.plotfit = 0;
else
    parse(p,data,varargin{:});
    in=p.Results;
end

%% PREPARE DATA
data(data==0)=[];
data(data>in.maxval)=[];

if isinteger(data)
    xout=double(unique(data(:)));
    n=double(histc(data(:),xout));
else
    [n,xout]=hist(data,in.nbins);
end
xout(n==0)=[]; n(n==0)=[];  n(xout==0)=0;
n=n/trapz(xout,n);

xout = xout(:); n = n(:);
maxnoise=cumtrapz(xout,n);
maxnoise=xout(find(maxnoise>0.999,1,'first'));
data(data>maxnoise)=[];

if isinteger(data)
    xout=double(unique(data(:)));
    n=double(histc(data(:),xout));
else
    [n,xout]=hist(data,in.nbins);
end

xout(n==0)=[]; n(n==0)=[];  n(xout==0)=0;
n=n/trapz(xout,n);
n(xout<0)=[];
xout(xout<0)=[];

xout = xout(:); n = n(:);
xi=0:max(xout)/in.nbins:max(xout);
yi = interp1(xout,n,xi);
yi(isnan(yi))=0;
yi=yi/trapz(xi,yi);
xi=xout; yi=n;

%% Fit: 'non-central chi'.
%eta = sum(xi.*yi.*mean(diff(xi)));
%    [N      eta     sigma]
var0=[1           eps            std(double(data))];
lb = [1           0                  0.1        ];
ub= [10    double(max(data)) std(double(data)*2)];
switch in.distrib
    case 'Non-central Chi'
        fx = [0 0 0];
    case 'Rician'
        fx = [1 1 0];
end

options = optimset('Algorithm','trust-region-reflective','TolFun',1e-8,'Display','final','MaxIter',10,'Display','off');
disp('     N        eta      sigma_g')
[varfit] = lsqnonlin(@(x1) noncentralchi_error(addfixparameters(var0,x1,fx),xi,yi,in.plotfit), var0(~fx), lb(~fx), ub(~fx),options);
varfit = addfixparameters(var0,varfit,fx);
disp(varfit)
N=varfit(1); eta=varfit(2); sigma_g=varfit(3);
fval = noncentralchi(xi, N,sigma_g,eta);

if in.fig
    figure(73)
    set(73,'Name','Noise histogram','NumberTitle','off')
    plot(xi,yi,'+','Color',in.color,'MarkerSize',10); hold on, plot(xi,fval,'Color',[1 0 0],'Linewidth',2);
    xlim([0 in.maxval]);
    if ~in.maxy, maxy=2*max(yi); else maxy=in.maxy; end
    ylim([0 maxy])
    title(['N = ' num2str(N) ', eta = ' num2str(eta) ', sigma = ' num2str(sigma_g)])
end

end

function Error = noncentralchi_error(var,x,y,plotfit)
N=var(1); eta=var(2); sigma_g=var(3);
f= noncentralchi(x, N,sigma_g,eta);
f(isnan(f))=0;
f=f/trapz(x,f);
if rand<plotfit
    disp(num2str(var))
    figure(4)
    hold off, plot(x,y); hold on, plot(x,f,'r');
    xlim([0 max(x)]);
    ylim([0 2*max(y)])
    pause(0.1)
end
Error = abs(f-y);
end

function p= noncentralchi(x, N,sigma_g,eta)
p = abs(x).^N./(sigma_g^2*eta^(N-1)).*exp(-(x.^2+eta^2)/(2*sigma_g^2)).*besseli(N-1,x*eta/sigma_g^2);
end


function [f,relres,iter]=isgramreal(s,g,a,M,varargin)
%ISGRAMREAL  Spectrogram inversion (real signal)
%   Usage:  f=isgramreal(s,g,a,M);
%           f=isgramreal(s,g,a,M,Ls);
%           [f,relres,iter]=isgramreal(...);
%
%   Input parameters:
%         c       : Array of coefficients.
%         g       : Window function.
%         a       : Length of time shift.
%         M       : Number of channels.
%         Ls      : length of signal.
%   Output parameters:
%         f       : Signal.
%         relres  : Vector of residuals.
%         iter    : Number of iterations done.
%
%   `isgramreal(s,g,a,M)` attempts to invert a spectrogram computed by ::
%
%     s = abs(dgtreal(f,g,a,M)).^2;
%
%   by an iterative method.
%
%   `isgramreal(s,g,a,M,Ls)` does as above but cuts or extends *f* to length *Ls*.
%
%   If the phase of the spectrogram is known, it is much better to use
%   |dgtreal|
%
%   `f,relres,iter]=isgramreal(...)` additionally returns the residuals in a
%   vector *relres* and the number of iteration steps done.
%
%   Generally, if the spectrogram has not been modified, the iterative
%   algorithm will converge slowly to the correct result. If the
%   spectrogram has been modified, the algorithm is not guaranteed to
%   converge at all.
%
%   `isgramreal` takes the following parameters at the end of the line of
%   input arguments:
%
%     'lt',lt      Specify the lattice type. See the help on
%                  |matrix2latticetype|. Only the rectangular or quinqux
%                  lattices can be specified.
%
%     'zero'       Choose a starting phase of zero. This is the default
%
%     'rand'       Choose a random starting phase.
%
%     'int'        Construct a starting phase by integration. Only works
%                  for Gaussian windows.
%
%     'griflim'    Use the Griffin-Lim iterative method, this is the
%                  default.
%
%     'bfgs'       Use the limited-memory Broyden Fletcher Goldfarb
%                  Shanno (BFGS) method.
%
%     'tol',t      Stop if relative residual error is less than the specified tolerance.
%
%     'maxit',n    Do at most n iterations.
%
%     'print'      Display the progress.
%
%     'quiet'      Don't print anything, this is the default.
%
%     'printstep',p
%                  If 'print' is specified, then print every p'th
%                  iteration. Default value is p=10.
%
%   The BFGS method makes use of the minFunc software. To use the BFGS method,
%   please install the minFunc software from:
%   `<http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html>`_.
%
%   See also:  dgtreal, idgtreal
%
%   References: griffin1984sem decorsiere2011 liu1989limited

%   AUTHOR : Remi Decorsiere and Peter L. Søndergaard.
%   REFERENCE: OK

% Check input paramameters.

  if nargin<3
    error('%s: Too few input parameters.',upper(mfilename));
  end;

  if numel(g)==1
    error('g must be a vector (you probably forgot to supply the window function as input parameter.)');
  end;

  definput.keyvals.Ls=[];
  definput.keyvals.lt=[0 1];
  definput.keyvals.tol=1e-6;
  definput.keyvals.maxit=100;
  definput.keyvals.printstep=10;
  definput.flags.method={'griflim','bfgs'};
  definput.flags.print={'print','quiet'};
  definput.flags.startphase={'zero','rand','int'};

  [flags,kv,Ls]=ltfatarghelper({'Ls','tol','maxit'},definput,varargin);

  N=size(s,2);
  W=size(s,3);

  % Make a dummy call to test the input parameters
  Lsmallest=dgtlength(1,a,M,kv.lt);

  M2=floor(M/2)+1;

  if M2~=size(s,1)
      error('Mismatch between the specified number of channels and the size of the input coefficients.');
  end;

  L=N*a;

  if rem(L,Lsmallest)>0
      error('%s: Invalid size of coefficient array.',upper(mfilename));
  end;

  %% ----- step 3 : Determine the window

  [g,info]=gabwin(g,a,M,L,kv.lt,'callfun',upper(mfilename));

  if L<info.gl
      error('%s: Window is too long.',upper(mfilename));
  end;

  if ~isreal(g)
      error('%s: Window must be real-valued.',upper(mfilename));
  end;

  %% Actual computation

  sqrt_s=sqrt(s);

  if flags.do_zero
    % Start with a phase of zero.
    c=sqrt(s);
  end;

  if flags.do_rand
    c=sqrt_s.*exp(2*pi*1i*rand(size(s)));
  end;

  if flags.do_int
      if kv.lt(2)>1
          error(['%s: The integration initilization is not implemented for ' ...
                 'non-sep lattices.'],upper(mfilename));
      end;

    s2=zeros(M,N);
    s2(1:M2,:)=s;
    if rem(M,2)==0
      s2(M2+1:M,:)=flipud(s(2:end-1,:));
    else
      s2(M2+1:M,:)=flipud(s(2:end));
    end;
    c=constructphase(s2,g,a);
    c=c(1:M2,:);
  end;

  gd = gabdual(g,a,M);

  % For normalization purposes
  norm_s=norm(s,'fro');

  relres=zeros(kv.maxit,1);
  if flags.do_griflim
    for iter=1:kv.maxit
      f=comp_idgtreal(c,gd,a,M,kv.lt,0);
      c=comp_dgtreal(f,g,a,M,kv.lt,0);

      relres(iter)=norm(abs(c).^2-s,'fro')/norm_s;

      c=sqrt_s.*exp(1i*angle(c));

      if flags.do_print
        if mod(iter,kv.printstep)==0
          fprintf('ISGRAMREAL: Iteration %i, residual = %f.\n',iter,relres(iter));
        end;
      end;

      if relres(iter)<kv.tol
        relres=relres(1:iter);
        break;
      end;

    end;

  end;

  if flags.do_bfgs
    if exist('minFunc')~=2
      error(['To use the BFGS method in ISGRAMREAL, please install the minFunc ' ...
             'software from http://www.cs.ubc.ca/~schmidtm/Software/minFunc.html.']);
    end;

    % Setting up the options for minFunc
    opts = struct;
    opts.display = kv.printstep;
    opts.maxiter = kv.maxit;
    opts.usemex = 0;

    % Don't limit the number of function evaluations, just the number of
    % time-steps.
    opts.MaxFunEvals = 1e9;

    f0 = comp_idgtreal(c,gd,a,M,kv.lt,0);
    [f,fval,exitflag,output]=minFunc(@objfun,f0,opts,g,a,M,s,kv.lt);
    % First entry of output.trace.fval is the objective function
    % evaluated on the initial input. Skip it to be consistent.
    relres = sqrt(output.trace.fval(2:end))/norm_s;
    iter = output.iterations;
  end;

  % Cut or extend f to the correct length, if desired.
  if ~isempty(Ls)
    f=postpad(f,Ls);
  else
    Ls=L;
  end;

  f=comp_sigreshape_post(f,Ls,0,[0; W]);

%  Subfunction to compute the objective function for the BFGS method.
function [f,df]=objfun(x,g,a,M,s,lt);
  c=comp_dgtreal(x,g,a,M,lt,0);

  inner=abs(c).^2-s;
  f=norm(inner,'fro')^2;

  df=4*real(conj(comp_idgtreal(inner.*c,g,a,M,lt,0)));


function [Yl,Yh,Yscale] = dtwavexfm(X,nlevels,biort,qshift);

% Function to perform a n-level DTCWT decompostion on a 1-D column vector X
% (or on the columns of a matrix X).
%
% [Yl,Yh,Yscale] = dtwavexfm(X,nlevels,biort,qshift);
%
%     X -> real 1-D signal column vector (or matrix of vectors)
%
%     nlevels -> No. of levels of wavelet decomposition
%
%     biort ->  'antonini'   => Antonini 9,7 tap filters.
%               'legall'     => LeGall 5,3 tap filters.
%               'near_sym_a' => Near-Symmetric 5,7 tap filters.
%               'near_sym_b' => Near-Symmetric 13,19 tap filters.
%
%     qshift -> 'qshift_06' => Quarter Sample Shift Orthogonal (Q-Shift) 10,10 tap filters,
%                              (only 6,6 non-zero taps).
%               'qshift_a' =>  Q-shift 10,10 tap filters,
%                              (with 10,10 non-zero taps, unlike qshift_06).
%               'qshift_b' => Q-Shift 14,14 tap filters.
%               'qshift_c' => Q-Shift 16,16 tap filters.
%               'qshift_d' => Q-Shift 18,18 tap filters.
%
%
%     Yl     -> The real lowpass subband from the final level.
%     Yh     -> A cell array containing the complex highpass subband for each level.
%     Yscale -> This is an OPTIONAL output argument, that is a cell array containing
%               the real lowpass coefficients at every scale.
%
%
% Example: [Yl,Yh] = dtwavexfm(X,5,'near_sym_b','qshift_b');
% performs a 5-level transform on the real image X using the 13,19-tap filters
% for level 1 and the Q-shift 14-tap filters for levels >= 2.
%
% Nick Kingsbury and Cian Shaffrey
% Cambridge University, May 2002

if isstr(biort) & isstr(qshift)		%Check if the inputs are strings
   biort_exist = exist([biort '.mat']);
   qshift_exist = exist([qshift '.mat']);
   if biort_exist == 2 & qshift_exist == 2;  %Check to see if the filters exist as .mat files
      load (biort);
      load (qshift);
   else
      error('Please enter the correct names of the Biorthogonal or Q-Shift Filters, see help DTWAVEXFM for details.');
   end
else
   error('Please enter the names of the Biorthogonal or Q-Shift Filters as shown in help DTWAVEXFM.');
end

L = size(X);

if any(rem(L(1),2)),	 % ensure that X is an even length, thus enabling it to be extended if needs be.
   error('Size of X must be a multiple of 2');
end

if nlevels == 0, return; end

%initialise
Yh=cell(nlevels,1);
if nargout == 3
   Yscale=cell(nlevels,1);   % This is only required if the user specifies a third output component.
end

j = sqrt(-1);

% Level 1.
Hi = colfilter(X, h1o);
Lo = colfilter(X, h0o);
t = 1:2:size(Hi,1);
Yh{1} = Hi(t,:) + j*Hi(t+1,:); % Convert Hi to complex form.
if nargout == 3
   Yscale{1} = Lo;
end

if nlevels >= 2;  % Levels 2 and above.
   for level = 2:nlevels;
      if rem(size(Lo,1),4),	% Check to see if height of Lo is divisable by 4, if not extend.
         Lo = [Lo(1,:); Lo; Lo(end,:)];
      end
      Hi = coldfilt(Lo,h1b,h1a);
      Lo = coldfilt(Lo,h0b,h0a);
	   t = 1:2:size(Hi,1);
   	Yh{level} = Hi(t,:) + j*Hi(t+1,:); % Convert Hi to complex form.
   	if nargout == 3
      	Yscale{level} = Lo;
   	end
   end
end

Yl = Lo;

return


function guv = evaluate_log_posterior_grad(this, uv)
%EVALUATE_LOG_POSTERIOR computes the gradient of the log-posterior
%   (negative energy) wrt the flow fields UV
%   Actually only proportional to the log posterior since the variance of neither the
%   spatial nor the data terms is considered
%
%   This is a member function of the class 'ba_optical_flow'.
%
%   Author: Deqing Sun, Department of Computer Science, Brown University
%   Contact: dqsun@cs.brown.edu
%   $Date: 2007-11-30 $
%
% Copyright 2007-2010, Brown University, Providence, RI. USA
%
%                          All Rights Reserved
%
% All commercial use of this software, whether direct or indirect, is
% strictly prohibited including, without limitation, incorporation into in
% a commercial product, use in a commercial service, or production of other
% artifacts for commercial purposes.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for research purposes is hereby granted without fee,
% provided that the above copyright notice appears in all copies and that
% both that copyright notice and this permission notice appear in
% supporting documentation, and that the name of the author and Brown
% University not be used in advertising or publicity pertaining to
% distribution of the software without specific, written prior permission.
%
% For commercial uses contact the Technology Venture Office of Brown University
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO
% THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR
% BROWN UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
% DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
% PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
% ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
% THIS SOFTWARE.

% Spatial term
S       = this.spatial_filters;
gu1     = zeros(size(uv,1), size(uv,2));
gv1     = gu1;

for i = 1:length(S)

    u_ = conv2(uv(:,:,1), S{i}, 'valid');
    v_ = conv2(uv(:,:,2), S{i}, 'valid');

    Si = reshape(S{i}(end:-1:1), size(S{i}));

    if isa(this.rho_spatial_u{i}, 'robust_function')
        u_ = -reshape(deriv(this.rho_spatial_u{i}, u_(:)), size(u_));
        v_ = -reshape(deriv(this.rho_spatial_v{i}, v_(:)), size(v_));
    elseif isa(this.rho_spatial_u{i}, 'gsm_density')
        u_ = reshape(evaluate_log_grad(this.rho_spatial_u{i}, u_(:)'), size(u_));
        v_ = reshape(evaluate_log_grad(this.rho_spatial_v{i}, v_(:)'), size(v_));
    else
        error('evaluate_log_posterior: unknown rho function!');
    end;

    gu1 = gu1+conv2(u_, Si, 'full');
    gv1 = gv1+conv2(v_, Si, 'full');
end;

gu2     = zeros(size(uv,1), size(uv,2));
gv2     = gu2;

% Data term
[It Ix Iy] = partial_deriv(this.images, uv, this.interpolation_method, this.deriv_filter, this.blend);

if isa(this.rho_data, 'robust_function')
    temp   = -reshape(deriv(this.rho_data, It(:)), size(It));

elseif isa(this.rho_data, 'gsm_density')
    temp   = reshape(evaluate_log_grad(this.rho_data, It(:)'), size(It));
else
    error('evaluate_log_posterior: unknown rho function!');
end;

gu2     = temp.*Ix;
gv2     = temp.*Iy;

guv = cat(3, gu2+this.lambda*gu1, gv2+this.lambda*gv1);


% DATA
%
% Files
%   cubeafemdata     - Data of an example of AFEM in a cube
%   eddycurrentdata1 - Copyright (C) Long Chen. See COPYRIGHT.txt for details.
%   elasticitydata   - data for elasticity problem
%   fourorderdate    - data for four order problem
%   jumpdata1        - data for interface problem
%   jumpmgdata1      - Data of JUMPMG1
%   jumpmgdata2      - Data of JUMPMG1
%   Maxwelldata1     - positive definite and homogenous Neumann boundary condition
%   Maxwelldata2     - non-homogenous Dirichlet/Neumann boundary condition
%   Maxwelldata3     - polynomial data
%   Maxwelldata4     - homogenous Dirichlet boundary condition
%   Maxwelldata5     - linear polynomial data
%   mixBCdata        - mix boundary condition data for Poisson equation
%   mixBCdata3       - mix boundary condition data for Poisson equation in 3-D
%   planewavedata    - plane wave solution of Maxwell equations: complex solution
%   planewavedata1   - plane wave solution of Maxwell equations: real solution.
%   planewavedataC   - plane wave solution of Maxwell equations: real solution and complex coefficients
%   planewavedataH   - plane wave solution of Maxwell equations in terms of H
%   polydata1        - polynomial data for Poisson equation
%   polydata3        - polynomial data for Poisson equation in 3-D
%   sincosdata       - trigonometric  data for Poisson equation
%   sincosdata3      - trigonometric data for Poisson equation in 3-D
%   tensordata1      - data for interface problem


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

%%
clear; close all; clc;

%% Syntax
% |axLim=axisLim(V);|

%% Description
% This function computes appropiate axis limits for the input vertices V.
% The vertices may be an k x l x m array, where by by k is the number of
% vertices, l is the number of dimensions (e.g. 2 or 3), and m is for
% instance a time (or other) dimension. The function returs axLim which are
% appropriate axis limits such that the coordinates in V can be displayed
% appropriately (and in a tight fashion).

%% Examples

%% Example 1: setting axis limits tightly around a coordinate set in 2D

%%
% Create example data
t=linspace(0,2*pi,250)';
r=5+2*sin(5*t);
V=r.*[cos(t) sin(t)];

%%
% Compute appropriate limits
axLim=axisLim(V) %Axis limits for vertices

%%
% Assign axis limits using |axisLim|

cFigure;
plot(V(:,1),V(:,2),'b-');
axis equal; axis(axisLim(V));
drawnow;

%% Example 2: setting axis limits tightly around a coordinate set in 3D

%%
% Create example data
[F,V]=stanford_bunny;

%%
% Compute appropriate limits
axLim=axisLim(V) %Axis limits for vertices

%%
% Assign axis limits using |axisLim|

cFigure;
gpatch(F,V);
axisGeom; camlight headlight;
axis(axisLim(V));
gdrawnow;

%% Example 3: setting axis limits tightly around multiple coordinate sets in 3D

%%
% Create example data
[F1,V1]=graphicsModels(3);
[F2,V2]=graphicsModels(4);
V2=V2+1;
%%
% Compute appropriate limits
axLim=axisLim(V1,V2) %Axis limits for vertices

%%
% Assign axis limits using |axisLim|

cFigure; hold on;
gpatch(F1,V1,'gw');
gpatch(F2,V2,'rw');
axisGeom; camlight headlight;
axis(axisLim(V1,V2));
gdrawnow;

%% Example 3: setting axis limits tightly around multiple coordinate sets with varying dimensions

%%
% Create example data
V1=r.*[cos(t) sin(t)];
[F2,V2]=geoSphere(2,1);

%%
% Compute appropriate limits
axLim=axisLim(V1,V2) %Axis limits for vertices

%%
% Assign axis limits using |axisLim|

cFigure; hold on;
plot(V1(:,1),V1(:,2),'b-');
gpatch(F2,V2,'rw');
axisGeom; camlight headlight;
axis(axisLim(V1,V2));
gdrawnow;

%% Example 4: setting axis limits tightly for coordinates over time

[F,V]=stanford_bunny; %Some graphics data

nSteps=50;
t=linspace(0,pi,nSteps)';
U=[-100*t/pi zeros(nSteps,1) 50*sin(t)];

V_DEF=zeros(size(V,1),3,nSteps);
for q=1:1:nSteps
    V_DEF(:,:,q)=V+U(q*ones(size(V,1),1),:);
end

%%
% Compute appropriate limits
axLim=axisLim(V_DEF) %Axis limits for vertices

%%
% Assign axis limits using |axisLim|

hf=cFigure;
hp=gpatch(F,V,'gw');
axisGeom; camlight headlight;
axis(axisLim(V_DEF)); %Set limits to be suitable across time
drawnow;

%%
% Use |anim8| to animate the scene

animStruct.Time=linspace(0,1,nSteps); %Time vector

for q=1:1:nSteps
    %Set entries in animation structure
    animStruct.Handles{q}=hp; %Handles of objects to animate
    animStruct.Props{q}={'Vertices'}; %Properties of objects to animate
    animStruct.Set{q}={V_DEF(:,:,q)}; %Property values for to set in order to animate
end

% Start |anim8| gui
anim8(hf,animStruct);

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


function cc_grids_constrained_display ( )

%*****************************************************************************80
%
%% CC_GRIDS_CONSTRAINED_DISPLAY displays grids generated by CC_GRIDS_CONSTRAINED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 November 2006
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CC_GRIDS_CONSTRAINED_DISPLAY:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Display the 2D Clenshaw-Curtis grids\n' );
  fprintf ( 1, '  generated by CC_GRIDS_CONSTRAINED.\n' );

  dim_num = 2;

  while ( 1 )
%
%  Get user input.
%
    q_max = input ( 'Enter Q_MAX or RETURN to exit;' );

    if ( isempty ( q_max ) )
      break
    end

    if ( q_max < dim_num )
      fprintf ( 1, '\n' );
      fprintf ( 1, '  We require DIM_NUM <= Q_MAX!\n' );
      continue
    end

    alpha = input ( 'Enter [ ALPHA1, ALPHA2 ] or RETURN to exit;' );

    if ( isempty ( alpha ) )
      break
    end

    order_min = input ( 'Enter [ ORDER_MIN1, ORDER_MIN2 ] or RETURN to exit;' );

    if ( isempty ( order_min ) )
      break
    end

    order_max = input ( 'Enter [ ORDER_MAX1, ORDER_MAX2 ] or RETURN to exit;' );

    if ( isempty ( order_max ) )
      break
    end
%
%  Compute data.
%
    [ grid_num, point_num ] = cc_grids_constrained_size ( dim_num, ...
      q_max, alpha, order_min, order_max );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Number of grids is %d\n', grid_num );
    fprintf ( 1, '  Number of points is %d\n', point_num );

    [ grid_order, grid_point ] = cc_grids_constrained ( dim_num, ...
      q_max, alpha, order_min, order_max, grid_num, point_num );

    clf
%
%  We have to name the axes in order to control the grid.
%
    axes_handle = axes;
%
%  Plot the points.
%
    handle = scatter ( grid_point(1,:), grid_point(2,:), 'filled' );
%
%  Force the plotting region to be square, not rectangular.
%
    axis square
%
%  Request grid lines.
%
    grid on
%
%  Specify the location of the grid lines, and suppress labeling.
%
    set ( axes_handle, 'xtick', [ -1, -.75, -.5, -.25, 0, .25, .50, .75, 1] );
    set ( axes_handle, 'xticklabel', [] );
    set ( axes_handle, 'ytick', [ -1, -.75, -.5, -.25, 0, .25, .50, .75, 1] );
    set ( axes_handle, 'yticklabel', [] );
%
%  Make the plotting region slightly bigger than the data.
%
    axis ( [ -1.1, 1.1, -1.1, 1.1 ] )
%
%  Title
%
    s = sprintf ( '%d <= Q <= %d', q_min, q_max );
    title ( s );

  end

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

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

  return
end


%% EXAMPLE 2: Plot SPOD spectrum and inspect SPOD modes.
%  The large-eddy simulation data provided along with this example is a
%  subset of the database of a Mach 0.9 turbulent jet described in [1] and
%  was calculated using the unstructured flow solver Charles developed at
%  Cascade Technologies. If you are using the database in your research or
%  teaching, please include explicit mention of Brès et al. [1]. The test
%  database consists of 5000 snapshots of the symmetric component (m=0) of
%  a round turbulent jet. A physical interpretaion of the SPOD results is
%  given in [2], and a comprehensive discussion and derivation of SPOD and
%  many of its properties can be found in [3].
%
%   References:
%     [1] G. A. Brès, P. Jordan, M. Le Rallic, V. Jaunet, A. V. G.
%         Cavalieri, A. Towne, S. K. Lele, T. Colonius, O. T. Schmidt,
%         Importance of the nozzle-exit boundary-layer state in subsonic
%         turbulent jets, J. of Fluid Mech. 851, 83-124, 2018
%     [2] Schmidt, O. T. and Towne, A. and Rigas, G. and Colonius, T. and
%         Bres, G. A., Spectral analysis of jet turbulence, J. of Fluid Mech. 855, 953–982, 2018
%     [3] Towne, A. and Schmidt, O. T. and Colonius, T., Spectral proper
%         orthogonal decomposition and its relationship to dynamic mode
%         decomposition and resolvent analysis, J. of Fluid Mech. 847, 821–867, 2018
%
% O. T. Schmidt (oschmidt@ucsd.edu), A. Towne, T. Colonius
% Last revision: 5-Sep-2022 (OTS)

clc, clear variables
addpath('utils')
load(fullfile('jet_data','jetLES.mat'),'p','x','r','dt');

%% SPOD of the test database.
%   Calculate the SPOD of the data matrix 'p' and use the timestep 'dt'
%   between snapshots to obtain the physical frequency 'f'. 'L' is the
%   matrix of modal energies, as before, and 'P' the data matrix of SPOD
%   modes. We leave all other options empty for now.
[L,P,f] = spod(p,[],[],[],dt);

%   First, we plot the SPOD spectrum.
figure
loglog(f,L)
xlabel('frequency'), ylabel('SPOD mode energy')

%   Second, we visualize the 1st and 2nd SPOD modes at three frequencies.
figure
count = 1;
for fi = [10 15 20]
    for mi = [1 2]
        subplot(3,2,count)
        contourf(x,r,real(squeeze(P(fi,:,:,mi))),11,'edgecolor','none'), axis equal tight, caxis(max(abs(caxis))*[-1 1])
        xlabel('x'), ylabel('r'), title(['f=' num2str(f(fi),'%.2f') ', mode ' num2str(mi) ', \lambda=' num2str(L(fi,mi),'%.2g')])
        xlim([0 10]); ylim([0 2])
        count = count + 1;
    end
end

%% Animate the same modes.
%   Note how all wavepackets travel at approximately the same phase
%   speed c_ph. The reason is that their streamwise wavenumber k_x changes
%   with frequency such that c_ph = omega/k_x is approximately constant.
figure
nt      = 30;
T       = 1/f(10);              % period of the 10th frequency
time    = linspace(0,T,nt);     % animate over one period
count = 1;
for ti = 1:nt
    for fi = [10 15 20]
        for mi = [1 2]
            subplot(3,2,count)
            pcolor(x,r,real(squeeze(P(fi,:,:,mi)*exp(2i*pi*f(fi)*time(ti))))), shading interp, axis equal tight, caxis(max(abs(caxis))*[-1 1])
            xlabel('x'), ylabel('r'), title(['f=' num2str(f(fi),'%.2f') ', mode ' num2str(mi) ', \lambda=' num2str(L(fi,mi),'%.2g')])
            xlim([0 10]); ylim([0 2])
            count = count + 1;
            hold on
        end
    end
    drawnow
    hold off
    count = 1;
end


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

%% Syntax
% |[Fs,Vs]=subtri(F,V,n,uniqueOpt);|

%% Description
% The |subtri| function enables refinement of triangulated data

%% Examples

clear; close all; clc;

%%
% Plot Settings
fontSize=15;
faceAlpha=1;
edgeColor=0.2*ones(1,3);
edgeWidth=1.5;
markerSize=35;
markerSize2=20;

%% Refining a triangle

V=[0 0 0; 1 0 0; 0.5 sqrt(3)/2 0];
F=[1 2 3];

n=0:1:3; %Number of added edge nodes
pColors=gjet(numel(n));

cFigure;
for q=1:1:numel(n)
    [Fs,Vs]=subtri(F,V,n(q));
    subplot(2,2,q); hold on;
    title([num2str(n(q)),' added edge nodes'],'FontSize',fontSize);
    gpatch(Fs,Vs,pColors(q,:),'k');
    plotV(Vs,'k.','markerSize',markerSize2);
    plotV(V,'k.','markerSize',markerSize);

    axis equal; axis tight; view(2);
end
drawnow;

%% Refining a tetrahedron

[V,F]=platonic_solid(1,1);

n=0:1:3; %Number of added edge nodes
pColors=gjet(numel(n));

cFigure;
for q=1:1:numel(n)
    [Fs,Vs]=subtri(F,V,n(q));
    subplot(2,2,q); hold on;
    title([num2str(n(q)),' added edge nodes'],'FontSize',fontSize);
    gpatch(Fs,Vs,pColors(q,:),'k');
    plotV(Vs,'k.','markerSize',markerSize2);
    plotV(V,'k.','markerSize',markerSize);
    axisGeom(gca,fontSize);
    camlight headlight;
end
drawnow;

%% Refining triangulated surfaces in general

[F,V]=geoSphere(1,1);

n=[0 1 2 3]; %Number of added edge nodes
pColors=gjet(numel(n));

cFigure;
for q=1:1:numel(n)
    [Fs,Vs]=subtri(F,V,n(q));
    subplot(2,2,q); hold on;
    title([num2str(n(q)),' added edge nodes'],'FontSize',fontSize);
    gpatch(Fs,Vs,pColors(q,:),'k');
    axisGeom(gca,fontSize);
    camlight headlight;
end
drawnow;

%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>

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


function determ = neumann_determinant ( row_num, col_num )

%*****************************************************************************80
%
%% NEUMANN_DETERMINANT returns the determinant of the NEUMANN matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer ROW_NUM, COL_NUM, the number of rows and columns in the grid.
%
%    Output, real DETERM, the determinant.
%
  determ = 0.0;

  return
end


% NANMAX Maximum value, ignoring NaNs.
%    M = NANMAX(A) returns the maximum of A with NaNs treated as missing.
%    For vectors, M is the largest non-NaN element in A.  For matrices, M is
%    a row vector containing the maximum non-NaN element from each column.
%    For N-D arrays, NANMAX operates along the first non-singleton
%    dimension.
%
%    [M,NDX] = NANMAX(A) returns the indices of the maximum values in A.  If
%    the values along the first non-singleton dimension contain more than
%    one maximal element, the index of the first one is returned.
%
%    M = NANMAX(A,B) returns an array the same size as A and B with the
%    largest elements taken from A or B.  Either one can be a scalar.
%
%    [M,NDX] = NANMAX(A,[],DIM) operates along the dimension DIM.
%
%    See also MAX, NANMIN, NANMEAN, NANMEDIAN, NANMIN, NANVAR, NANSTD.
%
%    Reference page in Doc Center
%       doc stats/nanmax
%
%    Other functions named nanmax
%
%       distributed/nanmax    fints/nanmax
%


function [ y, symm ] = cvx_s_upper_hankel( m, n, symm )

% CVX_S_UPPER_HANKEL Upper Hankel matrices.

c  = 0 : n - 1;
c  = c( ones( 1, m ), : );
r  = ( 0 : m - 1 )';
r  = r( :, ones( 1, n ) );
v  = abs( r + c ) + 1;
temp = v <= min( m, n );
y = sparse( v( temp ), r( temp ) + m * c( temp ) + 1, 1, min( m, n ), m * n );
symm = false;

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


% most of the time. they both this and pcasvd takes about the same time
% when smallest = 0, this should be faster but it's not always
% when it's 1, due to null(U1'), it prob slows it down but not always
function [U,d] = pcaeig(X,n,smallest)
% X : nt x n, where nt examples of feature vecs of size n
% n returns n dimensions
% smallest = 1 when we want the n evecs assoc with the smallest
% evals
% U is evecs, d is diagonals
% Copyright (c) 2013, Vipin Vijayan.
if size(X,1) < size(X,2)
    [U,D] = eig(X*X');
    d = diag(D);
    [~,ix] = sort(d,'descend');
    U = U(:,ix);
    d = d(ix);
else
    [V,D1] = eig(X'*X);
    d1 = diag(D1);
    [~,ix] = sort(d1,'descend');
    V = V(:,ix);
    d1 = d1(ix);
    U1 = X*V; % go from evecs of X'*X to evecs of X*X'
    for ni = 1:size(U1,2), U1(:,ni) = U1(:,ni)./norm(U1(:,ni)); end
    if ~smallest
        U = U1;
        d = d1;
    else
        U2 = null(U1'); % this runs svd on U1'
        U = [U1 U2];
        d = [d1 ; zeros(size(U2,2),1)];
    end
end
if ~smallest,
    tol = eps(class(X));
    n = min(n, sum(d > tol));
    U = U(:,1:n);
    d = d(1:n);
else
    n = min(n,size(U,2));
    U = U(:,end:-1:end-n+1);
    d = max(0,d);
    d = d(end:-1:end-n+1);
end
% D = diag(d);
end

% very slow with large dimensions
function [U,d] = pcaeigslow(X,n,smallest)
[U,D] = eig(X*X');
d = diag(D);
[~,ix] = sort(d,'descend');
U = U(:,ix);
d = d(ix);
if ~smallest,
    tol = eps(class(X));
    n = min(n, sum(diag(D) > tol));
    U = U(:,1:n);
    d = d(1:n);
else
    n = min(n,size(U,2));
    U = U(:,end:-1:end-n+1);
    d = abs(diag(D));
    d = d(end:-1:end-n+1);
end
% D = diag(d);
end


function g = mlpderiv(net, x)
%MLPDERIV Evaluate derivatives of network outputs with respect to weights.
%
%	Description
%	G = MLPDERIV(NET, X) takes a network data structure NET and a matrix
%	of input vectors X and returns a three-index matrix G whose I, J, K
%	element contains the derivative of network output K with respect to
%	weight or bias parameter J for input pattern I. The ordering of the
%	weight and bias parameters is defined by MLPUNPAK.
%
%	See also
%	MLP, MLPPAK, MLPGRAD, MLPBKP
%

%	Copyright (c) Ian T Nabney (1996-2001)

% Check arguments for consistency
errstring = consist(net, 'mlp', x);
if ~isempty(errstring);
  error(errstring);
end

[y, z] = mlpfwd(net, x);

ndata = size(x, 1);

if isfield(net, 'mask')
  nwts = size(find(net.mask), 1);
  temp = zeros(1, net.nwts);
else
  nwts = net.nwts;
end

g = zeros(ndata, nwts, net.nout);
for k = 1 : net.nout
  delta = zeros(1, net.nout);
  delta(1, k) = 1;
  for n = 1 : ndata
    if isfield(net, 'mask')
      temp = mlpbkp(net, x(n, :), z(n, :), delta);
      g(n, :, k) = temp(logical(net.mask));
    else
      g(n, :, k) = mlpbkp(net, x(n, :), z(n, :),...
	delta);
    end
  end
end


classdef CF8 < PROBLEM
% <multi> <real> <large/none> <constrained>
% Constrained benchmark MOP

%------------------------------- Reference --------------------------------
% Q. Zhang, A. Zhou, S. Zhao, P. N. Suganthan, W. Liu, and S. Tiwari,
% Multiobjective optimization test instances for the CEC 2009 special
% session and competition, School of CS & EE, University of Essex, Working
% Report CES-487, 2009.
%------------------------------- 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
        %% Default settings of the problem
        function Setting(obj)
            obj.M = 3;
            if isempty(obj.D); obj.D = 10; end
            obj.lower    = [0,0,zeros(1,obj.D-2)-4];
            obj.upper    = [1,1,zeros(1,obj.D-2)+4];
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values and constraint violations
        function Population = Evaluation(obj,varargin)
            X  = varargin{1};
            X  = max(min(X,repmat(obj.upper,size(X,1),1)),repmat(obj.lower,size(X,1),1));
            D  = size(X,2);
            J1 = 4 : 3 : D;
            J2 = 5 : 3 : D;
            J3 = 3 : 3 : D;
            Y  = X - 2*repmat(X(:,2),1,D).*sin(2*pi*repmat(X(:,1),1,D)+repmat(1:D,size(X,1),1)*pi/D);
            PopObj(:,1) = cos(0.5*X(:,1)*pi).*cos(0.5*X(:,2)*pi) + 2*mean(Y(:,J1).^2,2);
            PopObj(:,2) = cos(0.5*X(:,1)*pi).*sin(0.5*X(:,2)*pi) + 2*mean(Y(:,J2).^2,2);
            PopObj(:,3) = sin(0.5*X(:,1)*pi)                     + 2*mean(Y(:,J3).^2,2);
            PopCon      = 1 - (PopObj(:,1).^2+PopObj(:,2).^2)./(1-PopObj(:,3).^2) + 4*abs(sin(2*pi*((PopObj(:,1).^2-PopObj(:,2).^2)./(1-PopObj(:,3).^2)+1)));
            Population  = SOLUTION(X,PopObj,PopCon,varargin{2:end});
            obj.FE      = obj.FE + length(Population);
        end
        %% Generate points on the Pareto front
        function R = GetOptimum(obj,N)
            N      = ceil(N/5)*5;
            R      = zeros(N,3);
            R(:,3) = repmat(sin((0:1/(N/5-1):1).*pi/2)',5,1);
            for i = 0 : 4
                R(i*N/5+1:(i+1)*N/5,1) = sqrt(i/4*(1-R(i*N/5+1:(i+1)*N/5,3).^2));
            end
            R(:,2) = sqrt(max(1-R(:,1).^2-R(:,3).^2,0));
        end
    end
end


%  INTERNAL FUNCTION: doubling_solve solves the linear equation X=A*X*B+C using doubling algorithm
%
%  ::
%
%     [P,retcode]=doubling(A,B,C);
%
%


function [network, mappedX, reconX] = train_autoencoder(X, layers, noise, max_iter)
%TRAIN_AUTOENCODER Trains an simple autoencoder
%
%   [network, mappedX, reconX] = train_encoder(X, layers, noise, max_iter)
%
% Trains up an autoencoder with the structure that is specified in layers.
% The low-dimensional data is returned in mappedX, and the network in
% network. The variable noise indicates how much of the input data should be
% blacked out (default = 0).
%
%

% This file is part of the Matlab Toolbox for Dimensionality Reduction.
% The toolbox can be obtained from http://homepage.tudelft.nl/19j49
% You are free to use, change, or redistribute this code in any way you
% want for non-commercial purposes. However, it is appreciated if you
% maintain the name of the original author.
%
% (C) Laurens van der Maaten, Delft University of Technology

    if nargin < 2
        error('Not enough inputs.');
    end
    if isempty(layers)
        error('There should be at least one hidden layer.');
    end
    if ~exist('noise', 'var') || isempty(noise)
        noise = 0;
    end
    if ~exist('max_iter', 'var') || isempty(max_iter)
        max_iter = 50;
    end

    % Initialize the network
    D = size(X, 2);
    no_layers = length(layers) + 1;
    network = cell(no_layers, 1);
    network{1}.W = randn(D, layers(1)) * .0001;
    network{1}.bias_upW = zeros(1, layers(1));
    for i=2:no_layers - 1
        network{i}.W = randn(layers(i - 1), layers(i)) * .0001;
        network{i}.bias_upW = zeros(1, layers(i));
    end
    network{no_layers}.W = randn(layers(end), D) * .0001;
    network{no_layers}.bias_upW = zeros(1, D);
    reconX = run_data_through_autoenc(network, X);
    disp(['Initial MSE of reconstructions: ' num2str(mean((X(:) - reconX(:)) .^ 2))]);

    % Perform backpropagation to minimize reconstruction error
    network = backprop(network, X, X, max_iter, noise);

    % Get representation from hidden layer
    [reconX, mappedX] = run_data_through_autoenc(network, X);
    disp(['Final MSE of reconstructions: ' num2str(mean((X(:) - reconX(:)) .^ 2))]);


%%
% Auther : Gaul Swapnil Narhari,
% Developed @ IIT Kharagpur, India.
% In collaborationwith TaraNG, India.
%%
% for optimization see 'pso.m' file for fitness function defination see 'simple_fitness.m'
%%
clc;
clear all;
ObjectiveFunction = @simple_fitness;
nvars = 3;    % Number of variables
LB = [0 0 0];   % Lower bound
UB = [3 5 10];  % Upper bound
Popln=20;
Genrtn=50;
WByn=1;
[x,fvalue] = pso(ObjectiveFunction,'NumVar',nvars,'LowerBound',LB,'UpperBound',UB,'Population',Popln,'Genrations',Genrtn,'IncludeWB',WByn);
disp(x);
disp(fvalue);


function test11
%TEST11 test cs_rowcnt
%
% Example:
%   test11
% See also: testall

%   Copyright 2006-2007, Timothy A. Davis.
%   http://www.cise.ufl.edu/research/sparse

clear functions
index = UFget ;
[ignore f] = sort (max (index.nrows, index.ncols)) ;
f = f (1:200) ;

for i = f
    Prob = UFget (i, index) ;
    disp (Prob) ;
    A = Prob.A ;
    [m n] = size (A) ;
    if (~isreal (A) | m ~= n)                                               %#ok
        continue
    end

    A = spones (A) ;
    A = A+A' + speye(n) ;

    [cc h pa po R] = symbfact (A) ;
    rc1 = full (sum (R)) ;
    rc2 = cs_rowcnt (A, pa, po) ;
    if (any (rc1 ~= rc2))
        error ('!') ;
    end

    try
        p = amd (A) ;
    catch
        p = symamd (A) ;
    end
    A = A (p,p) ;

    [cc h pa po R] = symbfact (A) ;
    rc1 = full (sum (R)) ;
    rc2 = cs_rowcnt (A, pa, po) ;
    if (any (rc1 ~= rc2))
        error ('!') ;
    end

end


function [coeff,RMSout]=FitLaw_GA(X,y,fh,Int,LB,UB)
%
% function [coeff,RMSout]=FitLaw_GA(X,y,fh,Int,LB,UB)
%
% The script fits a given general analytical law using Genetic Algorithms.
% Such law can depend on several input variables and various parameters,
% but it must have only one output, to be matched to the input variable y.
% The optimum coefficients are derived using an optimization based on the
% Genetic Algorithm.
%
% INPUT
%   X = matrix containing the values of the indipendent variables of the
%       function. Each column refers to a variable
%   y = target values to be matched by the function (row vector)
%   fh = handle of the function to be fitted to y and whose parameters have
%        to be optimized
%   Int = initial interval of the parameters to be optmized. Column i of
%         the matrix refer to parameter i
%   LB,UB = vectors defining the lower and upper bounds never to be
%           exceeded by the parameters. Position i of the vectors refer to
%           parameter i.
%
% OUTPUT
%   coeff = parameters providing the best fitting
%   RMSout = lowest RMS of the fitting error
%
% EXAMPLE OF USAGE
%   Suppose one wants to fit to y the function p=x.*(1-exp(-a.*w+b.*z)),
%   where (x,w,z) are the indipendent variables and (a,b) are the
%   parameters to be determined. It is first necessary to define the handle
%   to the function p before calling the optimization function. This is
%   done as follows:
%
%      fh=@(X,par) X(:,1)'.*(1-exp(-par(1).*X(:,2)'+par(2).*X(:,3)'))
%
%   Afterwards, the callback of the function would be:
%
%   [coeff,RMSout]=FitLaw_GA([x' w' z'],y,fh,[-5 -5; 5 5],[-10 10],[10 10])
%
%   Note that since fh has been defined considering that each variable is
%   assigned to each column of the matrix X, then X in the callback has to
%   be in such form (as in the example). y is a row vector containing the
%   target values of the function to be fitted. [-5 -5; 5 5] defines the
%   initial intervals in which the parameters are sampled when the
%   algorithm starts. Specifically, column i of the matrix Int contains the
%   lower and upper limits for parameter i. However, as the algorithm
%   proceeds, the parameters may exceed such intervals. That is why lower
%   and upper bounds can be introduced to limit the acceptable values of
%   the parameters (in this example, both paramaters are such that
%   -10 < a,b < 10).
%
%   To improve the fitting power, increase the variables PopSize and Iter
%   defined below in the cell GENETIC ALGORITHM OPTIONS. Specifically,
%   a high value of PopSize provides a higher probability to avoid local
%   minima in the optimization procedure, while a high value of Iter
%   permits a proper convergence of the algorithm.
%   Obviously, high values of those variables imply longer calculation
%   times.
%
% By: L.Luini

%% GENETIC ALGORITHM OPTIONS
PopSize=200;   % population size (default==200)
Iter=100;   % number of iterations of the algorithm (default==100)
MigrInt=Iter/10;   % migration interval
Fig=1;   % if Fig==1, plot optimization results

%% RUN THE GENETIC ALGORITHM
numPar=size(Int,2);
options=gaoptimset('PlotFcns',{@gaplotbestf,@gaplotbestindiv}, ...
    'PopInitRange',Int, ...
    'PopulationSize',PopSize,'MigrationInterval',MigrInt, ...
    'StallGenLimit',Inf,'StallTimeLimit',Inf,'Generations',Iter);
coeff=ga(@FitFcn,numPar,[],[],[],[],LB,UB,[],options);
est=fh(X,coeff);
error=100.*(est-y)./y;
RMSout=sqrt(mean(error).^2+std(error).^2);

% plot results if the function depends only on 1 variable
if Fig==1&&numPar==1
    figure
    plot(X,y,'b','LineWidth',1.5)
    hold on;grid on;
    plot(X,est,'r','LineWidth',1.5)
    legend('Input data','Fitting curve')
    grid
end

    function fitness=FitFcn(param)

        % Fitness function definition: RMS of the error
        est=fh(X,param);
        error=100.*(est-y)./y;   % definition of the error
        fitness=sqrt(mean(error).^2+std(error).^2);
    end

end


% Copyright (C) 2007 Peter Carbonetto. All Rights Reserved.
% This code is published under the Eclipse Public License.
%
% Author: Peter Carbonetto
%         Dept. of Computer Science
%         University of British Columbia
%         May 19, 2007

function [dR, dS] = computeJGGradient (qR, qS, auxdata)
  [K C f Rv Rf Sv Sf NS d] = deal(auxdata{:});

  nr = length(Rv);   % The number of large regions.
  ns = length(Sv);   % The number of small regions.

  % Reshape the input vectors.
  qR = reshapemarginals(qR,Rv,K);
  qS = reshapemarginals(qS,Sv,K);

  % Compute the gradient terms for the large regions. Repeat for each
  % large region.
  dR = cell(1,nr);
  for r = 1:nr
    is    = Rv{r};  % The variable nodes in the large region.
    table = 1 ./ qR{r};

    % Multiply the table by all the factors in the large region.
    for j = Rf{r}
      table = multiplyfactors(table,is,f{j},C{j});
    end

    dR{r} = -log(table) + 1;
  end

  % Compute the gradient terms for the small regions. Repeat for each
  % small region.
  dS = cell(1,ns);
  for s = 1:ns
    is    = Sv{s};  % The variable nodes in the small region.
    table = 1 ./ qS{s};

    % Multiply the table by all the factors in the small region.
    for j = Sf{s}
      table = multiplyfactors(table,is,f{j},C{j});
    end

    dS{s} = (1 - d(s)) * (-log(table) + 1);
  end

  % Convert the computed gradients into vectors.
  dR = vectorize(dR);
  dS = vectorize(dS);


function  varargout = partitionData(Ndata, varargin)
% PARTITIONDATA Partition a vector of indices into random sets
% [a,b,c,...] = partitionData(N, 0.3, 0.2, 0.5, ...)
%
% Examples:
% [a,b,c]=partitionData(105,0.3,0.2,0.5);
% a= 1:30, b=32:52, c=52:105 (last bin gets all the left over)

Npartitions = length(varargin);
perm = randperm(Ndata);
%perm = 1:Ndata;
ndx = 1;
for i=1:Npartitions
  pc(i) = varargin{i};
  Nbin(i) = fix(Ndata*pc(i));
  low(i) = ndx;
  if i==Npartitions
    high(i) = Ndata;
  else
    high(i) = low(i)+Nbin(i)-1;
  end
  varargout{i} = perm(low(i):high(i));
  ndx = ndx+Nbin(i);
end


function value = year_is_leap_bahai ( y )

%*****************************************************************************80
%
%% YEAR_IS_LEAP_BAHAI returns TRUE if the Bahai year was a leap year.
%
%  Discussion:
%
%    The leap year rules are the same as those used in the Gregorian
%    calendar.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 September 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, the year to be checked.
%
%    Output, logical VALUE, TRUE if the year was a leap year,
%    FALSE otherwise.
%
  if ( y <= 0 )
    value = 0;
    return
  end

  if ( mod ( y, 400 ) == 0 )
    value = 1;
  elseif ( mod ( y, 100 ) == 0 )
    value = 0;
  elseif ( mod ( y, 4 ) == 0 )
    value = 1;
  else
    value = 0;
  end

  return
end


classdef Derivative < Algorithm

    properties (Access = public)
        order = 1;
        delta = 1;
        inPlaceComputation = true;
    end

    methods (Access = public)
        function obj = Derivative(order, delta)
            if nargin > 0
                obj.order = order;
                if nargin > 1
                    obj.delta = delta;
                end
            end
            obj.name = 'derivative';
            obj.inputPort = DataType.kSignal;
            obj.outputPort = DataType.kSignal;
        end

        function derivative = compute(obj, data)
            if size(data,1) == 1
                derivative = data;
            else
                if obj.order == 1
                    derivative = obj.computeFirstOrderDerivative(data);
                elseif obj.order == 2
                    derivative = obj.computeSecondOrderDerivative(data);
                else
                    derivative = [];
                end
            end
        end

        function derivative = computeFirstOrderDerivative(obj,data)
            n = length(data);
            derivative = zeros(n,1);
            for i = 2 : n
                derivative(i) = (data(i) - data(i-1)) / obj.delta;
            end
        end

        function derivative = computeSecondOrderDerivative(obj,data)
            n = length(data);
            derivative = zeros(n,1);

            derivative(1) = (data(2) - data(1)) / obj.delta;
            derivative(n) = (data(n) - data(n-1)) / obj.delta;

            deltaSquared = obj.delta * obj.delta;
            for i = 2 : n-1
                derivative(i) = (data(i-1) - data(i) + data(i+1)) / deltaSquared;
            end
        end

        function str = toString(obj)
            str = sprintf('%s_%d_%.2f',obj.name,obj.order,obj.delta);
        end

        function editableProperties = getEditableProperties(obj)
            property1 = Property('order',obj.order,1,2);
            property2 = Property('delta',obj.delta);
            editableProperties = [property1,property2];
        end

        function metrics = computeMetrics(obj,input)
            n = size(input,1);
            flops = 6 * obj.order * size(input,1);
            if obj.inPlaceComputation
                memory = 1;
            else
                memory = n * Constants.kSensorDataBytes;
            end
            outputSize = n * Constants.kSensorDataBytes;
            metrics = Metric(flops,memory,outputSize);
        end
    end
end


classdef Norm_DCF_Plot < handle
% This class is for plotting normalized DCF curves from the
% scores of a given detector, as a function of the effective target
% prior. The DCF is parametrized by the prior and has unity cost
% for both misses and false alarms. The algorithms to compute DCF
% have been optimized to allow the use of large score sets, in
% order to be able to obtain meaningful results at extreme
% operating points.
%
% There are six curves that can be plotted:
% (i) minimum DCF, where the evaluator chooses the optimal decision
%     threshold at every operating point. (The operating point is defined
%     by the effective target prior).
% (ii) actual DCF, where the decision threshold is the
%      minimum-probability-of-error Bayes decision threshold, assuming that
%      the given detector scores are log-likelihood-ratios. This decision
%      threshold is just -logit(Ptar).
% (iii) actual misses, the component of actual DCF due to miss errors.
% (iv) actual false alarms, the component of actual DCF due to false-alarm errors.
% (v) minimum misses, the component of minimum DCF due to miss errors.
% (vi) miniumu false alarms, the component of minimum DCF due to false-alarm errors.
%
% All curves are normalized by dividing by the DCF of the default system
% that makes decisions based on the prior alone. The normalization is
% min(Ptar,1-Ptar).
%
% The x-axis is logit(Ptar) = log(Ptar) - log(1-Ptar). The logit
% transformation maps the effective target prior to the whole
% extended real line from -inf to inf, but this plot is confined to
% the given limits xmin and xmax.
%
% For more information on DCF, type:
% > help fast_actDCF
% > help fast_minDCF
%
% Use set_system with the target and non-target scores for a system
% before calling the plotting functions.  The curves plotted will
% all be for the current set system.  Curves for more than one
% system can be plotted by calling set_system for the first system,
% plotting all of its curves and points of interest, calling
% set_system for the second system, plotting, etc.
%
% Inputs:
%    plot_axes: [xmin,xmax,ymin,ymax]: the range for the x-axis and
%      y-axis of this plot, where x = logit(Ptar).
%
%    plot_title: An optional title string for the plot.
%

properties (Access = private)
  fh
  plot_axes
  sys_name
  plo
  actDCF
  actPmiss
  actPfa
  minDCF
  minPmiss
  minPfa
  dr30Miss
  dr30FA
  Ptar_norm
  Pnon_norm
  handles_vec
  legend_strings = {};
end

methods (Access = public)
  set_system(plot_obj,tar,non,sys_name)
  set_system_from_scores(plot_obj,scores,key,sys_name)
  plot_fa_rate_min(plot_obj,plot_args,legend_string)
  plot_fa_rate_act(plot_obj,plot_args,legend_string)
  plot_miss_rate_min(plot_obj,plot_args,legend_string)
  plot_miss_rate_act(plot_obj,plot_args,legend_string)
  plot_dcf_curve_min(plot_obj,plot_args,legend_string)
  plot_dcf_curve_act(plot_obj,plot_args,legend_string)
  plot_DR30_fa(plot_obj,plot_args,legend_string)
  plot_DR30_miss(plot_obj,plot_args,legend_string)
  plot_DR30_both(plot_obj,plot_args_fa,plot_args_miss)
  plot_curves(plot_obj,mask,line_info)
  plot_operating_point(plot_obj,value,plot_args,legend_string)
  display_legend(plot_obj)
  save_as_pdf(plot_obj,outfilename)
end

methods (Access = public)
  % plot_obj = Norm_DCF_Plot()
  % plot_obj = Norm_DCF_Plot(plot_axes)
  % plot_obj = Norm_DCF_Plot(plot_axes,plot_title)
  function plot_obj = Norm_DCF_Plot(plot_axes,plot_title)
  % constructor
  if exist('plot_axes','var') && ~isempty(plot_axes)
    assert(length(plot_axes)==4)
    plot_obj.plot_axes = plot_axes;
  else
    plot_obj.plot_axes = [-10,0,0,1.2];
  end
  xmin = plot_obj.plot_axes(1);
  xmax = plot_obj.plot_axes(2);
  assert(xmin<xmax,'Illegal parameters xmin and xmax.')
  step = (xmax-xmin)/1000;
  plot_obj.plo = xmin:step:xmax;
  Ptar = sigmoid(plot_obj.plo);
  Pnon = sigmoid(-plot_obj.plo);
  refPe = min(Ptar,Pnon);
  plot_obj.Ptar_norm = Ptar ./ refPe;
  plot_obj.Pnon_norm = Pnon ./ refPe;
  plot_obj.actDCF = [];
  plot_obj.handles_vec = [];
  plot_obj.legend_strings = {};

  plot_obj.fh = figure();
  hold on
  ylabel('normalized DCF');
  xlabel('logit P_{tar}');
  grid
  axis(plot_obj.plot_axes);
  if exist('plot_title','var') && ~isempty(plot_title)
    title(plot_title);
  end
  end
end

methods (Access = private)
  add_legend_entry(plot_obj,lh,legend_string,append_name)
  plot_miss_rate(plot_obj,Pmiss,plot_args,legend_string)
  plot_fa_rate(plot_obj,Pfa,plot_args,legend_string)
  plot_dcf_curve(plot_obj,dcf,plot_args,legend_string)
end

end


function [col,bol,msz] = spm_MB_col(n)
% FORMAT [col,bol,msz] = spm_MB_col(n)
% Return colours and marker size for number of partitions
% n  - number of partitions
%__________________________________________________________________________
% Copyright (C) 2019-2020 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_MB_col.m 7768 2020-01-07 11:37:19Z spm $

% Marker colour and size
%--------------------------------------------------------------------------
s = rand('twister');
rand('twister',1);
msz   = fix(16 + 64/n);
for k = 1:n
    bol{k} = spm_softmax(log(rand(3,1))*2);
    col{k} = bol{k}*(1 - 1/2) + ones(3,1)/2;
end
rand('twister',s);


function [k, sk, n2] = rbfperiodic2KernCompute(kern, x, x2)

% RBFPERIODIC2KERNCOMPUTE Compute the RBFPERIODIC2 kernel given the parameters and X.
% FORMAT
% DESC computes the kernel parameters for the RBF periodic covariance with variying period
% kernel given inputs associated with rows and columns.
% ARG kern : the kernel structure for which the matrix is computed.
% ARG x : the input matrix associated with the rows of the kernel.
% ARG x2 : the input matrix associated with the columns of the kernel.
% RETURN k : the kernel matrix computed at the given points.
%
% FORMAT
% DESC computes the kernel matrix for the RBF periodic covariance with variying period
% kernel given a design matrix of inputs.
% ARG kern : the kernel structure for which the matrix is computed.
% ARG x : input data matrix in the form of a design matrix.
% RETURN k : the kernel matrix computed at the given points.
%
% SEEALSO : rbfperiodic2KernParamInit, kernCompute, kernCreate, rbfperiodic2KernDiagCompute
%
% COPYRIGHT : Neil D. Lawrence, 2007, 2009
%
% MODIFICATIONS : Andreas C. Damianou, 2011
%
% MODIFICATIONS : Michalis K. Titsias, 2011

% KERN

factor = kern.factor; % Default (if period is fixed: 2*pi/kern.period)
if nargin < 3
  n2 = sin(0.5*factor*(repmat(x, 1, size(x, 1)) - repmat(x', size(x, 1), 1)));
  n2 = n2.*n2;
  wi2 = (2 .* kern.inverseWidth);
  sk = exp(-n2*wi2);
else
  n2 = sin(0.5*factor*(repmat(x, 1, size(x2, 1)) - repmat(x2', size(x, 1), 1)));
  n2 = n2.*n2;
  wi2 = (2 .* kern.inverseWidth);
  sk = exp(-n2*wi2);
end
k = kern.variance*sk;
% Test kernel with: kernTest('rbfperiodic2',1)


function [X, R, S] = snapshot_gen_sym(design, doas, wavelength, stype, t, ncov, sp)
%SNAPSHOT_GEN_SYM Generates snapshots from symbols.
%Syntax:
%   X = SNAPSHOT_GEN_SYM(design, doas, wavelength, stype[, t, ncov, sp]);
%   [X, R] = SNAPSHOT_GEN_SYM(design, doas, wavelength, stype[, t, ncov, sp]);
%   [X, R, S] = SNAPSHOT_GEN_SYM(design, doas, wavelength, stype[, t, ncov, sp]);
%Inputs:
%   design - Array design.
%   doas - DOA vector. For 2D DOAs, each column represents a DOA pair.
%   wavelength - Wavelength.
%   stype - Symbol type.
%   t - Number of snapshots.
%   ncov - Covariance matrix of the additive complex circular-symmetric
%          Gaussian noise. Can be a scalar, vector (for uncorrelated noise
%          with different powers), or a matrix.
%   sp - Sources powers.
%Outputs:
%   X - Snapshots, where each columns is a single snapshot.
%   R - Sample covariance matrix (averaged by the number of snapshots).
%   S - A source_count x snapshot_count matrix consists of source signal
%       vectors.
if nargin <= 6
    sp = 1;
end
if nargin <= 5
    ncov = 1;
end
if nargin <= 4
    t = 1;
end
A = steering_matrix(design, wavelength, doas);
[m, k] = size(A);
S_internal = gen_symbols(k, t, stype, sp);
X = A * S_internal + gen_ccsg(m, t, ncov);
if nargout >= 2
    R = (X*X')/t;
    if nargout == 3
        S = S_internal;
    end
end
end

function S = gen_symbols(m, n, stype, sp)
switch lower(stype)
    case 'bpsk'
        symbols = [-1 1];
    case 'qpsk'
        symbols = exp(1j*[1 3 5 7]/4*pi);
    otherwise
        error('Unsupported symbol type.')
end
S = symbols(randi([1 length(symbols)], m, n));
if isscalar(sp)
    S = sqrt(sp) * S;
else
    S = bsxfun(@times, sqrt(sp(:)), S);
end
end

function X = gen_ccsg(m, n, cov)
X0 = randn(m, n) + 1j * randn(m, n);
if isscalar(cov)
    X = sqrt(cov/2) * X0;
elseif isvector(cov)
    X = bsxfun(@times, X0, cov(:));
else
    C = sqrtm(cov/2);
    X = C*X0;
end
end


function [u, erriter, i, timet] = CMF_Cut
%
%   Performing the continuous max-flow algorithm to solve the
%   continuous min-cut problem in 2D
%
%   Usage: [u, erriter, i, timet] = CMF_Cut;
%
%   Inputs: there is no input since all data and parameters can be
%           adjusted within the program
%
%   Outputs:
%       - u: the final results u(x) in [0,1]. As the following paper,
%           the global binary result can be available by threshholding u
%           by any constant alpha in (0,1):
%
%           Nikolova, M.; Esedoglu, S.; Chan, T. F.
%           Algorithms for Finding Global Minimizers of Image Segmentation and Denoising Models
%           SIAM J. App. Math., 2006, 66, 1632-1648
%
%       - erriter: it returns the error evaluation of each iteration,
%           i.e. it shows the convergence rate. One can check the algorithm
%           performance.
%
%       - i: gives the total number of iterations, when the algorithm converges.
%
%       - timet: gives the total computation time.
%
%   Example:
%       >> [u, erriter, i, timet] = CMF_Cut;
%
%       >> us = max(u, beta);  % where beta in (0,1)
%
%       >> imagesc(us), colormap gray, axis image, axis off;figure(gcf)
%
%       >> figure, loglog(erriter,'DisplayName','erriterN');figure(gcf)
%
%
%
%   The original algorithm was proposed in the following papers:
%
%   [1] Yuan, J.; Bae, E.;  Tai, X.-C.
%       A Study on Continuous Max-Flow and Min-Cut Approaches
%       CVPR, 2010
%
%   [2] Yuan, J.; Bae, E.; Tai, X.-C.; Boycov, Y.
%       A study on continuous max-flow and min-cut approaches. Part I: Binary labeling
%       UCLA CAM, Technical Report 10-61, 2010
%
%   The mimetic finite-difference discretization method was proposed for
%   the total-variation function in the paper:
%
%   [1] Yuan, J.; Schn{\"o}rr, C.; Steidl, G.
%       Simultaneous Optical Flow Estimation and Decomposition
%       SIAM J.~Scientific Computing, 2007, vol. 29, page 2283-2304, number 6
%
%   This software can be used only for research purposes, you should cite ALL of
%   the aforementioned papers in any resulting publication.
%
%   Please email cn.yuanjing@gmail.com for any questions, suggestions and bug reports
%
%   The Software is provided "as is", without warranty of any kind.
%
%
%                       Version 1.0
%           https://sites.google.com/site/wwwjingyuan/
%
%           Copyright 2011 Jing Yuan (cn.yuanjing@gmail.com)
%

ur = double(imread('cameraman.jpg'))/255;

[rows, cols] = size(ur);
imgSize = rows*cols;

% define the required parameters:
%
%   - alpha: the penalty parameter to the total-variation term.
%       For the case without incorporating image-edge weights, alpha is given
%       by the constant everywhere. For the case with image-edge weights,
%       alpha is given by the pixelwise weight function:
%
%       For example, alpha(x) = b/(1 + a*| nabla f(x)|) where b and a are positive
%       constants and |nabla f(x)| gives the strength of the local gradient.
%
%   - cc: gives the step-size of the augmented Lagrangian method.
%       The optimal range of cc is [0.3, 3].
%
%   - errbound: the error bound for convergence.
%
%   - numIter: the maximum iteration number.
%
%   - steps: the step-size for the graident-projection step to the
%       total-variation function. The optimal range of steps is [0.1,
%       0.17].
%

alpha = 0.5*ones(rows,cols);
cc = 0.3;
errbound = 1e-4;
numIter = 300;
steps = 0.16;

% build up the data terms
ulab(1) = 0.15;
ulab(2) = 0.6;
Cs = abs(ur - ulab(1));
Ct = abs(ur - ulab(2));

% set the initial values
%   - the initial value of u is set to be an initial cut, see below.
%   - the initial values of two terminal flows ps and pt are set to be the
%     specified legal flows.
%   - the initial value of the spatial flow fiels p = (pp1, pp2) is set to
%   be zero.

u = double((Cs-Ct) >= 0);
ps = min(Cs, Ct);
pt = ps;

pp1 = zeros(rows, cols+1);
pp2 = zeros(rows+1, cols);
divp = pp1(:,2:cols+1)-pp1(:,1:cols)+pp2(2:rows+1,:)-pp2(1:rows,:);

erriter = zeros(numIter,1);

tic
for i = 1:numIter

	% update the spatial flow field p = (pp1, pp2):
    %   the following steps are the gradient descent step with steps as the
    %   step-size.

    pts = divp - (ps - pt  + u/cc);
    pp1(:,2:cols) = pp1(:,2:cols) + steps*(pts(:,2:cols) - pts(:,1:cols-1));
    pp2(2:rows,:) = pp2(2:rows,:) + steps*(pts(2:rows,:) - pts(1:rows-1,:));

    % the following steps give the projection to make |p(x)| <= alpha(x)

    gk = sqrt((pp1(:,1:cols).^2 + pp1(:,2:cols+1).^2 + pp2(1:rows,:).^2 + pp2(2:rows+1,:).^2)*0.5);
    gk = double(gk <= alpha) + double(~(gk <= alpha)).*(gk ./ alpha);
    gk = 1 ./ gk;

    pp1(:,2:cols) = (0.5*(gk(:,2:cols) + gk(:,1:cols-1))).*pp1(:,2:cols);
    pp2(2:rows,:) = (0.5*(gk(2:rows,:) + gk(1:rows-1,:))).*pp2(2:rows,:);

    divp = pp1(:,2:cols+1)-pp1(:,1:cols)+pp2(2:rows+1,:)-pp2(1:rows,:);

    % updata the source flow ps

    pts = divp + pt - u/cc + 1/cc;
    ps = min(pts, Cs);

    % update the sink flow pt

    pts = - divp + ps + u/cc;
    pt = min(pts, Ct);

	% update the multiplier u

	erru = cc*(divp + pt  - ps);
	u = u - erru;

    % evaluate the avarage error

    erriter(i) = sum(sum(abs(erru)))/imgSize;

    if (erriter(i) < errbound)
        break;
    end
end
toc
timet = toc

msg = sprintf('number of iterations = %u. \n', i);
disp(msg);


function contourdemo

% Demo function for tricontour
%
% Darren Engwirda - 2006

clc, close all

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Driven Cavity
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

answer = lower(input(['This is a demo function for tricontour. \n'                                 ...
                      '\n'                                                                         ...
                      'The following meshes were generated using my mesh generator, "mesh2d.m" \n' ...
                      'and the data comes from my CFD code "Navier2d.m" \n'                        ...
                      '\n'                                                                         ...
                      'Continue?? [y/n] \n'],'s'));

if ~strcmp(answer,'y')
    return
end

load driven_cavity.mat

node  = old_data.node;
cnect = old_data.cnect;
p     = old_data.p;
t     = old_data.t;
U     = old_data.U;
V     = old_data.V;
P     = old_data.P;

figure

subplot(1,2,1), trimesh(t,p(:,1),p(:,2),U), axis square, title('X velocity')
subplot(1,2,2), trimesh(t,p(:,1),p(:,2),V), axis square, title('Y velocity')

figure

set(gcf,'Name','The xy velocity components for a box flow')

subplot(1,2,1), tricontour(p,t,U,15); axis equal, axis off, title('X velocity')
subplot(1,2,2), tricontour(p,t,V,15); axis equal, axis off, title('Y velocity')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                          Tester
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

answer = lower(input(['As well as making pretty pictures, the correct contouring interval is \n'  ...
                      'actually represented. \n'                                                  ...
                      '\n'                                                                        ...
                      'The following shows the contours of distance from a point at [0.5,0.5] \n' ...
                      'The function is correctly showing the contours at a distance of \n'        ...
                      '[0.1,0.2,0.3,0.4] \n'                                                      ...
                      '\n'                                                                        ...
                      'Continue?? [y/n] \n'],'s'));

if ~strcmp(answer,'y')
    return
end

xc = 0.5;
yc = 0.5;
d  = sqrt( (p(:,1)-xc).^2+(p(:,2)-yc).^2 );

figure, trimesh(t,p(:,1),p(:,2),d)
figure, [c,h]=tricontour(p,t,d,[0.1,0.2,0.3,0.4]); clabel(c,h), axis equal, grid on, hold on, plot(0.5,0.5,'bx')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                       Vortex Shedding
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

answer = lower(input(['The domain can be complex. The following example is a domain with holes. \n'             ...
                      '\n'                                                                                ...
                      'The complexity of the domain shouldn''t matter, you just need a valid triangulation. \n' ...
                      '\n'                                                                                ...
                      'Continue?? [y/n] \n'],'s'));

if ~strcmp(answer,'y')
    return
end

close all

load vortex_shedding.mat

node  = old_data.node;
cnect = old_data.cnect;
p     = old_data.p;
t     = old_data.t;
U     = old_data.U;
V     = old_data.V;
P     = old_data.P;
W     = old_data.W;

figure

trimesh(t,p(:,1),p(:,2),U), axis square, title('X velocity')

figure

set(gcf,'Name','The x velocity for the flow over a cylinder')

% Velocity contours
tricontour(p,t,U,50), axis equal, axis off, title('X velocity')

% Walls
patch('faces',cnect,'vertices',node,'facecolor','none','edgecolor','k')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        Peaks
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

answer = lower(input(['A standard contouring benchmark showing the operation of clabel. \n' ...
                      '\n'                                                                  ...                                                                                ...
                      'Continue?? [y/n] \n'],'s'));

if ~strcmp(answer,'y')
    return
end

close all

[xx,yy] = meshgrid(linspace(-3,3,64),linspace(-2.5,2.5,64));
zz      = peaks(xx,yy);
v       = -3:5;
figure(1)
[c,h] = contour(xx,yy,zz,v);
clabel(c,h)
title('Contour')

% Triangulate
p = [xx(:),yy(:)];
t = delaunayn(p);

figure(2)
[c,h] = tricontour(p,t,zz(:),v);
clabel(c,h)
title('Tricontour')


function [ bootql ] = offpolicy_eval_tdlearning( qldata3, physpol, gamma, num_iter )
% V value averaged over state population
% hence the difference with mean(V) stored in recqvi(:,3)

ncl=size(physpol,1)-2;
bootql=cell(num_iter,1);
p=unique(qldata3(:,8));
prop=5000/numel(p); %5000 patients of the samples are used
prop=min([prop 0.75]);  %max possible value is 0.75 (75% of the samples are used)

ii=qldata3(:,1)==1;
a=qldata3(ii,2);
d=zeros(ncl,1);
 for i=1:ncl
  d(i)=sum(a==i);    % intitial state disctribution
 end

fprintf('Progress of Q-Learning:\n');
fprintf(['\n' repmat('.',1,num_iter) '\n\n']);

parfor i=1:num_iter
fprintf('\b|\n');

ii=floor(rand(size(p,1),1)+prop);     % select a random sample of trajectories
j=ismember(qldata3(:,8),p(ii==1));
q=qldata3(j==1,1:4);

[Qoff, ~]=OffpolicyQlearning150816( q , gamma, 0.1, 300000);

V=zeros(750,25);
for k=1:750
    for j=1:25
        V(k,j)=physpol(k,j)*Qoff(k,j);
    end
end

Vs =sum(V')';
bootql(i)={nansum(Vs(1:750).*d)/sum(d)};

% Vs=nansum((physpol.*Qoff)')';
% bootql(i)={sum(Vs(1:ncl).*d)/sum(d)};
end

bootql=cell2mat(bootql);

end


function b= ImageDenoising(img, level)
     distorted_img = imnoise(img,'gaussian',0,level);

     yRGB = im2double(distorted_img);
     % Generate the same seed used in the experimental results of [1]
     randn('seed', 0);
     % Standard deviation of the noise --- corresponding to intensity
     %  range [0,255], despite that the input was scaled in [0,1]
     sigma = 25;
     % Add the AWGN with zero mean and standard deviation 'sigma'
     zRGB = yRGB + (sigma/255)*randn(size(yRGB));
     % Denoise 'zRGB'. The denoised image is 'yRGB_est', and 'NA = 1'
     %  because the true image was not provided
     [~, yRGB_est] = CBM3D(1, zRGB, sigma);
     % Compute the putput PSNR
%      PSNR = 10*log10(1/mean((yRGB(:)-yRGB_est(:)).^2))
     % show the noisy image 'zRGB' and the denoised 'yRGB_est'
%      figure; imshow(min(max(zRGB,0),1));
%      figure; imshow(min(max(yRGB_est,0),1));
     b = uint8(yRGB_est*255);

end