function enter_eul_angs(varargin)
% update because euler angles were changed
global ts rhs lr rhs1 lr1 xs xst ys yst zs zst ks phi theta psi rad deg x y z gamma delta alpha  vna vnat N Nt sxyz sav sN arcR arcth arctxtR phia1 phia2 phiat sa thetaa1 thetaa2 thetaat psia1 psia2 psiat gammaa1 gammaa2 gammaat saa  deltaa1 deltaa2 deltaat arcvsh alphaa1 alphaa2 alphaat arcR1 arcth1 arctxtR1

naner=false;

phin=str2num(get(phi,'String'));
if length(phin)==0
    naner=true;
end

thetan=str2num(get(theta,'String'));
if length(thetan)==0
    naner=true;
end

psin=str2num(get(psi,'String'));
if length(psin)==0
    naner=true;
end

if naner
    nan_error;
else

    if get(deg,'Value')
        phin=pi*phin/180;
        thetan=pi*thetan/180;
        psin=pi*psin/180;
    end

    an=ea_bounding(phin,thetan,psin); % correct angles
    if an(1)
        phin=an(2);
        thetan=an(3);
        psin=an(4);
        if get(deg,'Value')
            set(phi,'String',num2str(180*phin/pi));
            set(theta,'String',num2str(180*thetan/pi));
            set(psi,'String',num2str(180*psin/pi));
        else
            set(phi,'String',num2str(phin));
            set(theta,'String',num2str(thetan));
            set(psi,'String',num2str(psin));
        end
    end

    Ms=matrices(phin,thetan,psin);
    M=Ms{1}*Ms{2}*Ms{3};

    als=0.5; % transparensy of xyz
    lcs=[0.4 0.4 0.4]; %labels color

    if get(sxyz,'value')
        % x
        xsv=M*[1;0;0];
        xsv1=ks*xsv;
        %xs=arrowa(0,0,0,xsv1(1),xsv1(2),xsv1(3),rhs1*0.8,lr1*0.8,[1 0 0],als,hpar);
        arrow_update(xs,0,0,0,xsv1(1),xsv1(2),xsv1(3),rhs1*0.8,lr1*0.8);
        %xst=text('parent',hpar,'position',xsv1+ts*xsv,'string','x','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(xst,'position',xsv1+ts*xsv);

        % y
        ysv=M*[0;1;0];
        ysv1=ks*ysv;
        %ys=arrowa(0,0,0,ysv1(1),ysv1(2),ysv1(3),rhs1*0.8,lr1*0.8,[0 1 0],als,hpar);
        arrow_update(ys,0,0,0,ysv1(1),ysv1(2),ysv1(3),rhs1*0.8,lr1*0.8);
        %yst=text('parent',hpar,'position',ysv1+ts*ysv,'string','y','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(yst,'position',ysv1+ts*ysv);

        % z
        zsv=M*[0;0;1];
        zsv1=ks*zsv;
        %zs=arrowa(0,0,0,zsv1(1),zsv1(2),zsv1(3),rhs1*0.8,lr1*0.8,[0 0 1],als,hpar);
        arrow_update(zs,0,0,0,zsv1(1),zsv1(2),zsv1(3),rhs1*0.8,lr1*0.8);
        %zst=text('parent',hpar,'position',zsv1+ts*zsv,'string','z','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(zst,'position',zsv1+ts*zsv);

        arrow_visible_off_on(xs,true);
        set(xst,'visible','on');

        arrow_visible_off_on(ys,true);
        set(yst,'visible','on');

        arrow_visible_off_on(zs,true);
        set(zst,'visible','on');

    else

        arrow_visible_off_on(xs,false);
        set(xst,'visible','off');

        arrow_visible_off_on(ys,false);
        set(yst,'visible','off');

        arrow_visible_off_on(zs,false);
        set(zst,'visible','off');

    end

    if (nargin>=1)&&varargin{1}
        vn(1,1)=str2num(get(x,'string'));
        vn(2,1)=str2num(get(y,'string'));
        vn(3,1)=str2num(get(z,'string'));
        gamman=varargin{2};
        deltan=varargin{3};
        alphan=varargin{4};
    else
        % axis v
        axan=euler2axan(phin,thetan,psin,M);
        % {{gamma,delta,alpha},v}
        gda=axan{1};
        gamman=gda{1};
        deltan=gda{2};
        alphan=gda{3};
        vn=axan{2};
        if get(deg,'Value')
            set(gamma,'string',num2str(180*gamman/pi));
            set(delta,'string',num2str(180*deltan/pi));
            set(alpha,'string',num2str(180*alphan/pi));
        else
            set(gamma,'string',num2str(gamman));
            set(delta,'string',num2str(deltan));
            set(alpha,'string',num2str(alphan));
        end

        set(x,'string',num2str(vn(1)));
        set(y,'string',num2str(vn(2)));
        set(z,'string',num2str(vn(3)));
    end

    if get(sav,'value')
        vn1=ks*vn;
        %vna=arrow(0,0,0,vn(1),vn(2),vn(3),rhs1*0.8,lr1*0.8,[0.9 0.2 1],hpar);
        arrow_update(vna,0,0,0,vn(1),vn(2),vn(3),rhs1*0.8,lr1*0.8);
        %vnat=text('parent',hpar,'position',vn+ts*vn1,'string','v','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(vnat,'position',vn+ts*vn1);

        arrow_visible_off_on(vna,true);
        set(vnat,'visible','on');
    else
        arrow_visible_off_on(vna,false);
        set(vnat,'visible','off');
    end

    % line of nodes
    if get(sN,'value')
        Nv=Ms{1}*[1;0;0];
        Nv1=ks*Nv;
        %N=arrow(0,0,0,Nv(1),Nv(2),Nv(3),rhs1*0.8,lr1*0.8,[0.4 0.4 4],hpar);
        arrow_update(N,-Nv(1),-Nv(2),-Nv(3),2*Nv(1),2*Nv(2),2*Nv(3),rhs1*0.8,lr1*0.8);
        %Nt=text('parent',hpar,'position',Nv+ts*Nv1,'string','N','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(Nt,'position',Nv+ts*Nv1);

        arrow_visible_off_on(N,true);
        set(Nt,'visible','on');

    else

        arrow_visible_off_on(N,false);
        set(Nt,'visible','off');

    end

    % angles:
    if get(sa,'value')
        % phi:
        an=arc_data(phin,arcR,arcth,arctxtR);
        Ml=an{1};
        Mt=an{2};
        txv=an{3};
        %phia1=plot3(Ml(1,:),Ml(2,:),zeros(1,length(Ml(1,:))),'-k','parent',hpar);
        set(phia1,'XData',Ml(1,:),'YData',Ml(2,:),'ZData',zeros(1,length(Ml(1,:))));
        %phia2=plot3(Mt(1,:),Mt(2,:),zeros(1,length(Mt(1,:))),'-k','parent',hpar);
        set(phia2,'XData',Mt(1,:),'YData',Mt(2,:),'ZData',zeros(1,length(Mt(1,:))));
        %phiat=text('parent',hpar,'position',[txv 0],'string','\phi','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(phiat,'position',[txv 0]);

        set(phia1,'visible','on');
        set(phia2,'visible','on');
        set(phiat,'visible','on');

        % theta:
        an=arc_data(thetan,arcR,arcth,arctxtR);
        Ml1=an{1};
        Ml=Ms{1}*[zeros(1,length(Ml1(1,:))); -Ml1(2,:); Ml1(1,:)];
        Mt1=an{2};
        Mt=Ms{1}*[zeros(1,length(Mt1(1,:))); -Mt1(2,:); Mt1(1,:)];
        txv1=an{3};
        txv=Ms{1}*[0; -txv1(2); txv1(1)];
        %thetaa1=plot3(Ml(1,:),Ml(2,:),Ml(3,:),'-k','parent',hpar);
        set(thetaa1,'XData',Ml(1,:),'YData',Ml(2,:),'ZData',Ml(3,:));
        %thetaa2=plot3(Mt(1,:),Mt(2,:),Mt(3,:),'-k','parent',hpar);
        set(thetaa2,'XData',Mt(1,:),'YData',Mt(2,:),'ZData',Mt(3,:));
        %thetaat=text('parent',hpar,'position',txv,'string','\theta','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(thetaat,'position',txv);

        set(thetaa1,'visible','on');
        set(thetaa2,'visible','on');
        set(thetaat,'visible','on');

        % psi:
        an=arc_data(psin,arcR,arcth,arctxtR);
        Ml1=an{1};
        Ml=Ms{1}*Ms{2}*[Ml1(1,:); Ml1(2,:); zeros(1,length(Ml1(1,:)))];
        Mt1=an{2};
        Mt=Ms{1}*Ms{2}*[Mt1(1,:); Mt1(2,:); zeros(1,length(Mt1(1,:)))];
        txv1=an{3};
        txv=Ms{1}*Ms{2}*[txv1(1); txv1(2); 0];
        %psia1=plot3(Ml(1,:),Ml(2,:),Ml(3,:),'-k','parent',hpar);
        set(psia1,'XData',Ml(1,:),'YData',Ml(2,:),'ZData',Ml(3,:));
        %psia2=plot3(Mt(1,:),Mt(2,:),Mt(3,:),'-k','parent',hpar);
        set(psia2,'XData',Mt(1,:),'YData',Mt(2,:),'ZData',Mt(3,:));
        %psiat=text('parent',hpar,'position',txv,'string','\psi','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(psiat,'position',txv);

        set(psia1,'visible','on');
        set(psia2,'visible','on');
        set(psiat,'visible','on');

    else
        set(phia1,'visible','off');
        set(phia2,'visible','off');
        set(phiat,'visible','off');

        set(thetaa1,'visible','off');
        set(thetaa2,'visible','off');
        set(thetaat,'visible','off');

        set(psia1,'visible','off');
        set(psia2,'visible','off');
        set(psiat,'visible','off');
    end

    % axis-angle angles
    if get(saa,'value')
        % gamma:
        an=arc_data(gamman,arcR,arcth,arctxtR);
        Ml=an{1};
        Mt=an{2};
        txv=an{3};
        %gammaa1=plot3(Ml(1,:),Ml(2,:),zeros(1,length(Ml(1,:))),'-k','parent',hpar);
        set(gammaa1,'XData',Ml(1,:),'YData',Ml(2,:),'ZData',zeros(1,length(Ml(1,:))));
        %gammaa2=plot3(Mt(1,:),Mt(2,:),zeros(1,length(Mt(1,:))),'-k','parent',hpar);
        set(gammaa2,'XData',Mt(1,:),'YData',Mt(2,:),'ZData',zeros(1,length(Mt(1,:))));
        %gammaat=text('parent',hpar,'position',[txv 0],'string','\gamma','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(gammaat,'position',[txv 0]);

        set(gammaa1,'visible','on');
        set(gammaa2,'visible','on');
        set(gammaat,'visible','on');

        % delta:
        an=arc_data(deltan,arcR,arcth,arctxtR);
        csgm=cos(gamman);
        sngm=sin(gamman);
        Mrot=[csgm, -sngm, 0;
              sngm, csgm,  0;
              0,    0,     1];
        Ml1=an{1};
        Ml=Mrot*[Ml1(1,:); zeros(1,length(Ml1(1,:))); Ml1(2,:)];
        Mt1=an{2};
        Mt=Mrot*[Mt1(1,:); zeros(1,length(Mt1(1,:))); Mt1(2,:)];
        txv1=an{3};
        txv=Mrot*[txv1(1); 0; txv1(2)];
        %deltaa1=plot3(Ml(1,:),Ml(2,:),Ml(3,:),'-k','parent',hpar);
        set(deltaa1,'XData',Ml(1,:),'YData',Ml(2,:),'ZData',Ml(3,:));
        %deltaa2=plot3(Mt(1,:),Mt(2,:),Mt(3,:),'-k','parent',hpar);
        set(deltaa2,'XData',Mt(1,:),'YData',Mt(2,:),'ZData',Mt(3,:));
        %deltaat=text('parent',hpar,'position',txv,'string','\delta','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(deltaat,'position',txv);

        set(deltaa1,'visible','on');
        set(deltaa2,'visible','on');
        set(deltaat,'visible','on');

        an=arc_data(alphan,arcR1,arcth1,arctxtR1);
        csdl=cos(deltan);
        sndl=sin(deltan);
        Mrot1=[csdl, 0,  -sndl;
               0,    1,  0    ;
               sndl, 0,  csdl ];
        Ml1=an{1};
        Ml=Mrot*Mrot1*[zeros(1,length(Ml1(1,:))); -Ml1(2,:); Ml1(1,:)];
        Mt1=an{2};
        Mt=Mrot*Mrot1*[zeros(1,length(Mt1(1,:))); -Mt1(2,:); Mt1(1,:)];
        txv1=an{3};
        txv=Mrot*Mrot1*[0; -txv1(2); txv1(1)];
        %alphaa1=plot3(Ml(1,:)+vn(1)*arcvsh,Ml(2,:)+vn(2)*arcvsh,Ml(3,:)+vn(3)*arcvsh,'-k','parent',hpar);
        set(alphaa1,'XData',Ml(1,:)+vn(1)*arcvsh,'YData',Ml(2,:)+vn(2)*arcvsh,'ZData',Ml(3,:)+vn(3)*arcvsh);
        %alphaa2=plot3(Mt(1,:)+vn(1)*arcvsh,Mt(2,:)+vn(2)*arcvsh,Mt(3,:)+vn(3)*arcvsh,'-k','parent',hpar);
        set(alphaa2,'XData',Mt(1,:)+vn(1)*arcvsh,'YData',Mt(2,:)+vn(2)*arcvsh,'ZData',Mt(3,:)+vn(3)*arcvsh);
        %alphaat=text('parent',hpar,'position',txv+vn*arcvsh,'string','\alpha','HorizontalAlignment','center','VerticalAlignment','middle','color',lcs);
        set(alphaat,'position',txv+vn*arcvsh);

        set(alphaa1,'visible','on');
        set(alphaa2,'visible','on');
        set(alphaat,'visible','on');
    else
        set(gammaa1,'visible','off');
        set(gammaa2,'visible','off');
        set(gammaat,'visible','off');

        set(deltaa1,'visible','off');
        set(deltaa2,'visible','off');
        set(deltaat,'visible','off');

        set(alphaa1,'visible','off');
        set(alphaa2,'visible','off');
        set(alphaat,'visible','off');
    end
end


% this program is designed to induce yearly variability for the data after
% induced monthly variability by FFT using a simple linear relationship

function [yearly_corrected_precip]=yearly_precip_correction(monthly_corrected_precip)
% load the yearly precipitation after FFT
load('Pnew_precip');
P_FFT=Pnew_precip';

load(monthly_corrected_precip);

n=length(P_FFT); % years
m=length(monthly_corrected_precip);  % days

% calculate yearly precip
% the fourth column of Y is precip
j=1;
Z=zeros(n,1);
for i=1:365:m
    Z(j,1)=sum(monthly_corrected_precip(i:i+365-1,4));
    %Z(j,1)=sum(gP(i:i+365-1,1));
    j=j+1;
end

% calculate the ratio of yearly precip between those after FFT and
% generated by weather generator
for i=1:n
    P_ratio(i,1)=P_FFT(i,1)/Z(i,1);
end

% extend the yearly precip ratio to daily scale,the data in each
% year are the same
P_extent=zeros(m,1);
j=1;
for i=1:365:m
    P_extent(i:i+365-1,1)=P_ratio(j,1);
    j=j+1;
end

% adjust the daily precip generated by WG using above ratios
P_adjust=zeros(size(monthly_corrected_precip));
P_adjust(:,1:3)=monthly_corrected_precip(:,1:3);
for i=1:m
    P_adjust(i,4)=monthly_corrected_precip(i,4)*P_extent(i,1);
end
yearly_corrected_precip=P_adjust;

mm=find(yearly_corrected_precip(:,4)<0);
yearly_corrected_precip(mm,4)=0;

save('yearly_corrected_precip','yearly_corrected_precip')


function obj = EVD_wbmethod(obj)

global H W_mopt Nk Nt Nr  Ns Vn ifVFD n;
t1 = clock;
j = 0;
w = zeros(Nk,1);
v = zeros(Nk,1);
%init
if (ifVFD)
    W_equal = W_mopt;
else
    W_equal = exp( 1i*unifrnd(0,2*pi,Nr,Ns,Nk) );
end
V_equal = zeros(Nt,Ns,Nk);
H_equal = zeros(Ns,Ns,Nk);
m_mse = zeros(Nk,1);
for i = 1:Nk
    w(i) = trace(W_equal(:,:,i)'*W_equal(:,:,i));
end

H1 = zeros(Nt,Ns,Nk);
H2 = zeros(Nr,Ns,Nk);
trigger = 1;
m_MSE_new = 100;

%limit the iterations number by i<10
while ( trigger > 1e-4 && j<10)

    Vn1 = Vn * w;
    for i = 1: Nk
        H1(:,:,i) = H(:,:,i)'*W_equal(:,:,i);
    end
    [V_RF,V_U] = EVD_method(H1,Vn1);

    for i = 1:Nk
        V_equal(:,:,i) = V_RF * V_U(:,:,i);
        v(i) = trace(V_equal(:,:,i)'*V_equal(:,:,i));
        H2(:,:,i) = H(:,:,i)*V_equal(:,:,i);
    end
    Vn2 = Vn * v;
    [W_RF,W_B] = EVD_method(H2,Vn2);

    m_MSE_old = m_MSE_new;

    for k = 1:Nk
        W_equal(:,:,k) = W_RF * W_B(:,:,k);
        w(k) = trace(W_equal(:,:,k)'*W_equal(:,:,k));
        H_equal(:,:,k) = W_equal(:,:,k)'*H2(:,:,k);
        m_mse(k) = trace(H_equal(:,:,k) * H_equal(:,:,k)' - H_equal(:,:,k) - H_equal(:,:,k)')...
            + Vn * v(k) * w(k);
    end
    m_MSE_new = sum(m_mse)/Nk;
    trigger = m_MSE_old - m_MSE_new;
    j = j + 1;
    obj.modmse(j,n) = m_MSE_new + Ns;
end

for i = 1:Nk
    V_B(:,:,i)= V_U(:,:,i) /sqrt(v(i));
end

t2 = clock;
runtime  = etime(t2,t1);
obj.V_B = V_B;
obj.W_B = W_B;
obj.V_RF = V_RF;
obj.W_RF = W_RF;
obj.runtime = obj.runtime + runtime;
obj = get_wbmetric(obj);


function g = mlpOutputGrad(model, X)

% MLPOUTPUTGRAD Evaluate derivatives of mlp model outputs with respect to parameters.
% FORMAT
% DESC evaluates the derivates of a multi-layer perceptron's
% outputs with respect to the parameters of the multi-layer
% perceptron. Currently it simply wraps the NETLAB mlpderiv
% function.
% ARG model : the model for which the derivatives are to be
% computed.
% ARG X : the input data locations where the gradients are to be
% computed.
% RETURN g : the gradient of the outputs of the multi-layer
% perceptron with respect to each of the parameters. The size of
% the matrix is number of data x number of parameters x number of
% outputs of the model.
%
% SEEALSO : mlpCreate, mlpderiv
%
% COPYRIGHT : Neil D. Lawrence, 2006

% MLTOOLS

if length(model.hiddenDim) == 1
  g = mlpderiv(model, X);
else

  [Y, G, A] = mlpOut(model, X);
  gw = cell(1, length(model.w));
  for i = 1:length(gw)
    gw{i} = zeros(size(model.w{i}));
  end
  for i = 1:length(G);
    WdG{i} = (1-G{i}.*G{i})*w{i};
  end
  for k = 1:model.outputDim
    gw{end}(:, k) = Z{end}(:, k);
    gb{end} = 1;
    for i = length(model.w)-1:-1:1
      %gw{i} =
      error('Not yet implemented');
    end
  end

% Evaluate second-layer gradients.
gw2 = z'*deltas;
gb2 = sum(deltas, 1);

% Now do the backpropagation.
delhid = deltas*net.w2';
delhid = delhid.*(1.0 - z.*z);

% Finally, evaluate the first-layer gradients.
gw1 = x'*delhid;
gb1 = sum(delhid, 1);

g = [gw1(:)', gb1, gw2(:)', gb2];
end


function [ y, m, d, f ] = jed_to_ymdf_roman ( jed )

%*****************************************************************************80
%
%% JED_TO_YMDF_ROMAN converts a JED to a Roman YMDF date.
%
%  Discussion:
%
%    The Roman calendar used here is artificial.  It is assumed to begin
%    on the Julian calendar date 1 January 753 BC, and to be simply a
%    copy of the Julian calendar, shifted by 753 years.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 July 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real JED, the Julian Ephemeris Date.
%
%    Output, integer Y, M, D, real F,
%    the YMDF date.
%
  [ y, m, d, f ] = jed_to_ymdf_julian ( jed );

  y = y_julian_to_roman ( y );

  return
end


function [mSynCat] = create_syncat(mCatalog,nCdf,fMu,fSigma, fMinMagIn,bPlot)
% function [mSynCat] = create_syncat(mCatalog,nCdf,fMu,fSigma,fMinMagIn,bPlot);
% --------------------------------------------------
% Creates a synthetic catalog for the part below Mc with a Normal CDF.
% Usage:
% Before using this function, create a defined synthetic catalog according
% to a power-law behavior. It's assumed that the smallest magnitude bin is
% the bin of the magnitude of completeness. If fMu, fSigma and fMinMagIn are
% missing, enter interactively.
%
% Incoming variable:
% mCatalog : EQ catalog
% nCdf : Choice of cumulative distribution function
%        1 : Normal cumulative distribution function
%        2 : Lognormal cumulative distribution function
%        3 : Weibull CDF
%
% fMu    : Mu of Normal / Lognormal CDF
% fSigma : Sigma of Normal / Lognormal CDF
% fMinMagIn : Minimum magnitude for synthetic catalog
% bPlot : Plot historgram, 0 =no plot, 1 = plot
% Output:
% mSynCat : Synthetic catalog
% mCat : Catalog of events below Mc
%
% Authour: J. Woessner, j.woessner@sed.ethz.ch
% last update: 10.07.04

% Initialize
mCat = [];

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

% Check for input values
if nargin < 3
    % Calculate probablities for Normal CDF
    prompt = {'Enter mu:','Enter sigma:','Minimum magnitude:'};
    dlg_title = 'Parameters for normal CDF';
    num_lines= 1;
    def     = {'0.8','0.4','0'};
    answer  = inputdlg(prompt,dlg_title,num_lines,def);
    fMu = str2double(answer(1));
    fSigma = str2double(answer(2));
    fMinMagIn = str2double(answer(3));
end

% Calculate FMD
[mFMDC, mFMD] = calc_FMD(mCatalog);

% Find first bin (Mc bin) with data
vSel = (max(mFMD(2,:)) == mFMD(2,:));
fN_Mc = mFMD(2,vSel);

fMinBin = mFMD(1,vSel);
vMagstep = fMinMagIn:0.1:fMinBin-0.1;

% Choose CDF
switch nCdf
    case 1
        vProb = normcdf(vMagstep,fMu, fSigma);
    case 2
        vProb = logncdf(vMagstep,fMu,fSigma);
    case 3
        vProb = wblcdf(vMagstep,fMu,fSigma);
    otherwise
        disp('Check nCdf parameter!');
        return;
end

vProb = vProb';
vMagstep = vMagstep';

% Calculate number of EQs in bins
vN = round(vProb(:,1)*fN_Mc);
mData = [vMagstep vN];
vMag = [];
nCount=1;
for nMag=fMinMagIn:0.1:fMinBin-0.1
    %fM = repmat(nMag,mData(floor(abs(nMag)*10+1),2),1);
    fM = repmat(nMag,mData(nCount,2),1);
    vMag = [vMag; fM];
    nCount=nCount+1;
end

% Choose appropriate number of events from the catalog, change magnitudes
% and add to original catalog
vInd = round(rand(length(vMag),1)*length(mCatalog(:,1)));
% Avoid zeros
vIndice = find(vInd == 0);
vInd(vIndice) = vInd(vIndice)+1;

for n=1:length(vInd)
    mCat = [mCat; mCatalog(vInd(n),:)];
end
%mCat = mCatalog(vSel,:);
%mCat = mCatalog(1:length(vMag),:);
mCat(:,6) = vMag;
mSynCat = [mCat;mCatalog];

if (exist('bPlot','var') & bPlot == 1)
    %Plot result
    fMaxMag = max(mCatalog(:,6));
    figure_w_normalized_uicontrolunits('tag','maghist');
    histogram(mSynCat(:,6),fMinMagIn:0.1:fMaxMag);
    xlabel('Magnitude');
    ylabel('Frequency');
end


function Wrot = whiteningLocal(CC, yc, xc, nRange)

Wrot = zeros(size(CC,1), size(CC,1));
for j = 1:size(CC,1)
    ds          = (xc - xc(j)).^2 + (yc - yc(j)).^2;
    [~, ilocal] = sort(ds, 'ascend');
    ilocal      = ilocal(1:nRange);

    [E, D]      = svd(CC(ilocal, ilocal));
    D           = diag(D);
    eps         = 1e-6;
    wrot0       = E * diag(1./(D + eps).^.5) * E';
    Wrot(ilocal, j)  = wrot0(:,1);
end


function rs = surrogate2(s)

%tstoolbox/@signal/surrogate2
%   Syntax:
%     * rs = surrogate2(s)
%
%   create surrogate data for a scalar time series
%   see : James Theiler et al.'Using Surrogate Data to Detect Nonlinearity
%   in Time Series', APPENDIX : ALGORITHM II
%
% Copyright 1997-2001 DPI Goettingen, License http://www.physik3.gwdg.de/tstool/gpl.txt

narginchk(1,1);

c = surrogate2(s.core); 		% call real working routine for parent core object
rs = signal(c, s);				% special constructor calling syntax for working routines

rs = addhistory(rs,  ['Surrogated with Theiler Algorithm II'] );
rs = addcommandlines(rs, 's = surrogate2(s');


%% RISE Tutorial by Dr. Tao Zha
%% housekeeping
clear
close all
clc
%% Instructions
% - Please run this file block by block and make sure you read the
% comments in each block to understand what it does. If there is anything
% you do not understand, ask questions to the instructor or to your
% neighbor
% - to run a particular block, click on the block and then on your keyboard
% press CTRL+Enter
%% add the paths to RISE, the data and the models
setpaths=true;
if setpaths
    addpath Models % folder with the models
    addpath Data % folder containing the data
end
%% Bring in some data and transform them into RISE's time series format (ts)

tmp=load('Data/data_nk3eq_8501_1301');  %qdatae
dataList={
    'X','output gap  y_t (log GDP_t - log GDPPotential_t)'
    'PAI','PCE core inflation pi_t (log P_t - log P_{t-1})'
    'R','FFR R_t log(1+ffr/400)  (quarterly rate already)'
    };
mydata=struct();
startdate='1985Q1';
for id=1:size(dataList,1)
    % we just give the start date, RISE automatically understand that we
    % are dealing with quarterly data by the format startdate
    mydata.(dataList{id,1})=ts(startdate,... start date
        tmp.qdatae(:,id+1),... the data
        dataList{id,2});
end

%% plot your data, compute basic statistics and look at both carefully
varlist=fieldnames(mydata);
figure('name','US data')
nvars=numel(varlist);
for id=1:nvars
    subplot(nvars,1,id)
    dd=mydata.(varlist{id});
    plot(dd,'linewidth',2)
    title(mydata.(varlist{id}).varnames)
    fprintf('%s:: mean %0.3f  stdev %0.3f\n',mydata.(varlist{id}).varnames{1},mean(dd),std(dd));
end
[~,tmp]=sup_label(['US data ',mydata.(varlist{id}).start,':', mydata.(varlist{id}).finish],'t');
set(tmp,'fontsize',15)

%% Read the model(s)

model_names={'volatilityOnly','policyOnly','volatilityPolicySame',...
    'volatilityPolicyIndependent'};
nmodels=numel(model_names);
estim_models=cell(1,nmodels);

% rather than putting all the models in the same vector as we did earlier,
% we put them in a cell array. If we put them in the same vector and call
% the estimation function, RISE will think that we want to estimate a
% pareto-type of model. But this is not what we want to do and is probably
% beyond the scope of these lectures.

% we loop through the different models using the information in the labels
for imod=1:nmodels
    % replace "for" by "parfor" if you want to use parallel computation
    estim_models{imod}=rise(model_names{imod},... % name of the file to read
        'saveas',true,... % write the expanded model to disk with the default name
        'data',mydata... % we may assign the data now or later
        );
    % a model with multiple files inserted can be difficult to read. The
    % expanded model could be useful for understanding what RISE does and
    % for debugging purposes. The expanded model contains all the details
    % of the individual files (without the comments)
end

%% We estimate the models or filter them directly
close all,clc
% if we have the parallel computing toolbox, we can estimate all models in
% one go
filtration=cell{1,nmodels};
for imod=1:nmodels
    % replace "for" by "parfor" if you want to use parallel computation
    disp('*--------------------------------------------------------------*')
    disp(['*---------Estimation of ',model_names{imod},' model-----------*'])
    disp('*--------------------------------------------------------------*')
    [estim_models{imod},filtration{imod}]=estimate(estim_models{imod},'optimizer','fmincon');
end

%% plot the smoothed probabilities
% we plot the low response (coef_2) and the high volatility (vol_2) regimes
mystates={'coef_2','vol_2'};
mylabels={'low monetary policy response regime','High volatility regime'};
for imod=1:nmodels
    mytitle=['smoothed probabilities for ',model_names{imod},' model'];
    thisstates=mystates;
    thislabels=mylabels;
    discard=false(1,numel(thisstates));
    for ii=1:numel(thisstates)
        discard(ii)=~ismember(thisstates{ii},estim_models{imod}.markov_chains.state_names);
    end
    thisstates=thisstates(~discard);
    thislabels=thislabels(~discard);
    nstates=numel(thisstates);
    figure('name',mytitle)
    for istate=1:nstates
        subplot(nstates,1,istate)
        plot(filtration{imod}.smoothed_state_probabilities.(thisstates{istate}),...
            'linewidth',2)
        title([thislabels{istate},'(chain ',thisstates{istate}(1:end-2),' state ',thisstates{istate}(end),')'])
    end
    [junk,tmp]=sup_label(mytitle,'t');
    set(tmp,'fontsize',15)
    orient tall
end


function [ps,ix] = dpsimplify(p,tol)

% Recursive Douglas-Peucker Polyline Simplification, Simplify
%
% [ps,ix] = dpsimplify(p,tol)
%
% dpsimplify uses the recursive Douglas-Peucker line simplification
% algorithm to reduce the number of vertices in a piecewise linear curve
% according to a specified tolerance. The algorithm is also know as
% Iterative Endpoint Fit. It works also for polylines and polygons
% in higher dimensions.
%
% In case of nans (missing vertex coordinates) dpsimplify assumes that
% nans separate polylines. As such, dpsimplify treats each line
% separately.
%
% For additional information on the algorithm follow this link
% http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
%
% Input arguments
%
%     p     polyline n*d matrix with n vertices in d
%           dimensions.
%     tol   tolerance (maximal euclidean distance allowed
%           between the new line and a vertex)
%
% Output arguments
%
%     ps    simplified line
%     ix    linear index of the vertices retained in p (ps = p(ix))
%
% Examples
%
% 1. Simplify line
%
%     tol    = 1;
%     x      = 1:0.1:8*pi;
%     y      = sin(x) + randn(size(x))*0.1;
%     p      = [x' y'];
%     ps     = dpsimplify(p,tol);
%
%     plot(p(:,1),p(:,2),'k')
%     hold on
%     plot(ps(:,1),ps(:,2),'r','LineWidth',2);
%     legend('original polyline','simplified')
%
% 2. Reduce polyline so that only knickpoints remain by
%    choosing a very low tolerance
%
%     p = [(1:10)' [1 2 3 2 4 6 7 8 5 2]'];
%     p2 = dpsimplify(p,eps);
%     plot(p(:,1),p(:,2),'k+--')
%     hold on
%     plot(p2(:,1),p2(:,2),'ro','MarkerSize',10);
%     legend('original line','knickpoints')
%
% 3. Simplify a 3d-curve
%
%     x = sin(1:0.01:20)';
%     y = cos(1:0.01:20)';
%     z = x.*y.*(1:0.01:20)';
%     ps = dpsimplify([x y z],0.1);
%     plot3(x,y,z);
%     hold on
%     plot3(ps(:,1),ps(:,2),ps(:,3),'k*-');
%
%
%
% Author: Wolfgang Schwanghart, Markus Greim, 13. July, 2010.
% w.schwanghart[at]unibas.ch

if nargin == 0
    help dpsimplify
    return
end

if nargin ~= 2
    error('wrong number of input arguments')
end

% error checking
if ~isscalar(tol)
    error('tol must be a scalar')
end

% nr of dimensions
nrvertices    = size(p,1);
dims    = size(p,2);

% anonymous function for starting point and end point comparision
% compare = @(a,b) (a+eps >= b && a <= b) || ...
%                 (a-eps <= b && a >= b);
% now in simplifyrec()       for GNU/Octave compatibility

% __________________________________
% what happens, when there are NaNs?
% NaNs divide polylines.
Inan      = any(isnan(p),2);
% any NaN at all?
Inanp     = any(Inan);

% if there is only one vertex
if nrvertices == 1 || isempty(p);
    ps = p;
    ix = 1;

% if there are two
elseif nrvertices == 2 && ~Inanp;
    % when the line has no vertices (except end and start point of the line
    % check if the distance between both is less than the tolerance. If so
    % return the center
    if dims == 2;
        d    = hypot(p(1,1)-p(2,1),p(1,2)-p(2,2));
    else
        d    = sqrt(sum((p(1,:)-p(2,:)).^2));
    end

    if d <= tol;
        ps = sum(p,1)/2;
        ix = 1;
    else
        ps = p;
        ix = [1;2];
    end

elseif Inanp;

    % case: there are nans in the p array
    % --> find start and end indices of contiguous non-nan data
    Inan = ~Inan;
    sIX = strfind(Inan',[0 1])' + 1;
    eIX = strfind(Inan',[1 0])';

    if Inan(end)==true;
        eIX = [eIX;nrvertices];
    end

    if Inan(1);
        sIX = [1;sIX];
    end

    % calculate length of non-nan components
    lIX = eIX-sIX+1;
    % put each component into a single cell
    c   = mat2cell(p(Inan,:),lIX,dims);

    % now call dpsimplify again via cellfun.
    if nargout == 2;
        [ps,ix]   = cellfun(@(x) dpsimplify(x,tol),c,'uniformoutput',false);
        ix        = cellfun(@(x,six) x+six-1,ix,num2cell(sIX),'uniformoutput',false);
    else
        ps   = cellfun(@(x) dpsimplify(x,tol),c,'uniformoutput',false);
    end

    % write the data from a cell array to a matrix
    ps = cellfun(@(x) [x;nan(1,dims)],ps,'uniformoutput',false);
    ps = cell2mat(ps);
    ps(end,:) = [];

    % ix wanted? write ix to a matrix, too.
    if nargout == 2;
        ix = cell2mat(ix);
    end

else

% if there are no nans than start the recursive algorithm
ixe     = size(p,1);
ixs     = 1;

% logical vector for the vertices to be retained
I   = true(ixe,1);

% call recursive function
[p,I]   = simplifyrec(p,tol,ixs,ixe, dims, I);
ps  = p(I,:);

% if desired return the index of retained vertices
if nargout == 2;
    ix  = find(I);
end

end
end
% _________________________________________________________
function [p,I]  = simplifyrec(p,tol,ixs,ixe, dims, I);

mycompare = @(a,b) (a+eps >= b && a <= b) || ...
                 (a-eps <= b && a >= b);

    % check if startpoint and endpoint are the same
    % better comparison needed which included a tolerance eps

    c1 = num2cell(p(ixs,:));
    c2 = num2cell(p(ixe,:));

    % same start and endpoint with tolerance
    sameSE = all(cell2mat(cellfun(mycompare,c1(:),c2(:),'UniformOutput',false)));

    if sameSE;
        % calculate the shortest distance of all vertices between ixs and
        % ixe to ixs only
        if dims == 2;
            d    = hypot(p(ixs,1)-p(ixs+1:ixe-1,1),p(ixs,2)-p(ixs+1:ixe-1,2));
        else
            d    = sqrt(sum(bsxfun(@minus,p(ixs,:),p(ixs+1:ixe-1,:)).^2,2));
        end
    else
        % calculate shortest distance of all points to the line from ixs to ixe
        % subtract starting point from other locations
        pt = bsxfun(@minus,p(ixs+1:ixe,:),p(ixs,:));

        % end point
        a = pt(end,:)';

        beta = (a' * pt')./(a'*a);
        b    = pt-bsxfun(@times,beta,a)';
        if dims == 2;
            % if line in 2D use the numerical more robust hypot function
            d    = hypot(b(:,1),b(:,2));
        else
            d    = sqrt(sum(b.^2,2));
        end
    end

    % identify maximum distance and get the linear index of its location
    [dmax,ixc] = max(d);
    ixc  = ixs + ixc;

    % if the maximum distance is smaller than the tolerance remove vertices
    % between ixs and ixe
    if dmax <= tol;
        if ixs ~= ixe-1;
            I(ixs+1:ixe-1) = false;
        end
    % if not, call simplifyrec for the segments between ixs and ixc (ixc
    % and ixe)
    else
        [p,I]   = simplifyrec(p,tol,ixs,ixc, dims, I);
        [p,I]   = simplifyrec(p,tol,ixc,ixe, dims, I);

    end

end
% end


%PLOTF Plot feature distribution, special version
%
%   h = PLOTF(A,N)
%
% Produces 1-D density plots for all the features in dataset A. The
% densities are estimated using PARZENML. N is the number of
% feature density plots on a row.
%
% See also DATASETS, PARZENML

% Copyright: R.P.W. Duin, duin@ph.tn.tudelft.nl
% Faculty of Applied Sciences, Delft University of Technology
% P.O. Box 5046, 2600 GA Delft, The Netherlands

% $Id: plotf.m,v 1.6 2009/11/13 08:54:18 davidt Exp $

function h_out = plotf(a,n,z)
  %DXD make a standard setting for n, I'm getting crazy!
  if nargin<2
    n = 1;
  end

  if ~isdataset(a)
    a = prdataset(a,1); % solves a lot of problems
  end
  [m,k,c] = getsize(a);

	% Define the color for each of the classes:
  if c == 1
    clrmap = [0 0 1];
	elseif c == 2
		clrmap = [0 0 1; 1 0 0];
	else
		clrmap = hsv(c);
	end

	% Make subplots for each feature, so a grid of p x q subplots is
	% defined
	h = [];
	if k >= n
		p = ceil(k/n); q = n;
	else
		p = k; q = 1;
  end

  if isempty(getfeatlab(a))
    a = setfeatlab(a,[1:k]');
  end
  % Get the feature names
  feats = getfeatlab(a,'string');
	%DXD what happens here?!
  %RD If feature labels are scalars to single characters it might be
  %nicer to put 'Feature ' in front of it.
	if size(feats,2) == 1
		feats = [repmat('Feature ',size(feats,1),1) feats];
	end
	if isempty(feats)
		feats = num2str((1:k)');
	end

	% Make the plot for each of the features:
	for j = 1:k
		b = a(:,j);
		s = zeros(1,c);
		d = zeros(121,c);
		bb = [-0.10:0.01:1.10]' * (max(b)-min(b)) + min(b);
		ex = 0;
		% Make a density estimate of each of the classes:
		for i = 1:c
			I = findnlab(a,i);
			D = +distm(bb,b(I,:));
      if nargin < 3
        s(i) = parzenml(b(I,:));
      else
        s(i) = z(i);
      end
			% Compute the density function
			d(:,i) = sum(exp(-D/(s(i).^2)),2)./(length(I)*s(i));;
		end
		% Create the subplots with the correct sizes:
    if p==1 && q==1
      % avoid subplots in case of single plot
      plot(bb,zeros(size(bb)),'w.');
      hold on;
    else
      subplot(p,q,j)
      plot(bb,zeros(size(bb)),'w.');
      hold on
    end
		h = [];
		% Scatter the data and plot the density functions for each of the
		% classes:
		for i = 1:c
			I = findnlab(a,i);
			hh = plot(b(I),zeros(size(b(I))),'x',bb,+d(:,i));
			set(hh,'color',clrmap(i,:));
			h = [h;hh];
		end
		legend(h(1:2:end)',num2str(getlablist(a))); %does not work properly
		title([getname(a) ': ' feats(j,:)]);
		V = axis;
		axis([bb(1) bb(end) V(3) V(4)]);
		set(gca,'xtick',[]);
		set(gca,'ytick',[]);
		xlabel(feats(j,:));
		hold off
	end

	% The last details to take care of:
	if k == 1, title(''); end
	if nargout > 0
		h_out = h;
	end

	return


function color_plot(x,colors,varargin)
% COLOR_PLOT    Scatterplot with colored points.
% color_plot(x) makes a scatterplot of x(:,1) versus x(:,2) with points colored
% according to quantiles of x(:,3).
% color_plot(x,n) specifies the number of color quantiles (default 4).
% color_plot(x,colors) specifies an RGB matrix of colors (the number of rows
% determines the number of quantiles).  The default is YlGnBu_colors.
% color_plot(...,'ColorBar',1) adds a color bar with tick marks from the
% quantile values.
%
% Example:
%   xy = ndgridmat(linspace(-12,12,20),linspace(-12,12,20));
%   z = sin(sqrt(xy(:,1).^2 + xy(:,2).^2));
%   color_plot([xy z]);
%
% See also YlGnBu_colors.

% Written by Tom Minka and Charles Sutton

args = makestruct(varargin);
default_args = struct('ColorBar',0,'MarkerSize',6);
args = setfields(default_args,args);

if nargin < 2
  colors = 4;
end
if length(colors) == 1
  nlevels = colors;
  colors = YlGnBu_colors(nlevels);
else
  nlevels = rows(colors);
end
% color groups
[c,q] = cut_quantile(x(:,3),nlevels);
for lev = 1:nlevels
  i = find(c == lev);
  plot(x(i,1),x(i,2),'o','Color',colors(lev,:),'MarkerFaceColor',colors(lev,:),'MarkerSize',args.MarkerSize);
  hold on
end
hold off

colormap(colors);

if args.ColorBar
  caxis ([0,1]);

  cTickLbls = cell(numel(q), 1);
  for i = 1:length(q)
      cTickLbls{i} = num2str(q(i), '%11.2g');
  end

  colorbar('YTick', linspace(0,1,nlevels+1), 'YTickLabel', cTickLbls);
end

set(gca,'Color','none')


function [germs, germPaths] = centroidalVoronoi2d(germs, poly, varargin)
%CENTROIDALVORONOI2D Centroidal Voronoi tesselation within a polygon.
%
%   PTS = centroidalVoronoi2d(NPTS, POLY)
%   Generate points in a polygon based on centroidal voronoi tesselation.
%   Centroidal germs can be computed by using the Llyod's algorithm:
%   1) initial germs are chosen at random within polygon
%   2) voronoi polygon of the germs is computed
%   3) the centroids of each domain are computed, and used as germs of the
%   next iteration
%
%   [PTS, PATHLIST] = centroidalVoronoi2d(NPTS, POLY)
%   Also returns the path of each germs at each iteration. The result
%   PATHLIST is a cell array with as many cells as the number of germs,
%   containing in each cell the successive positions of the germ.
%
%   PTS = centroidalVoronoi2d(.., PARAM, VALUE)
%   Specify one or several optional arguments. PARAM can be one of:
%   * 'nIter'   specifies the number of iterations of the algorithm
%       (default is 50)
%   * 'verbose' display iteration number. Default is false.
%
%   Example
%     poly = ellipseToPolygon([50 50 40 30 20], 200);
%     nGerms = 100;
%     germs = centroidalVoronoi2d(nGerms, poly);
%     figure; hold on;
%     drawPolygon(poly, 'k');
%     drawPoint(germs, 'bo');
%     axis equal; axis([0 100 10 90]);
%     % extract regions of the CVD
%     box = polygonBounds(poly);
%     [n, e] = boundedVoronoi2d(box, germs);
%     [n2, e2] = clipGraphPolygon(n, e, poly);
%     drawGraphEdges(n2, e2, 'b');
%
%   See also
%   graphs, boundedVoronoi2d, centroidalVoronoi2d_MC
%
%   Rewritten from programs found in
%   http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html
%
%   Reference:
%    Qiang Du, Vance Faber, and Max Gunzburger,
%    Centroidal Voronoi Tessellations: Applications and Algorithms,
%    SIAM Review, Volume 41, 1999, pages 637-676.
%

% ------
% Author: David Legland
% E-mail: david.legland@inra.fr
% Created: 2012-02-23, using Matlab 7.9.0.529 (R2009b)
% Copyright 2012-2022 INRA - Cepia Software Platform

%% Parse input arguments

% Number of germs
if isscalar(germs)
    nGerms = germs;
    germs = [];
else
    nGerms = size(germs, 1);
end

% Number of iterations
nIter = 50;

verbose = false;

keepPaths = nargout > 1;

while length(varargin) > 1
    paramName = varargin{1};
    switch lower(paramName)
        case 'verbose'
            verbose = varargin{2};
        case 'niter'
            nIter = varargin{2};

        otherwise
            error(['Unknown parameter name: ' paramName]);
    end

    varargin(1:2) = [];
end

%% Initialisations

% bounding box of polygon
bbox = polygonBounds(poly);

% init germs if needed
if isempty(germs)
    germs = generatePointsInPoly(nGerms);
end
germIters = cell(nIter, 1);

%% Iteration of the Lloyd algorithm

for i = 1:nIter
     if verbose
        disp(sprintf('Iteration: %d/%d', i, nIter)); %#ok<DSPS>
    end

    if keepPaths
        germIters{i} = germs;
    end

    % Compute Clipped Voronoi diagram of germs
    if verbose
        disp('  compute Voronoi Diagram');
    end
    [n, e, f] = boundedVoronoi2d(bbox, germs);
    [n2, e2, f2] = clipMesh2dPolygon(n, e, f, poly); %#ok<ASGLU>

    % update the position of each germ
    if verbose
        disp('  compute centroids');
    end
    for iGerm = 1:nGerms
        polygon = n2(f2{iGerm}, :);
        germs(iGerm,:) = polygonCentroid(polygon);
    end

end

%% Evenutally compute germs trajectories

if nargout > 1
    % init
    germPaths = cell(nGerms, 1);
    path = zeros(nIter+1, 2);

    % Iteration on germs
    for i = 1:nGerms

        % create path corresponding to germ
        for j = 1:nIter
            pts = germIters{j};
            path(j,:) = pts(i,:);
        end
        path(nIter+1, :) = germs(i,:);

        germPaths{i} = path;
    end
end

function pts = generatePointsInPoly(nPts)
    % extreme coordinates
    xmin = bbox(1);  xmax = bbox(2);
    ymin = bbox(3);  ymax = bbox(4);

    % compute size of box
    dx = xmax - xmin;
    dy = ymax - ymin;

    % allocate memory for result
    pts = zeros(nPts, 2);

    % iterate until all points have been sampled within the polygon
    ind = (1:nPts)';
    while ~isempty(ind)
        NI = length(ind);
        x = rand(NI, 1) * dx + xmin;
        y = rand(NI, 1) * dy + ymin;
        pts(ind, :) = [x y];

        ind = ind(~polygonContains(poly, pts(ind, :)));
    end
end

end


function c8_log_test ( )

%*****************************************************************************80
%
%% C8_LOG_TEST tests C8_LOG.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2015
%
%  Author:
%
%    John Burkardt
%
  seed = 123456678;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'C8_LOG_TEST\n' );
  fprintf ( 1, '  C8_LOG computes the logarithm of a C8.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, ...
    '       C1=C8_UNIFORM_01          C2=C8_LOG(C1)             C3=C8_EXP(C2))\n' );
  fprintf ( 1, '     ---------------------     ---------------------     ---------------------\n' );
  fprintf ( 1, '\n' );

  for test = 1 : 10

    [ c1, seed ] = c8_uniform_01 ( seed );
    c2 = c8_log ( c1 );
    c3 = c8_exp ( c2 );

    fprintf ( 1, '  (%12f  %12f)  (%12f  %12f)  (%12f  %12f)\n', ...
      real ( c1 ), imag ( c1 ), real ( c2 ), imag ( c2 ), real ( c3 ), imag ( c3 ) );

  end

  return
end


function visualize_adv(W, horiz, n_rows, n_cols, do_sort, borders)

if (nargin < 2)
    horiz = 0;
end

if (nargin < 5)
    do_sort = 0;
end

if (do_sort == 1)
    Wnorms = sum(W.^2,1);
    [B,IX] = sort(Wnorms,'descend');
    W = W(:,IX);
end

% how many pixels for borders?
if (nargin < 6)
    borders = 1;
end

fprintf('Visualizing patches\n');
[ndim,nunits]=size(W);
npix = floor(sqrt(ndim)+0.999);
npix2 = floor(sqrt(nunits)+0.999);
minW=min(W(:));
maxW=max(W(:));

if (nargin < 4)
    n_rows = npix2;
    n_cols = npix2;
end

%bigpic = -(minW+maxW)/2*ones(((npix+borders)*npix2+borders));
%bigpic = -(minW+maxW)/2*ones(((n_rows+borders)*npix2+borders), ((n_cols+borders)*npix2+borders));
bigpic = -(minW+maxW)/2*ones(((npix+borders)*n_rows+borders), ((npix+borders)*n_cols+borders));
%if (nunits/npix2<=npix2-1),
%    bigpic = bigpic(:,1:(npix+borders)*(npix2-1)+borders);
%end;
idx = 0;
for i=1:n_rows
    for j=1:n_cols
        idx = idx + 1;

        if idx > nunits
            break;
        end

        if (horiz)
            bigpic((i-1)*(npix+borders)+borders+1:(i-1)*(npix+borders)+borders+npix,...
                (j-1)*(npix+borders)+borders+1:(j-1)*(npix+borders)+borders+npix)...
                = reshape(W(:,idx),npix,npix)';
        else
            bigpic((i-1)*(npix+borders)+borders+1:(i-1)*(npix+borders)+borders+npix,...
                (j-1)*(npix+borders)+borders+1:(j-1)*(npix+borders)+borders+npix)...
                = reshape(W(:,idx),npix,npix);
        end
    end
end;
imagesc(bigpic);
colormap(gray);
axis off;
axis equal;
fprintf('done.\n');


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

function result = cvalue(x1, x2, a, b, N, V, ...
                        model, t, r, q, varargin)

Nstrike = length(x1);

exp2 = exp( 1i .* repmat((1:N)',1,Nstrike) * diag((x2 - a) ./ (b - a)) .* pi );    % init
exp1 = exp( 1i .* repmat((1:N)',1,Nstrike) * diag((x1 - a) ./ (b - a)) .* pi );    % init

m = zeros(3*N-1, Nstrike);                                        % init base

m(N,:) = 1i * pi * (x2 - x1) ./ (b - a);
m(N+1:2*N,:) = 1 ./ repmat((1:N)',1,Nstrike) .* ( exp2 - exp1 );
m(1:N-1,:) = - conj(flipud(m(N+1:2*N-1, :)));
m(2*N+1:3*N-1,:) = ( exp2(1:N-1,:) * diag(exp2(N, :)) - exp1(1:N-1,:) ...
    * diag(exp1(N,:)) ) ./ ( repmat((N+1:2*N-1)',1,Nstrike) );

Grid_j = (0:N-1)';                                          % fix grid

% compute u values
u = exp(feval(@CF, model,pi*repmat(Grid_j,1,Nstrike)*diag(1./(b-a)), t,r,q,varargin{:})) .* V;
u(1,:) = 0.5*u(1,:);

m_s = [m(N:-1:1, :); zeros(1,Nstrike); m(2*N-1:-1:N+1, :)];
u_s = [u; zeros(N, Nstrike)];
m_c = m(3*N-1:-1:N, :);

shortCut = 1;

% apply fft five times
if shortCut == 1
    zeta = -ones(2*N, Nstrike);
    zeta(2 .* (1:N)' - 1,:) = 1;

    fft_u_s = fft(u_s);
    xi_s = ifft((fft(m_s)) .* fft_u_s);
    xi_c = ifft((fft(m_c)) .* (zeta .* fft_u_s));

    result = exp(-r * t) / pi .* imag( xi_s(1:N,:) + flipud(xi_c(1:N,:)) );
else
    M_c = zeros(N, N);
    M_s = zeros(N, N);

    result = zeros(N,Nstrike);

    for k = 1:Nstrike
        for n = 0:N-1
            M_c(:, n+1) = m(N+n:2*N-1+n,k);
            M_s(:, n+1) = m(N+n:-1:1+n,k);
        end

        result(:,k) = exp(-r*t) / pi .* imag((M_c + M_s) * u(:,k));
    end

end


close all;
% function F = discriminative_texture_feature(I_TEXT,theta,verbose,colored,include_intensity,tau_diff,steps_diff,sigma_diff)

Z = imread('zebra.bmp');
figure; imagesc(Z); set(gcf,'Name','original image');
% Z0 = discriminative_texture_feature(double(Z),6,[1 2],0,0,1,500,0); %

Z1 = discriminative_texture_feature(double(Z),0,[1 2],0,1,1,500,0); % this takes a lot of time!, compare to p 64 of Thomas Brox's Phd Thesis
Z2 = discriminative_texture_feature(double(Z));% this is a rasonable approximation(depending on the application) to the previous one while being much faster

F = imread('frog.bmp');
figure; imagesc(F); set(gcf,'Name','original image');
% F0 = discriminative_texture_feature(double(F),6,[1 2],0,0,1,500,0); %
F1 = discriminative_texture_feature(double(F),0,[1 2],0,1,1,1000,0); % this takes a lot of time!, compare to p 65 of Thomas Brox's Phd Thesis

F2 = discriminative_texture_feature(double(F),2,[2],0,1,10,100,0.5); % this is a rasonable approximation(depending on the application to the previous one while being much faster

[sy sx d] = size(Z);
figure;colormap gray;
subplot(2,3,1); imagesc(Z); title('original image');
for i = 1 :5, subplot(2,3,i+1); imagesc(reshape(Z1(i,:),[sy sx])); title(sprintf('F%d',i)); end


function pascal_to_i4_test ( )

%*****************************************************************************80
%
%% PASCAL_TO_I4_TEST tests PASCAL_TO_I4.
%
%  Location:
%
%    http://people.sc.fsu.edu/~jburkardt/m_src/triangle_integrals/pascal_to_i4.m
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    13 April 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'PASCAL_TO_I4_TEST\n' );
  fprintf ( 1, '  PASCAL_TO_I4 converts Pascal triangle indices to a\n' );
  fprintf ( 1, '  linear index.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '     I     J =>    K\n' );
  fprintf ( 1, '\n' );

  for d = 0 : 4
    for i = d : -1 : 0
      j = d - i;
      k = pascal_to_i4 ( i, j );
      fprintf ( 1, '  %4d  %4d    %4d\n', i, j, k );
    end
    fprintf ( 1, '\n' );
  end

  return
end


%load('BoxTorusMesh.mat')
%meshFit = mesh;
uh = UHfit(:,22);
meshFit = enrichMesh3D(meshFit,0);
bc = [1,1,1,1,1,1];
femFit = genNedFEM3D(meshFit,bc);
ng = 1;
X1 = meshFit.p(meshFit.t(:,1),:); X2 = meshFit.p(meshFit.t(:,2),:);
X3 = meshFit.p(meshFit.t(:,3),:); X4 = meshFit.p(meshFit.t(:,4),:);
gw = gaussWtetra(ng);
[gx,gy,gz] = gaussPtetra(X1,X2,X3,X4,ng);
feEvalBas = @EvalNed1Bas3D;

uhK = uh(femFit.g2ldof);
uK1 = 0; uK2 = 0; uK3 = 0;
for i = 1:6
    uK1 = uK1 + uhK(:,i).*feEvalBas(femFit.bas, ':', gx, gy, gz, i, 0, 1).*femFit.t_e_orit(:,i);
    uK2 = uK2 + uhK(:,i).*feEvalBas(femFit.bas, ':', gx, gy, gz, i, 0, 2).*femFit.t_e_orit(:,i);
    uK3 = uK3 + uhK(:,i).*feEvalBas(femFit.bas, ':', gx, gy, gz, i, 0, 3).*femFit.t_e_orit(:,i);
end

Vhfit = [uK1,uK2,uK3];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% separate evaluation
domain = [-1,1,-1,1,-1,1];
nx = 64;
ny = nx;
nz = nx;
mesh = genMesh3D(domain, nx, ny, nz);
mesh = enrichMesh3D(mesh,2);
tol = 10^(-12);
zCut = -0.3125;
fp1 = mesh.p(mesh.f(:,1),:);
fp2 = mesh.p(mesh.f(:,2),:);
fp3 = mesh.p(mesh.f(:,3),:);
fZid = (abs(fp1(:,3)-zCut)<tol).*(abs(fp2(:,3)-zCut)<tol).*(abs(fp3(:,3)-zCut)<tol);
fZid = find(fZid==1);
fmpt = (fp1(fZid,:)+fp2(fZid,:)+fp3(fZid,:))/3;

fMallfit = (meshFit.p(meshFit.t(:,1),:)+meshFit.p(meshFit.t(:,2),:)+...
    meshFit.p(meshFit.t(:,3),:)+meshFit.p(meshFit.t(:,4),:))/4;

tic
[tr,tj]=findtria(meshFit.p,meshFit.t,fmpt);
toc

VhCut = [uK1(tj),uK2(tj),uK3(tj)];

fmptPlan = fmpt(:,1:2);
zDT = delaunay(fmptPlan);

%%%%% trisulf plot
trisurf(zDT,fmptPlan(:,1),fmptPlan(:,2),VhCut(:,1));
shading interp

%%%%% vector field plot
quiver3(fmpt(:,1),fmpt(:,2),fmpt(:,3),VhCut(:,1),VhCut(:,2),VhCut(:,3))

%%%%%% contour plot
tricontour(fmptPlan,zDT,VhCut(:,1),10)

tid1 = find(mesh.tLoc==1);
tid1 = tid1(1:50:end);
fmpt1 = fMall(tid1,:);
[tr,tj]=findtria(meshFit.p,meshFit.t,fmpt1);
Vh1 = Vhfit(tj,:);
quiver5(fmpt1(:,1),fmpt1(:,2),fmpt1(:,3),...
    Vh1(:,1),Vh1(:,2),Vh1(:,3),5,'filled');


function test_tutorial_natmeg2014_timefrequency

% WALLTIME 00:30:00
% MEM 4gb
% DEPENDENCY

% this script executes the MATLAB content from
% http://www.fieldtriptoolbox.org/tutorial/natmeg2014/timefrequency
%
% it corresponds to the wiki version of 7 October 2014

clear all
close all

cd(dccnpath('/home/common/matlab/fieldtrip/data/ftp/workshop/natmeg2014'));

cfg = [];
cfg.dataset = 'oddball1_mc_downsampled.fif';
cfg.channel = 'MEG';

% define trials based on responses
cfg.trialdef.prestim       = 1.5;
cfg.trialdef.poststim      = 2.0;
cfg.trialdef.stim_triggers = [1 2];
cfg.trialdef.rsp_triggers  = [256 4096];
cfg.trialfun               = 'trialfun_oddball_responselocked';
cfg                        = ft_definetrial(cfg);

% preprocess MEG data
cfg.continuous             = 'yes';
cfg.demean                 = 'yes';
cfg.dftfilter              = 'yes';
cfg.dftfreq                = [50 100];

data_MEG_responselocked    = ft_preprocessing(cfg);

cfg              = [];
cfg.output       = 'pow';
cfg.channel      = 'all';
cfg.method       = 'mtmconvol';
cfg.taper        = 'hanning';
cfg.toi          = [-1 : 0.10 : 1.5];
cfg.foi          = 1:40;
cfg.t_ftimwin    = ones(size(cfg.foi)) * 0.5;

cfg.trials       = find(data_MEG_responselocked.trialinfo(:,1) == 256);
TFR_left_MEG     = ft_freqanalysis(cfg, data_MEG_responselocked);

cfg.trials       = find(data_MEG_responselocked.trialinfo(:,1) == 4096);
TFR_right_MEG    = ft_freqanalysis(cfg, data_MEG_responselocked);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.zlim         = [-2e-26 2e-26];
cfg.showlabels   = 'yes';
cfg.layout       = 'neuromag306mag.lay';
cfg.channel      = 'MEG*1';

figure;
ft_multiplotTFR(cfg, TFR_left_MEG);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.maskstyle    = 'saturation';
cfg.zlim         = [-1e-26 1e-26];
cfg.channel      = 'MEG1041';

figure;
ft_singleplotTFR(cfg, TFR_left_MEG);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.xlim         = [0.4 0.8];
cfg.zlim         = [-4e-27 4e-27];
cfg.ylim         = [15 25];
cfg.marker       = 'on';
cfg.layout       = 'neuromag306mag.lay';
cfg.channel      = 'MEG*1';

figure;
ft_topoplotTFR(cfg, TFR_left_MEG);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.xlim         = [0.4 0.8];
cfg.zlim         = [-4e-27 4e-27];
cfg.ylim         = [15 25];
cfg.marker       = 'on';
cfg.layout       = 'neuromag306mag.lay';
cfg.channel      = 'MEG*1';

figure;
ft_topoplotTFR(cfg, TFR_right_MEG);

cfg = [];
cfg.parameter = 'powspctrm';
cfg.operation = '(x1-x2)/(x1+x2)';

TFR_diff_MEG = ft_math(cfg, TFR_right_MEG, TFR_left_MEG);

cfg = [];
cfg.xlim         = [0.4 0.8];
cfg.zlim         = [-0.4 0.4];
cfg.ylim         = [15 25];
cfg.marker       = 'on';
cfg.layout       = 'neuromag306mag.lay';
cfg.channel      = 'MEG*1';

figure;
ft_topoplotTFR(cfg, TFR_diff_MEG);

cfg = [];
cfg.dataset = 'oddball1_mc_downsampled.fif';

% define trials based on responses
cfg.trialdef.prestim       = 1.5;
cfg.trialdef.poststim      = 2.0;
cfg.trialdef.stim_triggers = [1 2];
cfg.trialdef.rsp_triggers  = [256 4096];
cfg.trialfun               = 'trialfun_oddball_responselocked';
cfg                        = ft_definetrial(cfg);

% preprocess EEG data
cfg.channel                = 'EEG';
cfg.continuous             = 'yes';
cfg.demean                 = 'yes';
cfg.dftfilter              = 'yes';
cfg.dftfreq                = [50 100];

data_EEG_responselocked    = ft_preprocessing(cfg);

if false
  % skip the interactive section
  % select bad channels
  cfg = [];
  cfg.metric  = 'var';
  temp        = ft_rejectvisual(cfg, data_EEG_responselocked);
  % with this little trick we get the names of the selected channels
  badchannels = setdiff(data_EEG_responselocked.label,temp.label);
else
  badchannels = {
    'EEG001'
    'EEG002'
    'EEG003'
    'EEG004'
    'EEG005'
    'EEG006'
    'EEG007'
    'EEG008'
    'EEG015'
    'EEG016'
    'EEG017'
    'EEG097'
    'EEG098'
    'EEG099'
    'EEG100'
    'EEG101'
    'EEG102'
    'EEG111'
    'EEG112'};
end

% determine neighbours structure
cfg            = [];
cfg.method     = 'triangulation';
cfg.senstype   = 'EEG'; % Our data still contains information from the MEG channels, we want to make sure ft_prepare_neighbours does not get confused
neighbours_EEG = ft_prepare_neighbours(cfg, data_EEG_responselocked);

% plotting neighbours
cfg            = [];
cfg.neighbours = neighbours_EEG;
cfg.senstype   = 'EEG';
ft_neighbourplot(cfg, data_EEG_responselocked);

% fix channels
cfg = [];
cfg.method                    = 'spline';
cfg.neighbours                = neighbours_EEG;
cfg.badchannel                = badchannels;
cfg.senstype                  = 'EEG';
data_clean_EEG_responselocked = ft_channelrepair(cfg, data_EEG_responselocked);

cfg = [];
cfg.reref                  = 'yes';
cfg.refchannel             = 'all';
data_clean_EEG_responselocked = ft_preprocessing(cfg, data_clean_EEG_responselocked);

cfg              = [];
cfg.output       = 'pow';
cfg.channel      = 'all';
cfg.method       = 'mtmconvol';
cfg.taper        = 'hanning';
cfg.toi          = [-1 : 0.10 : 1.5];
cfg.foi          = 1:40;
cfg.t_ftimwin    = ones(size(cfg.foi)) * 0.5;

cfg.trials       = find(data_clean_EEG_responselocked .trialinfo(:,1) == 256);
TFR_left_EEG     = ft_freqanalysis(cfg, data_clean_EEG_responselocked );

cfg.trials       = find(data_clean_EEG_responselocked .trialinfo(:,1) == 4096);
TFR_right_EEG    = ft_freqanalysis(cfg, data_clean_EEG_responselocked );

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.xlim         = [0.5 1.0];
cfg.zlim         = [-4e-12 4e-12];
cfg.ylim         = [15 25];
cfg.marker       = 'on';
cfg.layout       = 'natmeg_customized_eeg1005.lay';

figure;
ft_topoplotTFR(cfg, TFR_left_EEG);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'relchange';
cfg.ylim         = [15 25];
cfg.xlim         = [0.5 1.0];
cfg.zlim         = [-1.2 1.2];
cfg.layout       = 'natmeg_customized_eeg1005.lay';

figure;
ft_topoplotTFR(cfg, TFR_left_EEG);

cfg = [];
cfg.parameter    = 'powspctrm';
cfg.operation    = '(x1-x2)/(x1+x2)';
TFR_diff_EEG = ft_math(cfg, TFR_right_EEG, TFR_left_EEG);

if false
  % skip the interactive section
  % if ft_math didn't work, then just do it by hand - its exactly the same:
  TFR_diff_EEG = TFR_right_EEG;
  TFR_diff_EEG.powspctrm = (TFR_right_EEG.powspctrm - TFR_left_EEG.powspctrm) ./ (TFR_right_EEG.powspctrm + TFR_left_EEG.powspctrm);
end

cfg = [];
cfg.xlim         = [0.4 0.8];
cfg.ylim         = [15 25];
cfg.zlim         = [-0.2 0.2];
cfg.marker       = 'on';
cfg.layout       = 'natmeg_customized_eeg1005.lay';

figure;
ft_topoplotTFR(cfg, TFR_diff_EEG);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.xlim         = [0.4 0.8];
cfg.ylim         = [15 25];
cfg.zlim         = [-1e-24 1e-24];
cfg.marker       = 'on';
cfg.layout       = 'neuromag306planar.lay';

figure;
ft_topoplotTFR(cfg, TFR_left_MEG);

TFR_left_MEG_comb  = ft_combineplanar([],TFR_left_MEG);
TFR_right_MEG_comb = ft_combineplanar([],TFR_right_MEG);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.xlim         = [0.4 0.8];
cfg.ylim         = [15 25];
cfg.zlim         = [-4e-24 4e-24];
cfg.marker       = 'on';
cfg.layout       = 'neuromag306cmb.lay';

figure;
ft_topoplotTFR(cfg, TFR_left_MEG_comb);

cfg = [];
cfg.parameter = 'powspctrm';
cfg.operation = '(x1-x2)/(x1+x2)';

TFR_diff_MEG_comb = ft_math(cfg, TFR_right_MEG_comb, TFR_left_MEG_comb);

cfg = [];
cfg.baseline     = [-0.5 -0.1];
cfg.baselinetype = 'absolute';
cfg.xlim         = [0.4 0.8];
cfg.ylim         = [15 25];
cfg.zlim         = [-0.3 0.3];
cfg.marker       = 'on';
cfg.layout       = 'neuromag306cmb.lay';

figure;
ft_topoplotTFR(cfg, TFR_diff_MEG_comb);


function A = repmatmatch(a,B)
%Replicate and tile an array to match the size of a given N-D array
%
% Syntax:	A = repmatmatch(a,B)
%
% Inputs:
% 	a - Input array to tile
% 	B - N-D array to match the size of
%
% Outputs:
% 	A - The replicated and tiled copy of input 'a'
%
% Example:
% 	a = [1 2 3];
% 	B = rand(2,3);
% 	A = repmatmatch(a,B);
%
% See also: repmat

% Author: Jacob Donley
% University of Wollongong
% Email: jrd089@uowmail.edu.au
% Copyright: Jacob Donley 2017
% Date: 28 August 2017
% Version: 0.1 (28 August 2017)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

aSz = size(a);
BSz = size(B);

if any(rem(BSz ./ aSz,1))
    error(['The size of each dimension of ''a'' should match ''B'' ' ...
       'or be evenly divisible by the corresponding dimension of ''B''.'])
end

A = repmat(a, BSz ./ aSz);

end


function [slug] = lbm2slug(lbm)
% convert mass from pounds-mass to slugs.
slug = lbm/32.17405;


function [out,Xt,str,ts] = rfnn_mimo_scatter(t,Xt,u,flag,itaVector,alphaVector, NumInVars,NumInTerms,NumOutVars,x0,T)

% This program is an implementation of the on-line RFNN (MIMO) system.
% The structure of the network is determined by the user.
% The input space is partitiond using the scatter-type method.
% All parameters of the network are estimated by Gradient Descent (GD)
% through error backpropagation.

    ninp = NumInVars;
    nout = NumOutVars;
   ninps = ninp+nout+1;  % number of inputs to sfunction [ x y LE ]
   NumRules = NumInTerms;  % Scatter-Type Input Space Partitioning.
       ns = 4*NumInVars*NumInTerms + NumOutVars*NumRules;
     nds = 3*NumInVars*NumInTerms + NumOutVars*NumRules;
     % Learning Rates
     ita1 = itaVector(1); ita2 = itaVector(2);
     ita3 = itaVector(3); ita4 = itaVector(4);
     % Momentum Constants.
     alpha1 = alphaVector(1); alpha2 = alphaVector(2);
     alpha3 = alphaVector(3); alpha4 = alphaVector(4);
%  ----------------------- % initial informations --------------
if abs(flag)==0

    out = [0,ns+nds,nout+ns+nds,ninps,0,1,1];    % states, outputs, inputs, ?, df, #ts
    str = [];                                 % API block consistency
     ts = T;                                  % sample time
    Xt = x0;
%  ----------------------- % state derivatives -----------------
elseif abs(flag) == 2

          x = u(1:ninp);
          e = u(ninp+1:ninp+nout);
   learning = u(ninp+nout+1);

if learning == 1

   % Unroll the states:
   off=1;
   off_end=NumInVars*NumInTerms;
   mean2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumInVars*NumInTerms-1;
   sigma2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off+NumInVars*NumInTerms-1;
   Theta2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumOutVars*NumRules-1;
   W = reshape(Xt(off:off_end),NumOutVars,NumRules);

   off=off_end+1;
   off_end=off+NumInVars*NumInTerms-1;
   Out2 = reshape(Xt(off:off_end),NumInVars,NumInTerms);

   % Unroll the differential states:
   off=off_end+1;
   off_end=off + NumInVars*NumInTerms-1;
   dmean2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumInVars*NumInTerms-1;
   dsigma2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumInVars*NumInTerms-1;
   dTheta2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumOutVars*NumRules-1;
   dW = reshape(Xt(off:off_end),NumOutVars,NumRules);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                    FEEDFORWARD OPERATION                                                      %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LAYER 2 - INPUT TERM NODES
  Out2_pr = Out2;
  In2 = x*ones(1,NumInTerms) + Out2_pr.*Theta2;
  Out2 = exp(-((In2-mean2)./sigma2).^2);

% LAYER 3 - RULE (PRODUCT) NODES
 precond = Out2.';
 Out3 = prod(precond,2);

%%%%%%%%%%%% END OF NETWORK FUNCTIONALITY SECTION %%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%			 					                 PARAMETER LEARNING SECTION	                       			                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% BACKWARD PASS. Error Backpropagation
% LAYER 3
delta3 = e.'*W;

% LAYER 2
ThetaE = zeros(NumInVars,NumInTerms);
for i=1:NumInVars
     for j=1:NumInTerms
   		  ThetaE(i,j) = (Out3(j)/Out2(i,j))*delta3(j);
     end
 end

% LAYER 2 PARAMETER ADJUSTMENT BY GRADIENT DESCENT.
deltamean2  =  2*ThetaE.*Out2.*(In2-mean2)./((sigma2).^2);
deltasigma2 =  2*ThetaE.*Out2.*((In2-mean2).^2)./(sigma2.^3);
deltaTheta2 = -2*ThetaE.*Out2.*(In2-mean2).*Out2_pr./sigma2.^2;

dmean2 = ita2*deltamean2 + alpha2*dmean2;
 mean2  = mean2 + dmean2;

dsigma2 = ita3*deltasigma2 + alpha3*dsigma2;
  sigma2 = sigma2 + dsigma2;

dTheta2 = ita4*deltaTheta2 + alpha4*dTheta2;
 Theta2  = Theta2 + dTheta2;

% LAYER 4 PARAMETER ADJUSTMENT
 deltaW = e*Out3.';
 dW = ita1*deltaW + alpha1*dW;
  W = W + dW;

%%%%%%%%%%%   END OF PARAMETER LEARNING PROCESS %%%%%%%%%
% State Vector Storage.
% Xt = [mean2 sigma2 Theta2 W Out2 dmean2 dsigma2 dTheta2 dW];

Xt = [ reshape(mean2,NumInVars*NumInTerms,1);
          reshape(sigma2,NumInVars*NumInTerms,1);
          reshape(Theta2,NumInVars*NumInTerms,1);
          reshape(W,NumOutVars*NumRules,1);
          reshape(Out2,NumInVars*NumInTerms,1);
          reshape(dmean2,NumInVars*NumInTerms,1);
          reshape(dsigma2,NumInVars*NumInTerms,1);
          reshape(dTheta2,NumInVars*NumInTerms,1);
          reshape(dW,NumOutVars*NumRules,1);];
end

out=Xt;

%  ----------------------- % outputs -------------------------
elseif flag == 3

  % Unpack the network's parameters first...
   off=1;
   off_end=NumInVars*NumInTerms;
   mean2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumInVars*NumInTerms-1;
   sigma2=reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off+NumInVars*NumInTerms-1;
   Theta2 =reshape(Xt(off:off_end),NumInVars,NumInTerms);

   off=off_end+1;
   off_end=off + NumOutVars*NumRules - 1;
   W = reshape(Xt(off:off_end),NumOutVars,NumRules);

   off=off_end+1;
   off_end=off+NumInVars*NumInTerms-1;
   Out2 = reshape(Xt(off:off_end),NumInVars,NumInTerms);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                       FEEDFORWARD OPERATION                                                       %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % LAYER 2 - INPUT TERM NODES
   x = u(1:ninp);

 Out2_pr = Out2;
 In2 = x*ones(1,NumInTerms) + Out2_pr.*Theta2;
 Out2 = exp(-((In2-mean2)./sigma2).^2);

% LAYER 3 - RULE (PRODUCT) NODES
precond = Out2.';
 Out3 = prod(precond,2);

 % LAYER 4
  outact = W*Out3;

  % Block Outputs Vector Formation.
   out=[outact;Xt];

else
   out=[];
end


function [V_hat, lam_hat] = cpf_predictor(V, lam, z, step, pv, pq)
%CPF_PREDICTOR  Performs the predictor step for the continuation power flow
%   [V_HAT, LAM_HAT] = CPF_PREDICTOR(V, LAM, Z, STEP, PV, PQ)
%
%   Computes a prediction (approximation) to the next solution of the
%   continuation power flow using a normalized tangent predictor.
%
%   Inputs:
%       V : complex bus voltage vector at current solution
%       LAM : scalar lambda value at current solution
%       Z : normalized tangent prediction vector from previous step
%       STEP : continuation step length
%       PV : vector of indices of PV buses
%       PQ : vector of indices of PQ buses
%
%   Outputs:
%       V_HAT : predicted complex bus voltage vector
%       LAM_HAT : predicted lambda continuation parameter

%   MATPOWER
%   Copyright (c) 1996-2016, Power Systems Engineering Research Center (PSERC)
%   by Shrirang Abhyankar, Argonne National Laboratory
%   and Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%% sizes
nb = length(V);

Va = angle(V);
Vm = abs(V);
Va_hat = Va;
Vm_hat = Vm;

%% prediction for next step
Va_hat([pv; pq]) = Va([pv; pq]) + step * z([pv; pq]);
Vm_hat([pq])     = Vm([pq])     + step * z([nb+pq]);
lam_hat = lam + step * z(2*nb+1);
V_hat = Vm_hat .* exp(1j * Va_hat);


% this simple exampe shows the general principles of geodesic toolbox
% Danil Kirsanov, 09/2007

global geodesic_library;
geodesic_library = 'geodesic_debug';      %"release" is faster and "debug" does additional checks
rand('state', 0);                         %comment this statement if you want to produce random mesh every time

N = 300;                                  %number of points in a mesh
[vertices,faces] = create_hedgehog_mesh(N, 0.1);   %create "noisy sphere" mesh; "vertices" contains 3D vertex coordinates; "faces" contains vertex id's for every triangle
%[vertices,faces] = create_flat_triangular_mesh(0.1, 0); N = length(vertices);  %rectangular mesh for sanity check

mesh = geodesic_new_mesh(vertices,faces);         %initilize new mesh
algorithm = geodesic_new_algorithm(mesh, 'exact');      %initialize new geodesic algorithm

vertex_id = 1;                             %create a single source at vertex #1
source_points = {geodesic_create_surface_point('vertex',vertex_id,vertices(vertex_id,:))};

geodesic_propagate(algorithm, source_points);   %propagation stage of the algorithm (the most time-consuming)

vertex_id = N;                              %create a single destination at vertex #N
destination = geodesic_create_surface_point('vertex',vertex_id,vertices(vertex_id,:));
path = geodesic_trace_back(algorithm, destination);     %find a shortest path from source to destination

distances = zeros(N,1);              %find distances to all vertices of the mesh (actual pathes are not computed)

[source_id, distances] = geodesic_distance_and_source(algorithm);     %find distances to all vertices of the mesh; in this example we have a single source, so source_id is always equal to 1

geodesic_delete;                            %delete all meshes and algorithms

%-----------------plotting------------------------
hold off;
colormap('default');
trisurf(faces,vertices(:,1),vertices(:,2),vertices(:,3),distances, 'FaceColor', 'interp', 'EdgeColor', 'k');       %plot the mesh
daspect([1 1 1]);

hold on;
plot3(source_points{1}.x, source_points{1}.y, source_points{1}.z, 'or', 'MarkerSize',3);    %plot sources

plot3(destination.x, destination.y, destination.z, 'ok', 'MarkerSize',3);       %plot destination
[x,y,z] = extract_coordinates_from_path(path);                                  %prepare path data for plotting
h = plot3(x*1.001,y*1.001,z*1.001,'k-','LineWidth',2);    %plot path
legend(h,'geodesic curve');


% All Pass Filter Sensitivities, RSS & WCA
% File: c:\M_files\short_updates\allpassrss.m
% Circuit function: G4.m
% updated 11/16/06
%
clear;clc
K=1e3;u=1e-6;
R1=626.25;R2=22.55*K;R3=25.05*K;R4=225.45*K;
C1=0.1*u;C2=C1;
Nom=[R1 R2 R3 R4 C1 C2]; % vector of nominal component values
BF=450;LF=550;NP=101; % linear freq sweep
F=linspace(BF,LF,NP);
% Form symmetric tolerance array T
Tr=0.01;Tc=0.05;
%
T=[-Tr -Tr -Tr -Tr -Tc -Tc;Tr Tr Tr Tr Tc Tc];
Nc=size(T,2); % Nc = number of components
% For assymetric tolerances if present
Mr=1+(T(2,:)+T(1,:))/2;
Tv=(T(2,:)-T(1,:))./(2*Mr); % Used only in RSS
Nav=Nom.*Mr; % Shift components to average value if
% tolerances are assymetric.  Mr = all 1's if symmetric.
%
[An,Bn,Dn,En,I]=G4(Nom); % Nominal SS arrays
%
dpf=0.0001; % derivative perturbation factor
rd=180/pi; % convert radians to degrees
%
% Q & R perturbation vectors are sequenced below:
% Reset; Q = [1 1 1 1 1]; R = [1 1 1 1 1]
% p = 1; Q = [1.0001 1 1 1 1];R = [0.9999 1 1 1 1];
% p = 2; Q = [1 1.0001 1 1 1];R = [1 0.9999 1 1 1];
% and so forth up to p = Nc.
%
Q=1+dpf;R=1-dpf;
%
for i=1:NP % Begin frequency sweep
   Qx=ones(1,Nc);Rx=ones(1,Nc); % Reset perturbation vectors
   s=2*pi*F(i)*j;
   Vo(i)=rd*angle(Dn*((s*I-An)\Bn)+En); % Nominal output
   for p=1:Nc % Begin component loop
      Qx(p)=Q;Rx(p)=R;
      if p > 1;Qx(p-1)=1;Rx(p-1)=1;end; % Reset previous
% Perturbate components forward with Q = 1+dpf
      [A,B,D,E]=G4(Nom.*Qx);
      Vr=rd*angle(D*((s*I-A)\B)+E);
% Perturbate components backward with R = 1-dpf
      [A,B,D,E]=G4(Nom.*Rx);
      Vb=rd*angle(D*((s*I-A)\B)+E);
      %
      Sen(i,p)=(Vr-Vb)/(2*Vo(i)*dpf); % Centered difference approximation
      %
      % For EVA
      %
      if Sen(i,p) > 0
         Lo(p)=1+T(1,p);Hi(p)=1+T(2,p);
      else
         Lo(p)=1+T(2,p);Hi(p)=1+T(1,p);
      end
   end % end component loop
   %
   % Get EVA VL and EVA VH
   %
   [A,B,D,E]=G4(Nom.*Lo);
   VL(i)=rd*angle(D*((s*I-A)\B)+E);
   [A,B,D,E]=G4(Nom.*Hi);
   VH(i)=rd*angle(D*((s*I-A)\B)+E);
   %
   % Get RSS using norm function
   %
   STn=norm(Sen(i,:).*Tv);
   Vrss1(i)=Vo(i)*(1-STn);Vrss2(i)=Vo(i)*(1+STn);
end % close frequency sweep loop i
%
subplot(2,2,1)
h=plot(F,Sen(:,5),'r',F,Sen(:,6),'b');
set(h,'LineWidth',2);
grid on
axis auto
set(gca,'FontSize',8)
%xlabel('Freq (Hz)');
ylabel('%/%')
title('C Sensitivities')
legend('C1','C2',0);
%
subplot(2,2,2)
h=plot(F,Sen(:,1),'k',F,Sen(:,2),'r',F,Sen(:,3),'b',F,Sen(:,4),'g');
set(h,'LineWidth',2);
grid on
axis auto
set(gca,'FontSize',8)
%xlabel('Freq (Hz)');
ylabel('%/%')
title('R Sensitivities')
legend('R1','R2','R3','R4',0);
%
subplot(2,2,4)
m=plot(F,VL,'b',F,VH,'r',F,Vo,'k--');
set(m,'LineWidth',2)
grid on
axis auto
set(gca,'FontSize',8)
%axis([BF LF 30 180])
%YT=linspace(30,180,6);
%set(gca,'ytick',YT);
xlabel('Freq (Hz)');
ylabel('Degrees')
title('EVA')
legend('EVLo','EVHi','Nom',0)
%
subplot(2,2,3)
m=plot(F,Vrss1,'b',F,Vrss2,'r',F,Vo,'k--');
set(m,'LineWidth',2)
grid on
axis auto
set(gca,'FontSize',8)
%axis([BF LF 30 180])
%YT=linspace(30,180,6);
%set(gca,'ytick',YT);
xlabel('Freq (Hz)');
ylabel('Degrees')
title('RSS')
legend('RSSLo','RSSHi','Nom',0)
%
figure(1);


classdef CEC2010_F18 < PROBLEM
% <single> <real> <constrained>
% CEC'2010 constrained optimization benchmark problem

%------------------------------- Reference --------------------------------
% R. Mallipeddi and P. N. Suganthan, Problem definitions and evaluation
% criteria for the CEC 2010 competition on constrained real-parameter
% optimization, Nanyang Technological University, Singapore, 2010.
%------------------------------- 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".
%--------------------------------------------------------------------------

    properties
        O;  % Optimal decision vector
    end
    methods
        %% Default settings of the problem
        function Setting(obj)
            CallStack = dbstack('-completenames');
            load(fullfile(fileparts(CallStack(1).file),'CEC2010.mat'),'Data');
            obj.O = Data{18};
            obj.M = 1;
            if isempty(obj.D); obj.D = 10; end
            obj.D = min(obj.D,length(obj.O));
            obj.lower    = zeros(1,obj.D) - 50;
            obj.upper    = zeros(1,obj.D) + 50;
            obj.encoding = ones(1,obj.D);
        end
        %% Calculate objective values
        function PopObj = CalObj(obj,PopDec)
            Z = PopDec - repmat(obj.O(1:size(PopDec,2)),size(PopDec,1),1);
            PopObj = sum((Z(:,1:end-1)-Z(:,2:end)).^2,2);
        end
        %% Calculate constraint violations
        function PopCon = CalCon(obj,PopDec)
            Z = PopDec - repmat(obj.O(1:size(PopDec,2)),size(PopDec,1),1);
            PopCon(:,1) = mean((-Z.*sin(sqrt(abs(Z)))),2);
            PopCon(:,3) = abs(mean((-Z.*sin(sqrt(abs(Z)))),2)) - 1e-4;
        end
    end
end


function y = tapas_condhalluc_obs2_sim(r, infStates, p)
% Simulates responses according to the condhalluc_obs model
%
% --------------------------------------------------------------------------------------------------
% Copyright (C) 2016 Christoph Mathys, TNU, UZH & ETHZ
%
% This file is part of the HGF toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

% Get parameters
be = p(1);
nu = p(2);

% Prediction trajectory
mu1hat = infStates(:,1,1);

% Get true-positive rate corresponding to stimuli
tp = r.u(:,2);

% Update belief using precision-weighted prediction error
% with nu the generalized precision
x = mu1hat + 1/(1 + nu)*(tp - mu1hat);

% Apply the logistic sigmoid to the inferred beliefs
prob = tapas_sgm(be.*(2.*x-1),1);

% Initialize random number generator
if isnan(r.c_sim.seed)
    rng('shuffle');
else
    rng(r.c_sim.seed);
end

% Simulate
y = binornd(1, prob);

return;


function [c, ceq, cGrad, ceqGrad] = pathConstraint(x)
% [c, ceq, cGrad, ceqGrad] = pathConstraint(x)
%
% This function implements a simple path constraint to keep the knee joint
% of the robot from hyer-extending.
%

q1 = x(1,:);
q2 = x(2,:);
q4 = x(4,:);
q5 = x(5,:);

c = [...
    q1-q2;    %Stance knee joint limit
    q5-q4];   %Swing knee joint limit

ceq = [];

if nargout == 4 %Analytic gradients
    % Gradients with respect to:
    % [t,q1,q2,q3,q4,q5,dq1,dq2,dq3,dq4,dq5,u1,u2,u3,u4,u5] = 1+5+5+5
    nCst = 2;   %stance leg ; swing leg
    nGrad = 16;  %time, angles, rates, torques
    nTime = size(x,2);
    cGrad = zeros(nCst,nGrad,nTime);
    cGrad(1,3,:) = -1;  % cst stance wrt q2
    cGrad(1,2,:) = 1; % cst stance wrt q1
    cGrad(2,5,:) = -1;  % cst swing wrt q4
    cGrad(2,6,:) = 1; % cst swing wrt q5

    ceqGrad = [];
end

end


function params = get_default_truck_trailer_params()
params.velocity = -1;
params.truckWheelbase = 3.0;
params.trailerWheelbase = 11.0;
params.feedbackGain = local_get_default_k();
params.forwardGain = local_get_fwd_k();

% for control
params.Q = [1 0 0
     0 1 0
     0 0 1];
params.R = 100;
params.noiseLevel = 100;
params.forwardTarget = [20, 2, 0.3];

% for viz
params.truckWidth         =  3;
params.truckMargin        = 1;
params.trailerWidth       = 2.8;
params.trailerMarginFront = 1;
params.trailerMarginBack  = 3;
params.tireLen   = 1.2;
params.tireWidth = 0.3;
end

%%
function K = local_get_default_k()
% offLinePolicyIteration
D1 = 3.0;     % trailer wheelbase
D2 = 6.0;   % tractor wheelbase
A = [  0    -1     0;
       0     0     0;
       0     0    1/D2];
B = [0;
    -1/D1;
    1/D1];
Q = [1 0 0
     0 1 0
     0 0 1];
R = 1000;
[~, ~, K] = care(A,B,Q,R)
end

%%
function K = local_get_fwd_k()
% offLinePolicyIteration
D1 = 3.0;     % trailer wheelbase
D2 = 6.0;   % tractor wheelbase
A = [  0     1;
       0     0];
B = [0;
     1/D1];
Q = [1 0
     0 1];
R = 1000;
[~, ~, K] = care(A,B,Q,R);
K = [K 0];
end


function [l] = cl2l(cl)
% Convert volume from centiliters to liters.
% Chad Greene 2012
l = cl*0.01;


function [xPred, SPred]=sqrtDiscEKFPred(xPrev,SPrev,f,FJacob,SQ)
%SQRTDISCEKFPRED Perform the discrete-time prediction step that comes with
%                the square-root implementation of the first-order Extended
%                Kalman Filter (EKF).
%
%INPUTS: xPrev The xDim X 1 state estimate at the previous time-step.
%        SPrev The xDim X xDim lower-triangular square root of the  state
%              covariance matrix at the previous time-step.
%            f A function handle for the state transition function that
%              takes the state as its parameter.
%       FJacob A function handle for calculating the xDim X xDim state
%              transition matrix. If an empty matrix is passed, then FJacob
%              will be found using numerical differentiation  via the
%              numDiff function with default parameters.
%           SQ The xDimX xDim lower-triangular square root of the  process
%              noise covariance matrix.
%
%OUTPUTS: xPred The xDim X 1 predicted state estimate.
%         SPred The xDim X xDim lower-triangular square root of the
%               predicted state covariance estimate.
%
%The first-order EKF is summarized in Figure 10.3.3-1 in Chapter 10.3.3 of
%[1].
%
%The partial derivatives in the Jacobian matrix returned by the function
%FJacob are ordered
%[dF/dx(1), dF/dx(2),...,dF/dx(xDim)]
%That is, column i consists of partial derivatives with respect to element
%i of the x vector.
%
%The mathematics behind the specific square root implementation used here
%are described in [2].
%
%REFERENCES:
%[1] Y. Bar-Shalom, X. R. Li, and T. Kirubarajan, Estimation with
%    Applications to Tracking and Navigation. New York: John Wiley and
%    Sons, Inc, 2001.
%[2] David F. Crouse , "Basic tracking using nonlinear 3D monostatic and
%    bistatic measurements," IEEE Aerospace and Electronic Systems
%    Magazine, vol. 29, no. 8, Part II, pp. 4-53, Aug. 2014.
%
%March 2015, David Karnick, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

xDim=size(xPrev,1);
if(isempty(FJacob))
    FJacob=@(x)numDiff(x,f,xDim);
end

xPred=f(xPrev);
F=FJacob(xPrev);
SPred=tria([F*SPrev,SQ]);
end

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


function f = initialize_variables(N, M, V, min_range, max_range)

%% function f = initialize_variables(N, M, V, min_range, max_range)
% This function initializes the chromosomes. Each chromosome has the
% following at this stage
%       * set of decision variables
%       * objective function values
%
% where,
% N - Population size
% M - Number of objective functions
% V - Number of decision variables
% min_range - A vector of decimal values which indicate the minimum value
% for each decision variable.
% max_range - Vector of maximum possible values for decision variables.

%  Copyright (c) 2009, Aravind Seshadri
%  All rights reserved.
%

min = min_range;
max = max_range;

% K is the total number of array elements. For ease of computation decision
% variables and objective functions are concatenated to form a single
% array. For crossover and mutation only the decision variables are used
% while for selection, only the objective variable are utilized.

K = M + V;

%% Initialize each chromosome
% For each chromosome perform the following (N is the population size)
f = zeros(N,K); % modified by zzb
for i = 1 : N
    % Initialize the decision variables based on the minimum and maximum
    % possible values. V is the number of decision variable. A random
    % number is picked between the minimum and maximum possible values for
    % the each decision variable.
    for j = 1 : V
        f(i,j) = min(j) + (max(j) - min(j))*rand(1);
    end
    % For ease of computation and handling data the chromosome also has the
    % vlaue of the objective function concatenated at the end. The elements
    % V + 1 to K has the objective function valued.
    % The function evaluate_objective takes one chromosome at a time,
    % infact only the decision variables are passed to the function along
    % with information about the number of objective functions which are
    % processed and returns the value for the objective functions. These
    % values are now stored at the end of the chromosome itself.
    f(i,V + 1: K) = evaluate_objective(f(i,1:V), M);
end


function [N,x0] = affine_null_space(A,b,varargin)
  % Given a system Ax = b, determine a matrix N spanning the right null space
  % of A and a feasible solution x0 so that:
  %
  %     A * (N * y + x0) = b  for any y
  %
  % Inputs:
  %   A  m by n (sparse) matrix.
  %   b  m by #b right-hand side
  %   Options:
  %     'Tol'  followed by tolerance for determine rank (what's considered
  %       zero?)
  %     'Method'  followed by either:
  %        {'qr'}  use QR decomposition of A' (robust, best understood, slowest)
  %        'luq'  use LUQ decomposition
  %        'rq'  use QR decomposition of A (good when m << n)
  %        'svd'  use SVD decompostion (only use for small/dense matrices)
  %        'rrlu'  simplifed version of LUQ (**broken**)
  % Outputs:
  %   N  n by #N matrix spanning null space, where #N = m - rowrank(A)
  %   x0 n by #b, so that columns are feasible solutions
  %

  tol = [];
  method = 'qr';
  % default values
  % Map of parameter names to variable names
  params_to_variables = containers.Map( ...
    {'Method','Tol'},{'method','tol'});
  v = 1;
  while v <= numel(varargin)
    param_name = varargin{v};
    if isKey(params_to_variables,param_name)
      assert(v+1<=numel(varargin));
      v = v+1;
      % Trick: use feval on anonymous function to use assignin to this workspace
      feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
    else
      error('Unsupported parameter: %s',varargin{v});
    end
    v=v+1;
  end
  if nargin<2 || isempty(b)
    b = zeros(size(A,1),1);
  end

  if isempty(tol)
    tol = max(max(size(A)) * norm(A,1) * eps,100*eps);
  end

  switch method
  case 'luq'
    %% Special sparse LUQ decomposition
    %tol
    %[L,U,Q] = luq(A,1,tol);
    %% Rank
    %nc = find(any(abs(U)>tol,2),1,'last');
    %nc
    %if isempty(nc)
    %  nc = 0;
    %  m = size(A,1)-nc;
    %  if nargout>=2
    %    x0 = ones(m,1);
    %  end
    %  N = speye(size(A,1),m);
    %else
    %  if nargout>=2
    %    y0 = U(1:nc,1:nc)\(speye(nc,size(L,1))*(L\b));
    %    x0 = Q\[y0;zeros(size(Q,1)-nc,size(b,2))];
    %  end
    %  QQ = Q^-1;
    %  N = QQ(:,nc+1:end);
    %end
    %%big = max(abs(N));
    %%if big > 0
    %%  N = N/big;
    %%end

    % FAR MORE ACCURATE THAN luq(A,...); see doc of spspaces (L is more accurate
    % than Q)
    [L,U,Q] = luq(A',0,tol);
    % this looks gross but somehow doesn't destroy sparsity
    LL = L^-1;
    S = max(abs(U),[],2);
    if ~isempty(S)
      J = find(S<=tol);
    else
      J = (1:size(S,1))';
    end
    N = LL(J,:)';
    nc = find(any(abs(U)>tol,2),1,'last');
    Unc = U(1:nc,1:nc);
    Lnc = L(:,1:nc);
    %x0 = A'*(((A')'*A')\b);
    %x0 = L*U*Q*((Q'*U'*L'*L*U*Q)\b);
    %x0 = L*U*(((U'*L'*L*U)\(Q'\b)));
    %x0 = Lnc*Unc*(((Unc'*Lnc'*Lnc*Unc)\(Q'\b)));
    %x0 = Lnc*(((Lnc'*Lnc)\(Unc'\(Q'\b))));
    x0 = LL'*(speye(size(L,2),size(Unc,1))*(Unc'\(Q'\b)));
  case 'rrlu'
    % "Strong rank revealing LU factorizations" [Miranian & Gu 2002]
    % https://math.berkeley.edu/~luiza/RRLU.pdf
    %
    % Seems there is a typo. They write: "Nr = [-A11\A12;I_{m-k,n-k}]" But so
    % that A*Nr makes sense, I think it should be "Nr = [-A11\A12;I_{n-k,n-k}]"
    %
    %
    m = size(A,1);
    n = size(A,2);
    [L,U,P,Q] = lu(sparse(A),tol);

    NZ = find((any(abs(U)>tol,2)));
    % LUQ just checks the diagonal:
    NZluq = find(abs(diag(U))>tol);
    if ~isempty(setxor(NZ,NZluq))
      size(NZ)
      size(NZluq)
      warning('Not handling non-zero bottom right corner (use luq)');
    end

    Z = find(~(any(abs(U)>tol,2)));
    R = sparse((1:size(U,1))',[NZ;Z],1);

    C = blkdiag(R',speye(size(U,2)-size(R,2)));
    % L U               = P A Q
    % L R' R U C C'     = P A Q
    % L R' R U C        = P A Q C
    % L R' [U11 U12; 0] = P A Q C
    %
    % let M = [-U11\U12;I]
    %
    % [U11 U12] M = 0
    %
    % L R' [U11 U12] M = P A Q C M
    % L R' 0           = P A Q C M
    %
    % Implies
    %
    % N = Q C M --> A N = 0
    %
    UU = R*U*C;
    nc = sum((any(abs(UU)>tol,2)));
    U11 = UU(1:nc,1:nc);
    U12 = UU(1:nc,nc+1:end);
    M = [-U11\U12;speye(size(U12,2),size(U12,2))];
    N = Q*C*M;

    % We have:
    %
    % L R' [U11 U12; 0] = P A Q C
    %
    % A x = b
    % Let x = Q C y
    % P A Q C y = P b
    % L R' [U11 U12; 0] y = P b
    % Assume: (L R') is invertible:
    % [U11 U12; 0] y = (L R')\(P b)
    % [U11 U12; 0] y = [b1;b2];
    % Invertible iff b2 = 0
    % [U11 U12; 0] y = [b1;0];
    % y = [U11\b1;y2] for any y2
    % And might as well set y2 to 0
    % y = [U11\b1; 0]
    %
    LL = L*R';
    bb = LL\(P*b);
    y = [U11\(bb(1:nc,:));zeros(size(U,2)-nc,size(bb,2))];
    x0 = Q*C*y;

  case 'qr'
    [Q,R,E] = qr(A');
    % Rank of A
    nc = find(any(abs(R)>tol,2),1,'last');
    % Q = [Q₁,N]
    Q1 = Q(:,1:nc);
    % A possibly non-unique solution
    if nargout>=2
      x0 = Q1*(R(1:nc,1:nc)'\(E(:,1:nc)'*(b)));
    end
    N = Q(:,nc+1:end);
  case 'rq'
    % http://mathoverflow.net/a/253997/23064
    [Q,R,E] = qr(A);
    nc = find(any(abs(R)>tol,2),1,'last');
    R1 = R(1:nc,1:nc);
    R2 = R(1:nc,nc+1:end);
    n = size(A,2);
    N = E*[-(R1\R2);speye(n-nc,n-nc)];
    %assert(nargout <= 1 && 'x0 not supported for rq');
    b1 = Q(:,1:nc)'*b;
    x0 = E*[R1\b1;zeros(size(E,2)-size(R1,1),size(b1,2))];
  case 'svd'
    [U,S,V] = svd(full(A));
    % Carefully extract diagonal of S
    Sdiag = S(sub2ind(size(S),1:min(size(S)),1:min(size(S))));
    Z = abs(Sdiag)<tol;
    N = V(:,setdiff(1:end,find(~Z)));
    Sdiag(Z) = 0;
    Sdiag(~Z) = 1./Sdiag(~Z);
    % Place back into S without changing size of S
    S(sub2ind(size(S),1:min(size(S)),1:min(size(S)))) = Sdiag;
    Apinv = V*S'*U';
    x0 = Apinv * b;
  end
  % Zap anything below tolerance
  %N(abs(N) < tol) = 0
  [NI,NJ,NV] = find(N);
  N = sparse(NI,NJ,(abs(NV)>tol).*NV,size(N,1),size(N,2));

  %assert(max(abs(A*(N*rand(size(N,2),size(b,2)) + x0) - b)) < 1e-10, ...
  %  'Should span solutions to A x = b');
  if nargout>1 && ~(all(all(abs(A*x0-b)<tol)))
    % Should check that constraint right-hand sides are compatible:
    %   [Q,R,E] = qr(A');
    %   rank_A = find(any(abs(R)>tol,2),1,'last');
    %   [Q,R,E] = qr([A b]');
    %   rank_Ab = find(any(abs(R)>tol,2),1,'last');
    %   assert(rank_Ab <= rank_A);
    %
    warning('MATLAB:singularMatrix', ...
      'A*x0 ~= b, this may mean that  A*x = b is impossible to satisfy');
  end
end


% Clear and close everything
clear all;
close all;

% Add paths needed
addpath('functions/matGeom/geom3d/')
addpath('functions/lips/')

% Load our data from file
path = '../input/floorplan_spencer_small.txt';
planes2d = load_2dplanedata(path);

% Convert to polygons with a height of 8ft
height = 8;
planes3d = planes2dtopolygons3d(planes2d, height);

% Plot the polyons (uses geom3d function)
figure;
for ii=1:size(planes3d,2)
	drawPolygon3d(planes3d{ii}(:,1),planes3d{ii}(:,2),planes3d{ii}(:,3),'b');
    hold on;
end
drawCoordinates3d([0,0,0],[0,0,0],10)
axis equal
xlabel('x-direction (ft)')
ylabel('y-direction (ft)')
zlabel('z-direction (ft)')


function [c,s] = wavefast(x,n,varargin)
%WAVEFAST Computes the FWT of a '3-D extended' 2-D array.
%   [C, L] = WAVEFAST(X, N, LP, HP, EXTMODE) computes 'PAGES' 2D N-level
%   FWTs of a 'ROWS x COLUMNS x PAGES' matrix X with respect to
%   decomposition filters LP and HP and boundary extension mode EXTMODE.
%
%   [C, L] = WAVEFAST(X, N, WNAME, EXTMODE) performs the same operation
%   but fetches filters LP and HP for wavelet WNAME using WAVEFILTER.
%
%   Scale parameter N must be less than or equal to log2 of the maximum
%   image dimension.  Filters LP and HP must be even. If EXTMODE = 'SYM'
%   (the default), X is symmetrically extended; if X = [c1 c2 c3 ... cn]
%   (in 1D), then its symmetric extension would be [... c3 c2 c1 c1 c2
%   c3 ... cn cn cn-1 cn-2 ...]. If EXTMODE = 'PER', X is periodically
%   extended to [... cn-1 cn c1 c2 c3 ... cn c1 c2 ...].
%
%   OUTPUTS:
%     Vector C is a coefficient decomposition vector:
%
%      C = [ a1(n)...ak(n) h1(n)...hk(n) v1(n)...vk(n)
%            d1(n)...dk(n) h1(n-1)... d1(1)...dk(1) ]
%
%     where ai, hi, vi, and di for i = 0,1,...k are columnwise vectors
%     containing approximation, horizontal, vertical, and diagonal
%     coefficient matrices, respectively, and k is the number of pages
%     in the 3-D extended array X. C has 3n + 1 sections where n is the
%     number of wavelet decompositions.
%
%     Matrix S is an [(n+2) x 2] bookkeeping matrix if k = 1; else it is
%     [(n+2) x 3]:
%
%      S = [ sa(n, :); sd(n, :); sd(n-1, :); ... ; sd(1, :); sx ]
%
%     where sa and sd are approximation and detail size entries.
%
%   See also WAVEBACK and WAVEFILTER.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% Check the input arguments for reasonableness.
extmode = 'SYM';
if ischar(varargin{1})
   [lp,hp] = wavefilter(varargin{1},'d');
   if nargin > 3
      extmode = varargin{2};
   end
else
   lp = varargin{1};   hp = varargin{2};
   if nargin > 4
      extmode = varargin{3};
   end
end

% Get the filter length, 'lp', input array size, 'sx', and number of
% pages, 'pages', in extended 2-D array x.
fl = length(lp);       sx = size(x);        pages = size(x,3);

if ((~ismatrix(x)) && (ndims(x) ~= 3)) || (min(sx) < 2) ...
      || ~isreal(x) || ~isnumeric(x)
   error('X must be a real, numeric 2-D or 3-D matrix.');
end

if (~ismatrix(lp)) || ~isreal(lp) || ~isnumeric(lp) ...
      || (~ismatrix(hp)) || ~isreal(hp) || ~isnumeric(hp) ...
      || (fl ~= length(hp)) || rem(fl,2) ~= 0
   error(['LP and HP must be even and equal length real, ' ...
      'numeric filter vectors.']);
end

if ~isreal(n) || ~isnumeric(n) || (n < 1) || (n > log2(max(sx)))
   error(['N must be a real scalar between 1 and ' ...
      'log2(max(size((X))).']);
end

% Init the starting output data structures and initial approximation.
c = [];        s = sx(1:2);
app = cell(pages, 1);
for i = 1:pages
   app{i} = double(x(:,:,i));
end

% For each decomposition ...
for i = 1:n
   % Extend the approximation.
   [app,keep] = extend(app,fl,pages,extmode);

   % Convolve rows with HP and downsample. Then convolve columns
   % with HP and LP to get the diagonal and vertical coefficients.
   rows = convolve(app,hp,'row',fl,keep,pages,extmode);
   coefs = convolve(rows,hp,'col',fl,keep,pages,extmode);
   c = addcoefs(c,coefs,pages);
   s = [size(coefs{1}); s];
   coefs = convolve(rows,lp,'col',fl,keep,pages,extmode);
   c = addcoefs(c,coefs,pages);

   % Convolve rows with LP and downsample. Then convolve columns
   % with HP and LP to get the horizontal and next approximation
   % coeffcients.
   rows = convolve(app,lp,'row',fl,keep,pages,extmode);
   coefs = convolve(rows,hp,'col',fl,keep,pages,extmode);
   c = addcoefs(c,coefs,pages);
   app = convolve(rows,lp,'col',fl,keep,pages,extmode);
end

% Append the final approximation structures.
c = addcoefs(c,app,pages);
s = [size(app{1}); s];
if ~ismatrix(x)
   s(:,3) = size(x,3);
end

%----------------------------------------------------------------------%
function nc = addcoefs(c,x,pages)
% Add 'pages' array coefficients to the wavelet decomposition vector.

nc = c;
for i = pages:-1:1
   nc = [x{i}(:)' nc];
end

%----------------------------------------------------------------------%
function [y,keep] = extend(x,fl,pages,extmode)
% Extend the 'pages' arrays of x in both dimensions and return
% 'keep' to determine the number of coefficients to keep after
% convolution and downsampling.

y = cell(pages,1);
for i = 1:pages
   if strcmpi(extmode,'SYM')
      keep = floor((fl + size(x{i}) - 1) / 2);
      y{i} = padarray(x{i},[(fl - 1) (fl - 1)],'symmetric','both');
   elseif strcmpi(extmode,'PER')
      keep = size(x{i});
      y{i} = padarray(x{i},[fl/2 fl/2],'circular','both');
   else
      error('Invalid extension mode!');
   end
end

%----------------------------------------------------------------------%
function y = convolve(x,h,type,fl,keep,pages,extmode)
% For the 'pages' 2-D arrays in x, convolve the rows or columns with
% h, downsample, and extract the section defined by 'keep'.

y = cell(pages,1);
for i = 1:pages
   if strcmp(type,'row')
      if strcmpi(extmode, 'SYM')
         y{i} = conv2(x{i},h);
         y{i} = y{i}(:,1:2:end);
         y{i} = y{i}(:,fl / 2 + 1:fl / 2 + keep(2));
      else
         y{i} = conv2(x{i},h,'valid');
         y{i} = y{i}(:, 2:2:2 * ceil(keep(2) / 2));
      end
   else
      if strcmpi(extmode,'SYM')
         y{i} = conv2(x{i},h');
         y{i} = y{i}(1:2:end,:);
         y{i} = y{i}(fl / 2 + 1:fl / 2 + keep(1), :);
      else
         y{i} = conv2(x{i},h','valid');
         y{i} = y{i}(2:2:2 * ceil(keep(1) / 2),:);
      end
   end
end


classdef nninterp < nntest
  methods (Test)

    function basicShrink(test)
      zoom = 1 ;
      shrink = 3 ;
      batchSize = 10 ;
      x = test.randn([5 5 3 batchSize]) ;
      y = vl_nninterp(x, shrink, zoom) ;

      % check derivatives with numerical approximation
      dzdy = test.randn(size(y)) ;
      dzdx = vl_nninterp(x, shrink, zoom, dzdy) ;
      test.der(@(x) vl_nninterp(x, shrink, zoom), x, dzdy, dzdx, 1e-3*test.range) ;
    end

    function basicShrinkZoom(test)
      zoom = 4 ;
      shrink = 3 ;
      batchSize = 10 ;
      padBeg = 2 ;
      padEnd = 1 ;
      pad = {'padBeg', padBeg, 'padEnd', padEnd} ;
      x = test.randn([5 5 3 batchSize]) ;
      y = vl_nninterp(x, shrink, zoom, pad{:}) ;

      % check derivatives with numerical approximation
      dzdy = test.randn(size(y)) ;
      dzdx = vl_nninterp(x, shrink, zoom, dzdy, pad{:}) ;
      test.der(@(x) vl_nninterp(x, shrink, zoom, pad{:}), ...
                               x, dzdy, dzdx, 1e-3*test.range) ;
    end

  end
end