function [h1, h2] = ivmPrintPlot(model, plotType, iter, X, ...
                                 y, capName, experimentNo)

% IVMPRINTPLOT Make a 3-D or contour plot of the IVM.
% FORMAT
% DESC makes a 3-D or contour plot from an IVM model to show
% results and prints it out to various directories (in eps and png form).
% ARG model : the model from which the plot is generated.
% ARG plotType : type of plot to be used, options include
% 'ncnmContour', which gives the contours at the edge of the null
% category region for the null category noise model, and
% 'ivmContour'.
% ARG iter : iteration number, if give it is used at the title of
% the plot.
% ARG X : optional argument, if given it is the plotted input
% locations, otherwise model.X is used.
% ARG y : optional argument, if given it is the plotted target
% locations, otherwise model.y is used.
% ARG capName : the name of the saved plots.
% ARG experimentNo : the experiment number to assign to the files.
% RETURN h1 : a handle to the data in the plot.
% RETURN h2 : a handle to any contours, or functions plotted
% derived from the IVM.
%
% SEEALSO : noise3dPlot, noisePointPlot, ivmMeshVals, ivmCreate
%
% COPYRIGHT : Neil D. Lawrence, 2007

% IVM

ivm3dPlot(model, plotType, iter, X, y);
% display active points.
model = ivmOptimiseIvm(model, 2);
fileName = ['dem' capName 'Ivm' num2str(experimentNo)];

printPlot(fileName, '../tex/diagrams', '../html');


function [feature1, feature2, feature3] = SFAfeature(im_lists, layer_name, options)
% SFA features

% written by Dingquan Li
% dingquanli@pku.edu.cn
% IDM, SMS, PKU
% Last update: Aug. 9, 2017

if ~exist('options','var')
    options = 'none';
end

% multi-patch representation
patchSize = [224 224]; %
stride = floor(patchSize/2); %

% Initialize the DCNN
model = [fileparts(which(mfilename)) '/models/ResNet-50-deploy.prototxt']; %
weights = [fileparts(which(mfilename)) '/models/ResNet-50-model.caffemodel']; %
caffe.set_mode_gpu(); %
net = caffe.Net(model, weights, 'test');

l = net.blobs(layer_name).shape;
l = l(3);
feature1 = zeros(length(im_lists),2*l);
feature2 = zeros(length(im_lists),5*l);
feature3 = zeros(length(im_lists),4*l);
for k = 1:length(im_lists)
    fprintf(['Extracting the feature of the ' num2str(k) 'th image ...\n']);

    im = imread(im_lists{k});

    patches = im2patches(im, patchSize, stride);

    % feature extraction
    patch_features = DCNN(patches, net, layer_name);

    % feature aggregation
    feature_mean = mean(patch_features,2);
    feature_std = std(patch_features,0,2);

    feature_q4 = prctile(patch_features,100,2);
    feature_q3 = prctile(patch_features,75,2);
    feature_q2 = prctile(patch_features,50,2);
    feature_q1 = prctile(patch_features,25,2);
    feature_q0 = prctile(patch_features,0,2);

    feature_Moment2 = moment(patch_features,2,2);
    feature_Moment3 = moment(patch_features,3,2);
    feature_Moment4 = moment(patch_features,4,2);

    feature1(k,:) = [feature_mean;feature_std]'; % mean&std aggregation
    feature2(k,:) = [feature_q4;feature_q3;feature_q2;feature_q1;feature_q0]'; % quantile aggregation
    feature3(k,:) = [feature_mean; nthroot(feature_Moment2,2);nthroot(feature_Moment3,3);...
        nthroot(feature_Moment4,4)]'; % moment aggregation

    switch options
        case 'flipH'
            patches = im2patches(im(:,end:-1:1,:), patchSize, stride);

            % feature extraction
            patch_features = DCNN(patches, net, layer_name);

            % feature aggregation
            feature_mean = mean(patch_features,2);
            feature_std = std(patch_features,0,2);

            feature_q4 = prctile(patch_features,100,2);
            feature_q3 = prctile(patch_features,75,2);
            feature_q2 = prctile(patch_features,50,2);
            feature_q1 = prctile(patch_features,25,2);
            feature_q0 = prctile(patch_features,0,2);

            feature_Moment2 = moment(patch_features,2,2);
            feature_Moment3 = moment(patch_features,3,2);
            feature_Moment4 = moment(patch_features,4,2);

            feature1(k+length(im_lists),:) = [feature_mean;feature_std]'; % mean&std aggregation
            feature2(k+length(im_lists),:) = [feature_q4;feature_q3;feature_q2;feature_q1;feature_q0]'; % quantile aggregation
            feature3(k+length(im_lists),:) = [feature_mean; nthroot(feature_Moment2,2);nthroot(feature_Moment3,3);...
                nthroot(feature_Moment4,4)]'; % moment aggregation
        case 'clipUL'
            T = 6;
            for i = 0:T-1
                for j = 0:T-1
                    if i^2+j^2==0
                        continue
                    end
                    patches = im2patches(im(i+1:end,j+1:end,:), patchSize, stride);

                    % feature extraction
                    patch_features = DCNN(patches, net, layer_name);

                    % feature aggregation'res5c'
                    feature_mean = mean(patch_features,2);
                    feature_std = std(patch_features,0,2);

                    feature_q4 = prctile(patch_features,100,2);
                    feature_q3 = prctile(patch_features,75,2);
                    feature_q2 = prctile(patch_features,50,2);
                    feature_q1 = prctile(patch_features,25,2);
                    feature_q0 = prctile(patch_features,0,2);

                    feature_Moment2 = moment(patch_features,2,2);
                    feature_Moment3 = moment(patch_features,3,2);
                    feature_Moment4 = moment(patch_features,4,2);

                    feature1(k+(i*T+j)*length(im_lists),:) = [feature_mean;feature_std]'; % mean&std aggregation
                    feature2(k+(i*T+j)*length(im_lists),:) = [feature_q4;feature_q3;feature_q2;feature_q1;feature_q0]'; % quantile aggregation
                    feature3(k+(i*T+j)*length(im_lists),:) = [feature_mean; nthroot(feature_Moment2,2);nthroot(feature_Moment3,3);...
                        nthroot(feature_Moment4,4)]'; % moment aggregation
                end
            end
    end
end
caffe.reset_all();

function patch_features = DCNN(patches, net, layer_name)
% Extract high-level semantic features from pool5 of ResNet-50

% Preprocess the patches
im_data = patches(:,:,[3 2 1],:); % RGB2BGR
im_data = permute(im_data,[2 1 3 4]); % HWC2WHC
im_data = single(im_data); % single

cropped_dim = size(patches,1);
mean_data = caffe.io.read_mean([fileparts(which(mfilename)) '/models/imagenet_mean.binaryproto']); %
topleft = floor((size(mean_data,1)-cropped_dim)/2)+1;
mean_data = mean_data(topleft:topleft+cropped_dim-1,topleft:topleft+cropped_dim-1,:);

crops_data = arrayfun(@(i)im_data(:,:,:,i)-mean_data,1:size(patches,4),'UniformOutput',false);

% Extract features
l = net.blobs(layer_name).shape; % 2048
l = l(3);
patch_features = zeros(l,length(crops_data));
for n = 1:length(crops_data)
    net.forward(crops_data(n));
%     patch_features(:,n) = std(reshape(net.blobs('res5c').get_data(),[],l,1),0,1); % pool5
    patch_features(:,n) = mean(reshape(net.blobs(layer_name).get_data(),[],l,1)); % pool5
%     patch_features(:,n) = max(reshape(net.blobs('res5c').get_data(),[],l,1)); % pool5
end
patch_features = double(patch_features);

function [patches,imcol,I] = im2patches(I, patchSize, stride)
% IM2PATCHES Extract rectangular patches from input image.
%
%   patches = IM2PATCHES(I,patchSize) I can be a MxN matrix (e.g. gray-
%   scale image) or a MxNxK array (e.g. RGB image). patchSize can be:
%   a) a scalar, in which case: patchHeight = patchWidth = patchSize.
%   b) a vector [patchHeight,patchWidth]
%   c) a Mx4 matrix with bounding box coordinates in the form
%   [xmin,ymin,xmax,ymax].
%   patches is a patchHeight x patchWidth x K x nPatches array (K >= 1).
%
%   patches = IM2PATCHES(I,patchSize,stride) stride between consecutive
%   patches. Stride can be used to extract overlapping patchesand can be
%   either a scalar, or a 2x1 vector to define different strides across
%   axes x and y.
%
%   [patches,imcol,I] = IM2PATCHES(...) also returns imcol, which is a
%   nPixelsPerPatch x nPatches matrix whose columns are the elements of
%   each patch, and I, which is the input image I after padding with zeros.
%
%   USAGE EXAMPLES:
%   patches = im2patches(I,[h,w]);   % equal to: im2col(I,[h,w],'distinct')
%   patches = im2patches(I,[h,w],1); % equal to: im2col(I,[h,w],'sliding')
%
%   NOTE: IM2PATCHES extracts patches padding with zeros when necessary.
%   The only exception is when stride == 1, or when the stride has a value
%   that the last patches horizontally and vertically fit precicely in the
%   image, without crossing the borders.
%
% See also: patches2im, im2col, col2im
%
% Stavros Tsogkas, <stavros.tsogkas@ecp.fr>
% Last update: August 2015

assert(ismatrix(I) || ndims(I) == 3, 'Input must be a 2D or 3D array');
if ismatrix(patchSize) && size(patchSize,2) == 4
    warning('This part of the function has not been tested')
    % patchSize is a Mx4 matrix containing the [xmin,ymin,xmax,ymax]
    % coordinates of bounding boxes that are fully contained in the image
    bb      = patchSize;
    bb(:,1) = max(1,bb(:,1));
    bb(:,2) = max(1,bb(:,2));
    bb(:,3) = min(size(I,2),bb(:,3));
    bb(:,4) = min(size(I,1),bb(:,4));
    patches = cell(size(bb,1),1);
    for i=1:size(bb,1)
        patches{i} = I(bb(i,2):bb(i,4),bb(i,1):bb(i,3),:);
    end
else
    assert(all(patchSize > 0), 'Patch size cannot be negative or zero')
    if isscalar(patchSize)          % Square patches
        patchHeight = patchSize;
        patchWidth  = patchSize;
    elseif numel(patchSize) == 2    % Rectangular patches
        patchHeight = patchSize(1);
        patchWidth  = patchSize(2);
    else
        error('patchSize can be either a scalar or a [patchHeight, patchWidth] vector.')
    end
    if nargin < 3                   % Identical strides for X and Y axis.
        strideX = patchWidth;       % Default is equivalent to 'distinct'
        strideY = patchHeight;      % option for Matlab's im2col.
    elseif isscalar(stride)
        strideY = stride;
        strideX = stride;
    elseif numel(stride) == 2       % Different strides for X and Y axis.
        strideY = stride(1);
        strideX = stride(2);
    else
        error('Stride can be either a scalar or a [strideX, strideY] vector.')
    end
    [hin,win,din] = size(I);
    hout = hin - mod(hin-patchHeight,strideY) + strideY*(strideY > 1);
    wout = win - mod(win-patchWidth, strideX) + strideX*(strideX > 1);
    nPixelsPerPatch = patchWidth*patchHeight*din;
    I(end+1:hout,end+1:wout,:) = 0; % pad with zeros if necessary
    % x-y indices for a single (possibly N-dimensional) patch
    [x,y,z] = meshgrid(1:patchWidth,1:patchHeight,1:din);
    % pixel indices for all patches
    [xstart,ystart] = meshgrid(0:strideX:(wout-patchWidth),0:strideY:(hout-patchHeight));
    inds    = bsxfun(@plus, reshape(y,nPixelsPerPatch,[]), ystart(:)');
    inds    = inds + (bsxfun(@plus, hout*reshape(x-1,nPixelsPerPatch,[]), hout*xstart(:)'));
    inds    = bsxfun(@plus, inds, (z(:)-1)*(hout*wout));
    imcol   = I(inds);
    patches = reshape(imcol,patchHeight,patchWidth,din,[]);
end
% =========================================================================
% Alternative versions for Matlab's im2col 'distinct' and 'sliding' modes.
% These versions are a little faster than the code used in im2patches for
% creating the imcol image, but they cannot handle an arbitrary stride
% between neighboring patches.
% =========================================================================
% % -------------------------------------------------------------------------
% function out = im2col_distinct(A,blocksize)
% % -----------------------------------------------------------------------
% nrows = blocksize(1);
% ncols = blocksize(2);
% nele = nrows*ncols;
%
% row_ext = mod(size(A,1),nrows);
% col_ext = mod(size(A,2),ncols);
%
% padrowlen = (row_ext~=0)*(nrows - row_ext);
% padcollen = (col_ext~=0)*(ncols - col_ext);
%
% A1 = zeros(size(A,1)+padrowlen,size(A,2)+padcollen);
% A1(1:size(A,1),1:size(A,2)) = A;
%
% t1 = reshape(A1,nrows,size(A1,1)/nrows,[]);
% t2 = reshape(permute(t1,[1 3 2]),size(t1,1)*size(t1,3),[]);
% t3 =  permute(reshape(t2,nele,size(t2,1)/nele,[]),[1 3 2]);
% out = reshape(t3,nele,[]);
%
% return;
%
% % -------------------------------------------------------------------------
% function out = im2col_sliding(A,blocksize)
% % -------------------------------------------------------------------------
%
% nrows = blocksize(1);
% ncols = blocksize(2);
%
% %// Get sizes for later usages
% [m,n] = size(A);
%
% %// Start indices for each block
% start_ind = reshape(bsxfun(@plus,[1:m-nrows+1]',[0:n-ncols]*m),[],1); %//'
%
% %// Row indices
% lin_row = permute(bsxfun(@plus,start_ind,[0:nrows-1])',[1 3 2]);  %//'
%
% %// Get linear indices based on row and col indices and get desired output
% out = A(reshape(bsxfun(@plus,lin_row,[0:ncols-1]*m),nrows*ncols,[]));
%
% return;


% Copyright (c) 2015, Francesco Perrone
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.

function [WF,WFtower,t,dy,dz,Y,Z,Zbottom,Ztower] = turbulent_wind_field_generator(U0,I0,Seed,HubHt,Ny,Nz,Ly,Lz,dt,T,xLu,xLv,xLw,Lc,a,shearExp)

%% FREQUENY/TIME PREALLOCATION & INITIALISATION
T = round(T + (Ly/U0));
Nt = Ny*Nz; % Total number of grid points
N = find_steps_number(T,dt); % Number of samples (in frequency and time domain)
Fs = N/T;
df = Fs/N; % Frequency sample
fp = df:df:0.5*Fs; % Positive frequency array [Hz]
dT = T/N; % Wind file time step

%% DEFINITION OF SIMULATION GRID

[Y,Z,dy,dz] = define_grid_coordinates(Ly,Lz,Ny,Nz,HubHt); % Generate (Y,Z) coordinates of grid points and spacing on y-/z-axis
Zunique = unique(Z);
Zbottom = min(Zunique(:));
Ztower = (Zbottom):-dz:0;
% Ytower = zeros(size(Ztower));
Ntower = numel(Ztower);
Uvert = repmat(U0.*((Zunique/HubHt).^shearExp),1,Ny)'; % Exponential vertical wind profile
Uvert_tower = U0.*((Ztower/HubHt).^shearExp);
Uvert1 = Uvert(:);
Distance = abs(sqrt(bsxfun(@plus,sum([Y(:) Z(:)].^2,2),sum([Y(:) Z(:)].^2,2)') - 2*([Y(:) Z(:)]*[Y(:) Z(:)]'))); % Distance matrix

%% POWER SPECTRA

r = 5/3; % Kaimal spectrum exponent
sigma_u = (I0*0.01*U0);
sigma_v = 0.8*sigma_u;
sigma_w = 0.5*sigma_u;
var_u = sigma_u^2;
var_v = sigma_v^2;
var_w = sigma_w^2;

Suu_p = ((4*var_u*(xLu/U0))./((1 + 6*fp*(xLu/U0)).^r))*0.5; % Positive amplitude spectrum (U-component)
Svv_p = ((4*var_v*(xLv/U0))./((1 + 6*fp*(xLv/U0)).^r))*0.5; % Positive amplitude spectrum (V-component)
Sww_p = ((4*var_w*(xLw/U0))./((1 + 6*fp*(xLw/U0)).^r))*0.5; % Positive amplitude spectrum (W-component)

Su = sqrt(Suu_p*N*Fs);
Sv = sqrt(Svv_p*N*Fs);
Sw = sqrt(Sww_p*N*Fs);

%% CALCULATION OF FFT TERMS

rng(Seed,'twister'); % Start Mersenne twister

fft_uu_p = zeros(Nt,N*0.5);
fft_vv_p = zeros(Nt,N*0.5);
fft_ww_p = zeros(Nt,N*0.5);

nn_u = exp(1i*2*pi*rand(Nt,numel(fp)));
nn_v = exp(1i*2*pi*rand(Nt,numel(fp)));
nn_w = exp(1i*2*pi*rand(Nt,numel(fp)));

for idx_chol = 1:numel(fp)
    Coh_uu = chol(exp(-a.*Distance.*sqrt(((fp(idx_chol)./U0).^2) + ((0.12./Lc).^2))),'lower'); %Coherence function U-component (according to IEC 61400-1 Ed.3)
    fft_uu_p(:,idx_chol) = (Coh_uu*Su(idx_chol))*nn_u(:,idx_chol);%chol(Coh_uu,'lower')
    fft_vv_p(:,idx_chol) = (Coh_uu*Sv(idx_chol))*nn_v(:,idx_chol);%chol(Coh_vv_ww,'lower')
    fft_ww_p(:,idx_chol) = (Coh_uu*Sw(idx_chol))*nn_w(:,idx_chol);%chol(Coh_vv_ww,'lower')
end

% Prepare FFT terms for each time series by mirroring the positive side
% about the frequency axis
fft_uu = [zeros(Nt,1) fft_uu_p fliplr(conj(fft_uu_p(:,1:end-1)))];
fft_vv = [zeros(Nt,1) fft_vv_p fliplr(conj(fft_vv_p(:,1:end-1)))];
fft_ww = [zeros(Nt,1) fft_ww_p fliplr(conj(fft_ww_p(:,1:end-1)))];

fft_uu(:,N*0.5 + 1) = real(fft_uu(:,N*0.5 + 1));
fft_vv(:,N*0.5 + 1) = real(fft_vv(:,N*0.5 + 1));
fft_ww(:,N*0.5 + 1) = real(fft_ww(:,N*0.5 + 1));

%% GENERATE TIME SERIES

Ucomp = (ifft((fft_uu),[],2));
Vcomp = (ifft((fft_vv),[],2));
Wcomp = (ifft((fft_ww),[],2));

%% SCALE TIME SERIES

stdU = (std(Ucomp,[],2));
stdV = (std(Vcomp,[],2));
stdW = (std(Wcomp,[],2));

idx_hub = ((Nz+1)*Ny)*0.5 - (Ny-1)*0.5;

SF = [sigma_u./stdU(idx_hub) , sigma_v./stdV(idx_hub) , sigma_w./stdW(idx_hub)];

Ucomp1 = arrayfun(@(i) Ucomp(i,:)*SF(1),1:Nt,'UniformOutput',false);
Ucomp1 = vertcat(Ucomp1{:});
Vcomp1 = arrayfun(@(i) Vcomp(i,:)*SF(2),1:Nt,'UniformOutput',false);
Vcomp1 = vertcat(Vcomp1{:});
Wcomp1 = arrayfun(@(i) Wcomp(i,:)*SF(3),1:Nt,'UniformOutput',false);
Wcomp1 = vertcat(Wcomp1{:});

t = 0:dT:(N-1)*dT;

WF = zeros(N,Nz,Ny,3);
WFtower = zeros(N,numel(Ztower),3);
it = 0;
for iz = 1:Nz
    for iy = 1:Ny
        it = it + 1;
        WF(:,iz,iy,1) = Ucomp1(it,:) + Uvert1(it);
        WF(:,iz,iy,2) = Vcomp1(it,:);
        WF(:,iz,iy,3) = Wcomp1(it,:);
    end
end

for iz = 1:Ntower
        WFtower(:,iz,1) = (WF(:,1,.5*(Ny+1),1) - mean(WF(:,1,.5*(Ny+1),1))) + Uvert_tower(iz);
        WFtower(:,iz,2) = WF(:,1,.5*(Ny+1),2);
        WFtower(:,iz,3) = WF(:,1,.5*(Ny+1),3);
end

end


function [outputs,model,accuracies,accuracies_locs,bestlambda] = hkl_fold(nfold,typefold,X,Y,lambdas,loss,kernel,kernel_params,varargin);
%%%%%%%%%%%%%%%%%%%%%%%
% HKL K-FOLD
%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% required parameter
% nfold                 5 or 10
% typefold              'same' or 'scaled' -> using same lambda or same lambda/n
% X                     input data: n x p matrix (n=number of observations)
%						or kernel matrices ( n(n+1)/2 x p x q single)
% Y                     responses ( n x 1 matrix )
%                       NB: for classification in {0,1} (and not in {-1,1})
% lambdas               regularization parameters (might be vector or single number)
%						better to start first with large values of lambdas
% loss                  loss function ('square','logistic')
% kernel                kernel to be decomposed (see list below)
% kernel_params         kernel parameters
% varargin              see hkl.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% find out if display is suppressed...
f = strcmp('display',varargin(1:2:end));
if any(f)
    display = varargin{find(f)*2};
else
    display = 1;
end

if display fprintf('all folds\n'); end
% first perform learning on the full dataset%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[outputs,model,accuracies] = hkl(X,Y,lambdas,loss,kernel,kernel_params,varargin{:});

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% centering and scaling is done separatetly for each fold
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% cut into pieces
n = length(Y);

% cut into folds
folds = cell(1,nfold);
compfolds = cell(1,nfold);
for ifold = 1:nfold
    if ifold<nfold
        folds{ifold} = floor( (ifold-1)*n/nfold + 1): floor( ifold*n/nfold );
    else
        folds{ifold} = floor( (ifold-1)*n/nfold + 1):n;
    end
    compfolds{ifold}=1:n;
    compfolds{ifold}(folds{ifold}) = [];

end

% define lambdas on the fold
switch typefold,
    case 'same'
        lambdas_fold = lambdas;
    case 'scaled'
        lambdas_fold = lambdas / ( 1- 1/nfold) ;
end

for ifold = 1:nfold
    if display fprintf('fold %d\n',ifold); end
    Yloc = Y(compfolds{ifold});
    Ytestloc = Y(folds{ifold});

    if ~strcmp(kernel,'base kernels') || ~strcmp(kernel,'base kernels-mkl') || ~strcmp(kernel,'base kernels-bimkl')
        Xloc = X(compfolds{ifold},:);
        Xtestloc = X(folds{ifold},:);
    else
        error('not implemented yet')

    end

    [outputs_loc,model_loc,accuracies_loc] = hlp_diskcache('predictivemodels',@hkl,Xloc,Yloc,lambdas_fold,loss,kernel,kernel_params,varargin{:},'Xtest',Xtestloc,'Ytest',Ytestloc);

    accuracies_locs{ifold} = accuracies_loc;
end

temp = [];
for ifold=1:nfold, temp = [ temp; accuracies_locs{ifold}.testing_error]; end;

[a,bestlambda] = min(mean(temp,1));
try
estimated_best_error = accuracies.testing_error(bestlambda)
best_error = min(accuracies.testing_error)
catch,end


function s = sudoku_line_row_swap ( box_row, line_row1, line_row2, s )

%*****************************************************************************80
%
%% SUDOKU_LINE_ROW_SWAP swaps two horizontal lines that share the same box row.
%
%  Discussion:
%
%    Two rows of a Sudoku may be shifted without changing the basic
%    structure, as long as the rows are in the same box row.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 February 2006
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer BOX_ROW, the index of the box row, between 1 and 3.
%
%    Input, integer LINE_ROW1, LINE_ROW2, the indices of the two rows
%    which are to be interchanged.  These should be between 1 and 3.
%
%    Input, integer S(9,9), the Sudoku to be shuffled.
%
%    Output, integer S(9,9), the shuffled Sudoku.
%
  if ( 1 <= box_row & box_row <= 3 )
    if ( 1 <= line_row1 & line_row1 <= 3 )
      if ( 1 <= line_row2 & line_row2 <= 3 )

        i1 = 3 * ( box_row - 1 ) + line_row1;
        i2 = 3 * ( box_row - 1 ) + line_row2;

        t(1, 1:9) = s(i1,1:9);
        s(i1,1:9) = s(i2,1:9);
        s(i2,1:9) = t(1, 1:9);

      end
    end
  end

  return
end


function T=operatormatrix(Op)
%OPERATORMATRIX  Matrix representation of an operator
%   Usage: T=operatormatrix(Op);
%
%   `T=operatormatrix(Op)` returns the matrix representation *T* of the
%   operator *Op*. The operator object *Op* must have been created using
%   |operatornew|.
%
%   See also: operatornew, operator, operatoreigs

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

if ~isstruct(Op)
  error('%s: First argument must be a operator definition structure.',upper(mfilename));
end;

T=operator(Op,eye(Op.L));


function res = clipPolyline(poly, box)
%CLIPPOLYLINE Clip an open polyline with a rectangular box.
%
%   POLY2 = clipPolyline(POLY, BOX);
%   POLY is N-by-2 array of vertex coordinates.
%   BOX has the form: [XMIN XMAX YMIN YMAX].
%   Returns the set of polylines created by the intersection of the
%   polyline POLY and the bounding box BOX. The result is a cell array with
%   as many cells as the number of curve clips.
%
%
%   Example
%     circle = [5 5 6];
%     poly = circleToPolygon(circle, 200);
%     box = [0 10 0 10];
%     res = clipPolyline(poly, box);
%     figure;
%     hold on; axis equal; axis([-2 12 -2 12]);
%     drawCircle(circle, 'b:')
%     drawBox(box, 'k')
%     drawPolyline(res, 'linewidth', 2, 'color', 'b')
%
%   See also
%     polygons2d, boxes2d, clipPolygon, clipEdge
%

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2005-05-14
% Copyright 2005-2022 INRA - Cepia Software Platform

% check case of polylines stored in cell array
if iscell(poly)
    res = cell(1, length(poly));
    for i = 1:length(poly)
        res{i} = clipPolyline(poly{i}, box);
    end
    return;
end

% check case of empty polylines
N = size(poly, 1);
if N == 0
    res = cell(0, 0);
    return
end

% create edges array of polyline
edges = [poly(1:N-1, :) poly(2:N, :)];

% clip edges
edges = clipEdge(edges, box);

% select non empty edges, and get their vertices
% find clipped edges within box
inds = sum(abs(edges), 2) > 1e-14;

% find list of adjacent edges within box
dinds = diff(inds);
inds0 = find(dinds == 1) + 1;
if inds(1) == 1
    inds0 = [1 inds0];
end
inds1 = find(dinds == -1);
if inds(end) == 1
    inds1 = [inds1 N-1];
end

nClips = length(inds0);
res = cell(1, nClips);
for iClip = 1:nClips
    range = inds0(iClip):inds1(iClip);
    poly2 = [edges(range, 1:2) ; edges(range(end), 3:4)];
    res{iClip} = poly2;
end


function [C, C_index, C_dist] = DC(S_prefix, S_number, S_profix, r, k)
%
% Discord Candidate
% Authors: Dragomir Yankov, Eamonn Keogh and Umaa Rebbapragada
% Original paper :
% Disk Aware Discord Discovery: Finding Unusual Time Series
% in Terabyte Sized Datasets
% Website : http://www.cs.ucr.edu/~eamonn/selected_publications.htm
% e-mail : {dyankov,eamonn}@cs.ucr.edu, urebbapr@cs.tufts.edu
% Programmer: Wei-Chih Lai
%
% Inputs
%   S_prefix: a string as prefix for path of files
%   S_number: 1x1 integer means number of files
%   S_profix: a string as profix for path of files
%   r: 1x1 integer means threshold
%   k: 1x1 integer means number of top outliers
%
% Outputs
%   C: kxn vector
%      outlier instances
%   C_index: kx1 vector
%      index of outliers in origin datasets
%   C_dist: kx1 vector
%      distance of outliers
%
    assert(k > 0);
    [C, C_index] = DC_Selection(S_prefix, S_number, S_profix, r);
    [C, C_dist] = DC_Refinement(S_prefix, S_number, S_profix, C, C_index, r);
    [~, index] = sort(C_dist, 'descend');
    index = index(1:min(size(C_dist, 1), k), 1);
    C = C(index, :);
    C_index = C_index(index, :);
    C_dist = C_dist(index, :);


function r8mat_ref_test ( )

%*****************************************************************************80
%
%% R8MAT_REF_TEST tests R8MAT_REF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 October 2008
%
%  Author:
%
%    John Burkardt
%
  m = 4;
  n = 7;

  a = [ ...
    1.0, -2.0, 3.0, -1.0; ...
    3.0, -6.0, 9.0, -3.0; ...
    0.0,  0.0, 0.0,  0.0; ...
    2.0, -2.0, 0.0,  1.0; ...
    6.0, -8.0, 6.0,  0.0; ...
    3.0,  3.0, 6.0,  9.0; ...
    1.0,  1.0, 2.0,  3.0 ]';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8MAT_REF_TEST\n' );
  fprintf ( 1, '  R8MAT_REF computes the row echelon form of a matrix.\n' );

  r8mat_print ( m, n, a, '  Input A:' );

  a = r8mat_ref ( m, n, a );

  r8mat_print ( m, n, a, '  REF form:' );

  return
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   Q = INVERSEKINEMATIC_tx200l(robot, T)
%   Solves the inverse kinematic problem for the STAUBLI tx200l robot
%   where:
%   robot stores the robot parameters.
%   T is an homogeneous transform that specifies the position/orientation
%   of the end effector.
%
%   A call to Q=INVERSEKINEMATIC_tx200l returns 8 possible solutions, thus,
%   Q is a 6x8 matrix where each column stores 6 feasible joint values.
%
%
%   Example code:
%
%   robot=load_robot('staubli', 'tx200l');
%   q = [0 0 0 0 0 0];
%   T = directkinematic(robot, q);
%   %Call the inversekinematic for this robot
%   qinv = inversekinematic(robot, T);
%   check that all of them are feasible solutions!
%   and every Ti equals T
%   for i=1:8,
%        Ti = directkinematic(robot, qinv(:,i))
%   end
%	See also DIRECTKINEMATIC.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Copyright (C) 2012, by Carlos Pardo Pla
%
% This file is part of ARTE (A Robotics Toolbox for Education).
%
% ARTE is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% ARTE is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with ARTE.  If not, see <http://www.gnu.org/licenses/>.
function q = inversekinematic_tx200l(robot, T)

%initialize q,
%eight possible solutions are generally feasible
q=zeros(6,8);

%Evaluate the parameters
theta = eval(robot.DH.theta);
d = eval(robot.DH.d);
a = eval(robot.DH.a);
alpha = eval(robot.DH.alpha);

%See geometry at the reference for this robot
L6=abs(d(6));

A1 = a(1);

%T= [ nx ox ax Px;
%     ny oy ay Py;
%     nz oz az Pz];
Px=T(1,4);
Py=T(2,4);
Pz=T(3,4);

%Compute the position of the wrist, being W the Z component of the end effector's system
W = T(1:3,3);

% Pm: wrist position
Pm = [Px Py Pz]' - L6*W;

%first joint, two possible solutions admited:
% if q(1) is a solution, then q(1) + pi is also a solution
q1=atan2(Pm(2), Pm(1));

%solve for q2
q2_1=solve_for_theta2(robot, [q1 0 0 0 0 0 0], Pm);

q2_2=solve_for_theta2(robot, [q1+pi 0 0 0 0 0 0], Pm);

%solve for q3
q3_1=solve_for_theta3(robot, [q1 0 0 0 0 0 0], Pm);

q3_2=solve_for_theta3(robot, [q1+pi 0 0 0 0 0 0], Pm);

%Arrange solutions, there are 8 possible solutions so far.
% if q1 is a solution, q1* = q1 + pi is also a solution.
% For each (q1, q1*) there are two possible solutions
% for q2 and q3 (namely, elbow up and elbow up solutions)
% So far, we have 4 possible solutions. Howefer, for each triplet (theta1, theta2, theta3),
% there exist two more possible solutions for the last three joints, generally
% called wrist up and wrist down solutions. For this reason,
%the next matrix doubles each column. For each two columns, two different
%configurations for theta4, theta5 and theta6 will be computed. These
%configurations are generally referred as wrist up and wrist down solution
q = [q1         q1         q1        q1       q1+pi   q1+pi   q1+pi   q1+pi;
     q2_1(1)    q2_1(1)    q2_1(2)   q2_1(2)  q2_2(1) q2_2(1) q2_2(2) q2_2(2);
     q3_1(1)    q3_1(1)    q3_1(2)   q3_1(2)  q3_2(1) q3_2(1) q3_2(2) q3_2(2);
     0          0          0         0         0      0       0       0;
     0          0          0         0         0      0       0       0;
     0          0          0         0         0      0       0       0];

%leave only the real part of the solutions
q=real(q);

%normalize q to [-pi, pi]
q(1,:) = normalize(q(1,:));
q(2,:) = normalize(q(2,:));

% solve for the last three joints
% for any of the possible combinations (theta1, theta2, theta3)
for i=1:2:size(q,2),
    qtemp = solve_spherical_wrist_tx200l(robot, q(:,i), T, 1); %wrist up
    qtemp(4:6)=normalize(qtemp(4:6));
    q(:,i)=qtemp;

    qtemp = solve_spherical_wrist_tx200l(robot, q(:,i), T, -1); %wrist down
    qtemp(4:6)=normalize(qtemp(4:6));
    q(:,i+1)=qtemp;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% solve for second joint theta2, two different
% solutions are returned, corresponding
% to elbow up and down solution
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function q2 = solve_for_theta2(robot, q, Pm)

%Evaluate the parameters
d = eval(robot.DH.d);
a = eval(robot.DH.a);

%See geometry
L2=abs(a(2));
L3=abs(d(4));

%given q1 is known, compute first DH transformation
T01=dh(robot, q, 1);

%Express Pm in the reference system 1, for convenience
p1 = inv(T01)*[Pm; 1];

r = sqrt(p1(1)^2 + p1(2)^2);

beta = atan2(-p1(2), p1(1));
gamma =(acos((L2^2+r^2-L3^2)/(2*r*L2)));

if ~isreal(gamma)
    disp('WARNING:inversekinematic_tx200l: the point is not reachable for this configuration, imaginary solutions');
    %gamma = real(gamma);
end

%return two possible solutions
%elbow up and elbow down
%the order here is important and is coordinated with the function
%solve_for_theta3
q2(1) = pi/2 - beta - gamma; %elbow up
q2(2) = pi/2 - beta + gamma; %elbow down

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% solve for third joint theta3, two different
% solutions are returned, corresponding
% to elbow up and down solution
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function q3 = solve_for_theta3(robot, q, Pm)

%Evaluate the parameters
d = eval(robot.DH.d);
a = eval(robot.DH.a);

%See geometry
L2=abs(a(2));
L3=abs(d(4));

%given q1 is known, compute first DH transformation
T01=dh(robot, q, 1);

%Express Pm in the reference system 1, for convenience
p1 = inv(T01)*[Pm; 1];

r = sqrt(p1(1)^2 + p1(2)^2);

eta =(acos((L2^2 + L3^2 - r^2)/(2*L2*L3)));

if ~isreal(eta)
   disp('WARNING:inversekinematic_tx200l: the point is not reachable for this configuration, imaginary solutions');
   %eta = real(eta);
end

%return two possible solutions
%elbow up and elbow down solutions
%the order here is important
q3(1) = pi - eta;
q3(2) = eta - pi;

% Solve the special case of this spherical wrist
% For wrists that whose reference systems have been placed as in the
% ABB IRB 140--> use solve_spherical_wrist2
% For wrists with the same orientation as in the KUKA KR30_jet
%--> use solve_spherical_wrist
function q = solve_spherical_wrist_tx200l(robot, q, T, wrist)

% T is the noa matrix defining the position/orientation of the end
% effector's reference system
vx6=T(1:3,1);
vz5=T(1:3,3); % The vector a z6=T(1:3,3) is coincident with z5

% Obtain the position and orientation of the system 3
% using the already computed joints q1, q2 and q3
T01=dh(robot, q, 1);
T12=dh(robot, q, 2);
T23=dh(robot, q, 3);
T03=T01*T12*T23;

vx3=T03(1:3,1);
vy3=T03(1:3,2);
vz3=T03(1:3,3);

% find z4 normal to the plane formed by z3 and a
vz4=cross(vz3, vz5);	% end effector's vector a: T(1:3,3)

% in case of degenerate solution,
% when vz3 and vz6 are parallel--> then z4=0 0 0, choose q(4)=0 as solution
if norm(vz4) <= 0.00000001
    if wrist == 1 %wrist up
        q(4)=0;
    else
        q(4)=-pi; %wrist down
    end
else
    %this is the normal and most frequent solution
    cosq4=wrist*dot(vy3,vz4);
    sinq4=wrist*dot(-vx3,vz4);
    q(4)=atan2(sinq4, cosq4);
end
%propagate the value of q(4) to compute the system 4
T34=dh(robot, q, 4);
T04=T03*T34;
vx4=T04(1:3,1);
vy4=T04(1:3,2);

% solve for q5
cosq5=dot(-vy4,vz5);
sinq5=dot(vx4,vz5);
q(5)=atan2(sinq5, cosq5);

%propagate now q(5) to compute T05
T45=dh(robot, q, 5);
T05=T04*T45;
vx5=T05(1:3,1);
vy5=T05(1:3,2);

% solve for q6
cosq6=dot(vx6,vx5);
sinq6=dot(vx6,vy5);
q(6)=atan2(sinq6, cosq6);


 function centers = lloyd_max_hist(data, centers, MM, tol, max_iter, chat)
%function centers = lloyd_max_hist(data, centers, MM, tol, max_iter, chat)
%|
%| "improved" version of the lloyd-max algorithm for scalar quantizer design
%| that saves computation by histogramming the data first.
%| Before using this, try using highrate_centers() first!
%|
%| in
%|	data	[N 1]	training data
%|	centers	[K 1]	initial guess of centroids (codebook)
%|	MM		# of histogram bins: K < M < N
%| out
%|	centers [K 1]	final centroids
%|
%| Copyright 2004-7-1, Jeff Fessler, University of Michigan

if nargin == 1 && streq(data, 'test'), lloyd_max_hist_test, return, end
if nargin < 2, ir_usage, end
if nargin < 3, MM = 0; end
if nargin < 4, tol = 1e-3; end
if nargin < 5, max_iter = 40; end
if nargin < 6, chat = 0; end

data = data(:);
Norig = length(data);
if MM
	if ~isreal(data)
		if length(MM) == 1
			MM = [MM MM];
		end
		[wt data] = hist_equal([real(data) imag(data)], MM);
		[dr di] = ndgrid(data(:,1), data(:,2));
		data = dr + 1i * di;
	else
		[wt data] = hist(data, MM);
	end
	data = data(:);
	wt = wt(:);
	% eliminate data bins with 0 wt
	data = data(wt ~= 0);
	wt = wt(wt ~= 0);
else
	wt = ones(size(data));
end

K = length(centers);
if length(unique(centers)) ~= K
	error 'initial centers are not unique'
end
redundant = 0;
if K > length(data)
	if K > Norig
		warning(sprintf('#centroids %d > #data %d!?', K, Norig))
	else
		printf('Warn: #centroids %d > #unique(data) %d.', K, length(data))
	end
	redundant = 1;
end

tol = tol * max(abs(data));
iter = 1;
change = inf;
while iter <= max_iter && change > tol
	if ~redundant && (length(unique(centers)) ~= K)
		warning 'centers became not unique'
	end
	index = quant1_index(data, centers);
	old = centers;
	for kk=1:K
		ik = index == kk;
		if sum(ik)
			if ~sum(wt(ik))
				warning 'bug?'
				keyboard
			end
			centers(kk) = sum(data(ik) .* wt(ik)) ./ sum(wt(ik));
		else
			centers(kk) = NaN;
		end
	end

	% assign any unused centers to the data point(s) furthest from centroids
	if redundant
		centers(isnan(centers)) = 0;
	elseif any(isnan(centers))
		printm('fixing unused centers %d', sum(isnan(centers)))
		while any(isnan(centers))
			cgood = col(centers(~isnan(centers)));
			index = quant1_index(data, cgood);
			dhat = cgood(index);
			iworst = imax(abs(data - dhat));
			knan = find(isnan(centers));
			centers(knan(1)) = data(iworst);
		end
	end
%	disp([iter centers])
	change = max(abs(centers - old));
	iter = iter + 1;
end
if iter == max_iter + 1
	warning 'max %d iterations reached'
end
if chat
	printf('%s: %d iterations', mfilename, iter)
end

% quant1_index()
% find index of nearest centroid.
% this version works even for complex data / centroids
%
function index = quant1_index(x, centers)
[dummy index] = min(abs(outer_sum(x, -centers)), [], 2);
%breaks = (centers(2:end) + centers(1:end-1)) / 2;
%index0 = 1 + sum(outer_sum(x, -breaks) > 0, 2);
%minmax(index-index0)

% quant1_rms()
% rms error between data and its quantized version (complex ok)
%
function rms = quant1_rms(x, centers)
index = quant1_index(x, centers);
rms = sqrt(mean(abs(x(:) - col(centers(index))).^2));

% lloyd_max_hist_test
% self test: compare this approach to matlab's lloyds routine
function lloyd_max_hist_test
rng(0)
x = [10*randn(10^4,1); 50 + 15*randn(10^4,1)];
%x = [10*rand(10^4,1); 50 + 15*rand(10^4,1)];

L = 5;
%c0 = 10*linspace(-1,1,L);
pn = jf_protected_names;
c0 = pn.prctile(x, 100*([1:L]-0.5)/L);

[nx cx] = hist(x, 100);

ch = highrate_centers(x, L);

if exist('lloyds') == 2
	tic
	[p1 c1] = lloyds(x, c0);
	t1 = toc;
else
	p1 = nan(L,1);
	c1 = nan(L,1);
	t1 = nan;
end

tic
c2 = lloyd_max_hist(x, c0, 50);
t2 = toc;

o = ones(L,1);
if im
	plot(cx, nx, '-', c0, 80*o, 'yo', ch, 60*o, 'yx', ...
		c1, 40*o, 'ys', c2, 20*o, 'y^')
	legend('hist', 'c0', 'highrate', 'lloyds', 'hist')
end

tic
c3 = lloyd_max_hist(x, c0);
t3 = toc;

if exist('quantiz') == 2
	[dum1 dum2 distor] = quantiz(x, p1, c1);
else
	distor = nan;
end

rms0 = quant1_rms(x, c0);
rms1 = quant1_rms(x, c1);
rms2 = quant1_rms(x, c2);
rms3 = quant1_rms(x, c3);
rmsh = quant1_rms(x, ch);
printf('lloyds matlab time=%g rms=%g distor=%g', t1, rms1, sqrt(distor))
printf('lloyd_max_hist time=%g rms=%g', t2, rms2)
printf('lloyd_max (no hist) time=%g rms=%g', t3, rms3)
printf('rms0=%g rmsh=%g', rms0, rmsh)
if im
	disp([c0, c1, c2, c3])
end


function W = freqindex(W,varargin)

% WAVEFORM = FREQINDEX(WAVEFORM) calculates the frequency index of a waveform.
% The FI is stored as a new field called FFT_FI. This function must be run after
% WF_FFT.COMPUTE so that the necessary spectral fields exist in advance
%
% WAVEFORM = FREQINDEX(WAVEFORM,1) includes a plot of the waveform, and the
% frequency spectrum with the FI frequency bins shaded by their appropriate
% heights. If WAVEFORM is a vector, plots will only be included for the
% first five waveforms. This is a bit ad hoc, but it prevents accidental
% plotting of thousands of waveforms. To plot specific waveforms one can
% always use freqindex(w(n)) where n is the index of the nth waveform.
%
% See also wf_fft.compute wf_fft.plot

% Author: Michael West, Geophysical Institute, Univ. of Alaska Fairbanks
% $Date$
% $Revision$

DOPLOT = 0;
if length(varargin) == 1
    DOPLOT = varargin{1};
end

% LOOP THROUGH WAVEFORMS (INEFFICIENT CODE!)
for i = 1:length(W)
    w = W(i);

    % GET FFT
    %W(i) = demean(W(i));
    %W(i) = wf_fft(W(i));
    F = get(W(i),'FFT_FREQ');
    A  = get(W(i),'FFT_AMP');
    if isempty(F) || isempty(A)
    	%W(i) = wf_fft.compute(W(i));
        error(['Trace ' num2str(i) ' does not have FFT_FREQ or FFT_AMP fields. Run WF_FFT.COMPUTE before WF_FFT.FREQINDEX' ]);
    end
    %A = A .* A;
    j = find(F >= 1 & F <= 2);
    Al = mean(A(j));
    j = find(F >= 10 & F <= 20);
    Ah = mean(A(j));
    fi = log10(Ah/Al);
    W(i) = addfield(W(i),'FFT_FI',fi);

    % PLOT IT
    if DOPLOT && i<=5

        figure('Color','w');
        set(gcf,'DefaultAxesFontSize',14);

        subplot(2,1,1);
        plot(w);
        title(datestr(get(w,'START'),31));

        subplot(2,1,2);
        hold on;
        fill( [1 1 2 2] , [0 Al Al 0] , [.7 .7 .7]);
        fill( [10 10 20 20] , [0 Ah Ah 0] , [.7 .7 .7]);
        plot( F , A , 'r-' );
        xlabel('Frequency (Hz)');
        ylabel('Power');
        set(gca,'XScale','Log');
        grid on; box on;
        xlim([0.1 50]);
        title(['Frequency index: ' num2str(fi,'%5.2f')]);

    end

end


function [ m, d ] = thanksgiving_canada ( y )

%*****************************************************************************80
%
%% THANKSGIVING_CANADA computes Canadian Thanksgiving for a Common year.
%
%  Discussion:
%
%    Canadian Thanksgiving occurs on the second Monday in October.
%
%  Example:
%
%    Input:
%
%      Y = 2002
%
%    Output:
%
%      M = 11
%      D = 28
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 September 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, the year.
%
%    Output, integer M, D, the month and day of Thanksgiving.
%

%
%  Determine the day of the week for 8 October, the earliest day
%  that Thanksgiving can occur.
%
  m = 10;
  d = 8;
  f = 0.0;

  w = ymdf_to_weekday_common ( y, m, d, f );
%
%  If W = 2 means this day is Monday, and day D is Thanksgiving.
%  Otherwise, figure out how to increment W to 2;
%  The same increment makes D the correct day number.
%
  if ( w < 2 )
    d = d + 2 - w;
  elseif ( 2 < w )
    d = d + 2 + 7 - w;
  end

  return
end


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

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @deftypemethod  @@sym {} max (@var{a})
%% @deftypemethodx @@sym {} max (@var{a}, @var{b})
%% @deftypemethodx @@sym {} max (@var{a}, [], @var{dim})
%% @deftypemethodx @@sym {[@var{r}, @var{I}] =} max (@dots{})
%% Return maximum value of a symbolic vector or vectors.
%%
%% Example:
%% @example
%% @group
%% max(sym(1), sym(2))
%%   @result{} (sym) 2
%% max([1 2*sym(pi) 6])
%%   @result{} (sym) 2⋅π
%% [M, I] = max([1 2*sym(pi) 6])
%%   @result{} M = (sym) 2⋅π
%%   @result{} I = 2
%% @end group
%% @end example
%%
%% @seealso{@@sym/min}
%% @end deftypemethod

function [z, I] = max(A, B, dim)

  if (nargout <= 1)
    if (nargin == 1)
      if (isvector(A))
        z = pycall_sympy__ ('return Max(*_ins[0])', A);
      else
        z = max(A, [], 1);
      end
    elseif (nargin == 2)
      z = elementwise_op ('Max', sym(A), sym(B));
    elseif (nargin == 3)
      assert (isempty (B))
      assert (logical(dim == 1) || logical(dim == 2))

      cmd = { '(A, dim) = _ins'
              'if not A.is_Matrix:'
              '    A = sp.Matrix([A])'
              'if dim == 0:'
              '    if A.rows == 0:'
              '        return A'
              '    return Matrix([[Max(*A.col(i)) for i in range(0, A.cols)]])'
              'elif dim == 1:'
              '    if A.cols == 0:'
              '        return A'
              '    return Matrix([Max(*A.row(i)) for i in range(0, A.rows)])' };
      z = pycall_sympy__ (cmd, A, dim - 1);
    else
      print_usage ();
    end
    return
  end

  % dealing with the index (2nd output) is complicated, defer to min
  if (nargin == 1)
    [z, I] = min(-A);
    z = -z;
  elseif (nargin == 3)
    [z, I] = min(-A, -B, dim);
    z = -z;
  else
    print_usage ();
  end

end

%% many other tests are in @sym/min

%!test
%! % simple
%! assert (isequal (max([sym(10) sym(11)]), sym(11)))

%!test
%! syms x y
%! assert (isequal (children (max (x, y)), [x y]))


lw=2;
fz=20;

data_fb_real =load('much_longer_fb_real.log');
data_fac_real=load('much_longer_fac_real.log');
data_ola_real=load('much_longer_ola_real.log');

% Columns in data, fb : a M L W gl time
% Columns in data, fac: a M L W time
% Columns in data, ola: a M L W gl bl time

Ls=data_fac_real(:,3);
t_fb_real =data_fb_real(:,6);
t_fac_real=data_fac_real(:,5);
t_ola_real=data_ola_real(:,7);

if 0
  % Color legend
  l1='b';
  l2='b--';
  l3='r';
  l4='r--';
else
  % bw legend
  l1='b';
  l2='b--';
  l3='b-.';
  l4='b:';
end;

figure(1);

M=data_fac_real(1,2);
L=data_fac_real(:,3);

plot(Ls,t_fb_real,l1,...
     Ls,t_fac_real,l2,...
     Ls,t_ola_real,l3,'LineWidth',lw);
set(gca,'Fontsize',fz);

h=legend('Portnoff, real','Fac, real','Fac-OLA, real',...
       'Location','NorthWest');

% Grow the box a little, otherwise the export to .eps is messed up.
q=get(h,'Position');
set(h,'Position',[q(1)*.9 q(2)*.95 q(3)*1.8 q(4)]);

xlabel('Signal length / samples','Fontsize',fz);
ylabel('Running time / seconds','Fontsize',fz);

print -deps plot_much_longer_1.eps


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

%% Syntax
% |[Ep,Vp,Cp]=pillowHex(E,V,C,shrinkFactor);|

%% Description
%

%%
clear; close all; clc;

%%
% Plot settings
fontSize=25;
faceAlpha1=0.25;
edgeWidth=2;
markerSize=35;
cMap=gjet(6);

%% Examples
%

%% Example: Pillowing a hexahedral element

%%
% Creating an example hexahedral element
V=[0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1;]; %nodes
E=1:8; %Element

%%

shrinkFactor=0.5;
[Ep,Vp]=pillowHex(E,V,[],shrinkFactor);

%%
% Visualize results

[F]=element2patch(E);  %Patch data for plotting
[Fp]=element2patch(Ep);  %Patch data for plotting

cFigure;

subplot(1,2,1); hold on;
title('Original hex element','FontSize',fontSize);
gpatch(F,V,'gw','g',0.5,edgeWidth);
% patchNormPlot(F,V,0.25);
plotV(V,'k.','MarkerSize',markerSize);
colormap(cMap);
axisGeom;
axis off;
camlight headlight;

subplot(1,2,2); hold on;
title('Pillowed hex element','FontSize',fontSize);
gpatch(Fp,Vp,'bw','b',0.5,edgeWidth);
% patchNormPlot(Fp,Vp,0.25);
plotV(Vp,'k.','MarkerSize',markerSize);
colormap(cMap);
axisGeom;
axis off;
camlight headlight;

drawnow;

%% Example: Pillowing a set of hexahedral elements

%%
% Creating an example hexahedral element set
boxDim=[5 6 7];
boxEl=[4 5 6];

[meshStruct]=hexMeshBox(boxDim,boxEl);

E=meshStruct.E;
V=meshStruct.V;
C=(1:1:size(E,1))';

%%
%
shrinkFactor=0.5;
[Ep,Vp,Cp]=pillowHex(E,V,C,shrinkFactor);

%%
% Visualize results
[F,CF]=element2patch(E,C);  %Patch data for plotting
[Fp,CFp]=element2patch(Ep,Cp);  %Patch data for plotting

cFigure;

subplot(1,2,1); hold on;
title('Original hex element','FontSize',fontSize);
gpatch(F,V,CF,'k',0.5);
% patchNormPlot(F,V,0.25);
plotV(V,'k.','MarkerSize',markerSize);
colormap(cMap);
axisGeom;
axis off;
camlight headlight;

subplot(1,2,2); hold on;
title('Pillowed hex element','FontSize',fontSize);
gpatch(Fp,Vp,CFp,'k',0.5);
% patchNormPlot(Fp,Vp,0.25);
plotV(Vp,'k.','MarkerSize',markerSize);
colormap(cMap);
axisGeom;
axis off;
camlight headlight;

drawnow;

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

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


function [X,P]=subPx(g,x,gMax,N)
% clear, load subPxData.mat, N=100;
xi=linspace(x(1),x(end),N*length(x));
gi = interp1(x,g,xi,'spline');
[pk,loc]=peakDetect(gi,0,0);
% in case multiple peaks are detected, the one closest to gMax is chosen
if length(loc)>1
    disp('WARNING: multiple peaks detected')
    [val,id]=min(abs(xi(loc)-x(find(g==gMax))));
else
    id=1;
end
X=xi(loc(id)); P=pk(id);
% figure(1), plot(x,g,'o',xi,gi,'.',xi(L),gi(L),'o')


function ort_vec = get_ort_vec(lew_rgb,mask_local)
% compute the mean color w.r.t pixels covered by the binary saliency mask
    [ii,jj] = find(mask_local~=0);
    ort_vec = zeros(1,3); % RGB color vector
    for k = 1 : length(ii)
        ort_vec(1,1) = ort_vec(1,1) + lew_rgb(ii(k),jj(k),1);
        ort_vec(1,2) = ort_vec(1,2) + lew_rgb(ii(k),jj(k),2);
        ort_vec(1,3) = ort_vec(1,3) + lew_rgb(ii(k),jj(k),3);
    end
    ort_vec = ort_vec / length(ii);
end


function out = disp2str(x)
%DISP2STR     Output of intval x into out
%
%The output produced by disp_(x(:)), infsup(x(:)), or midrad(x(:)),
%  according to the format in use, is returned into  out  as follows:
%
% out.exp  empty if no common exponent printed, otherwise
%            string of common exponent
% out.str  column array of strings representing to x(:)
%

% written  08/29/00     S.M. Rump
% modified 04/04/04     S.M. Rump  set round to nearest for safety
% modified 04/06/05     S.M. Rump  rounding unchanged
% modified 08/26/12     S.M. Rump  global variables removed
%

  INTLAB_INTVAL_DISPLAY = getappdata(0,'INTLAB_INTVAL_DISPLAY');
%VVVV x = x(:);
  x = reshape(x,prod(size(x)),1);
%AAAA Matlab V5.2 bug fix
  switch INTLAB_INTVAL_DISPLAY
    case 'DisplayInfsup', out = infsup(x,[],[]);
    case 'DisplayMidrad', out = midrad(x,[],[]);
    case 'Display_', out = disp_(x,[],[]);
  end


% Function MYGRID_SAND	Read bathymetry data from Sandwell Database
%      [image_data,vlat,vlon] = mygrid_sand(region,iopt)
%
% program to get bathymetry from topo_8.2.img  (Smith and Sandwell bathymetry)
%  (values are even numbered if interpolated, odd-numbered if from a ship sounding)
% WARNING: change DatabasesDir to the correct one for your machine
%						Catherine de Groot-Hedlin
% latitudes must be between -72.006 and 72.006;
%	input:
%		region =[south north west east];
%               iopt = 1 if bathymetry is wanted (default)
%		       2 if ship tracks are wanted
%	output:
%		image_data
%                (for iopt = 1) - matrix of sandwell bathymetry/topography
%                (for iopt = 2) - matrix of ones and zeros, where 1 represents
%                    a ship location, 0 represents a depth based on interpolation
%		vlat - vector of latitudes associated with image_data
%      		vlon - vector of longitudes

%
function  [image_data,vlat,vlon] = mygrid_sand(region,iopt)

    DatabasesDir = '/export/home/grunion/cdh/airforce/sandwell.d';

    % determine the requested region
    blat = region(1);
    tlat = region(2);
    wlon = region(3);
    elon = region(4);

    % Setup the parameters for reading Sandwell data
    db_res         = 2/60;		% 2 minute resolution
    db_loc         = [-72.006 72.006 0.0 360-db_res];
    db_size        = [6336 10800];
    nbytes_per_lat = db_size(2)*2;	% 2-byte integers
    image_data     = [];

    % Determine if the database needs to be read twice (overlapping prime meridian)
    if ((wlon<0)&(elon>=0))
        wlon      = [wlon           0];
        elon      = [360-db_res  elon];
    end

    % Calculate number of "records" down to start (latitude) (0 to db_size(1)-1)
    % (mercator projection)
    rad=pi/180;arg1=log(tan(rad*(45+db_loc(1)/2)));
    arg2=log(tan(rad*(45+blat/2)));
    iblat = fix(db_size(1) +1 - (arg2-arg1)/(db_res*rad))

    arg2=log(tan(rad*(45+tlat/2)));
    itlat = fix(db_size(1) +1 - (arg2-arg1)/(db_res*rad))

    if (iblat < 0 ) | (itlat > db_size(1)-1)
        errordlg([' Requested latitude is out of file coverage ']);
    end

    % Go ahead and read the database
    for i = 1:length(wlon);

        % Open the data file
        fid = fopen([DatabasesDir '/topo_8.2.img'], 'r');
        if (fid < 0)
            errordlg(['Could not open database: ' DatabasesDir '/topo_8.2.img'],'Error');
        end

        % Make sure the longitude data goes from 0 to 360
        if wlon(i) < 0
            wlon(i) = 360 + wlon(i);
        end

        if elon(i) < 0
            elon(i) = 360 + elon(i);
        end

        % Calculate the longitude indices into the matrix (0 to db_size(1)-1)
        iwlon(i) = fix((wlon(i)-db_loc(3))/db_res)
        ielon(i) = fix((elon(i)-db_loc(3))/db_res)
        if (iwlon(i) < 0 ) | (ielon(i) > db_size(2)-1)
            errordlg([' Requested longitude is out of file coverage ']);
        end

        % allocate memory for the data
        data = zeros(iblat-itlat+1,ielon(i)-iwlon(i)+1);

        % Skip into the appropriate spot in the file, and read in the data
        disp('Reading in bathymetry data');
        for ilat = itlat:iblat
            offset = ilat*nbytes_per_lat + iwlon(i)*2;
            status = fseek(fid, offset, 'bof');
            data(iblat-ilat+1,:)=fread(fid,[1,ielon(i)-iwlon(i)+1],'integer*2');
        end

        % close the file
        fclose(fid);

        % put the two files together if necessary
        if (i>1)
            image_data = [image_data data];
        else
            image_data = data;
        end
    end

    % Determine the coordinates of the image_data
    vlat=zeros(1,iblat-itlat+1);
    arg2 = log(tan(rad*(45+db_loc(1)/2.)));
    for ilat=itlat+1:iblat+1;
        arg1 = rad*db_res*(db_size(1)-ilat+0.5);
        term=exp(arg1+arg2);
        vlat(iblat-ilat+2)=2*atan(term)/rad -90;
    end
    vlon=db_res*((iwlon+1:ielon+1)-0.5);
    % now choose between bathymetry and ship track
    if iopt==2
        image_data=mod(image_data,2);
    end
    % to plot it up
    if iopt ==2
        imagesc(vlon,vlat,image_data),axis('xy'),colormap(1-gray)
        title('ship track soundings')
    else
        imagesc(vlon,vlat,image_data),axis('xy'),colormap(jet),colorbar('vert')
        title('Smith and Sandwell bathymetry')
    end
    xlabel('longitude'),ylabel('latitude')


% Laser to Camera calibration parameters (II optim stages)
% 22-Jan-2017 22:26:16
%
% Transformation matrix specifies laser coordinate frame
% in the reference frame of the camera
%
%-- Translation vector (t)
t = [ -0.193510 ; 0.031471 ; -0.094037 ]
%-- Rotation matrix (R)
R = ...
[ -0.523357  0.852009  -0.013370 ;...
  0.117409  0.056561  -0.991472 ;...
  -0.843986  -0.520463  -0.129635 ]


function [str] = printHyperOrbitsMFMSToTextbox(hHyperbolicOrbitsText, waypoints, hOrbitDepart, orbitsIn, orbitsOut, vInfArrive, OUnitVector, vInfMag, form, form2, paddLen)
%printHyperOrbitsMFMSToTextbox Summary of this function goes here
%   Detailed explanation goes here

    hRule = getHRule();

    [vInfRA,vInfDec,~] = cart2sph(OUnitVector(1),OUnitVector(2),OUnitVector(3));
    vInfRA = rad2deg(vInfRA);
    vInfDec = rad2deg(vInfDec);

    str = {};
    str{end+1} = ['Hyperbolic Departure Orbit from ', cap1stLetter(waypoints{1}.name)];
    str{end+1} = hRule;
    str{end+1} = [paddStr('Semi-major Axis = ',paddLen), num2str(hOrbitDepart(1), form), ' km'];
    str{end+1} = [paddStr('Eccentricity = ', paddLen), num2str(hOrbitDepart(2), form2)];
    str{end+1} = [paddStr('Inclination = ',paddLen), num2str(rad2deg(AngleZero2Pi(hOrbitDepart(3))), form), ' deg'];
    str{end+1} = [paddStr('Right Ascension of AN = ',paddLen), num2str(rad2deg(AngleZero2Pi(hOrbitDepart(4))), form), ' deg'];
    str{end+1} = [paddStr('Argument of Periapse = ',paddLen), num2str(rad2deg(AngleZero2Pi(hOrbitDepart(5))), form), ' deg'];
    str{end+1} = '---------------------';
    str{end+1} = [paddStr('Out. Hyp. Vel. Vect Rt. Asc. = ',paddLen), num2str(vInfRA, form), ' deg'];
    str{end+1} = [paddStr('Out. Hyp. Vel. Vect Declin. = ',paddLen), num2str(vInfDec, form), ' deg'];
    str{end+1} = [paddStr('Out. Hyp. Vel. Magnitude = ',paddLen), num2str(vInfMag, form2), ' km/s'];

    for(i=2:length(waypoints)) %#ok<*NO4LP>
        if(i < length(waypoints))
            [~, flyByRp] = computeApogeePerigee(orbitsIn(i-1,1), orbitsIn(i-1,2));

            str{end+1} = hRule;
            str{end+1} = ['Inbound Hyperbolic Flyby Orbit to ', cap1stLetter(waypoints{i}.name)];
            str{end+1} = hRule;
            str{end+1} = [paddStr('Semi-major Axis = ',paddLen), num2str(orbitsIn(i-1,1), form), ' km'];
            str{end+1} = [paddStr('Eccentricity = ', paddLen), num2str(orbitsIn(i-1,2), form2)];
            str{end+1} = [paddStr('Inclination = ',paddLen), num2str(rad2deg(AngleZero2Pi(orbitsIn(i-1,3))), form), ' deg'];
            str{end+1} = [paddStr('Right Ascension of AN = ',paddLen), num2str(rad2deg(AngleZero2Pi(orbitsIn(i-1,4))), form), ' deg'];
            str{end+1} = [paddStr('Argument of Periapse = ',paddLen), num2str(rad2deg(AngleZero2Pi(orbitsIn(i-1,5))), form), ' deg'];
            str{end+1} = [paddStr('Periapse Radius = ',paddLen), num2str(flyByRp, form), ' km'];

            hOrbit = orbitsOut(i-1,:);
            [~, OUnitVector, vInfMag] = computeHyperSVectOVect(hOrbit(1), hOrbit(2), hOrbit(3), hOrbit(4), hOrbit(5), 0.0, waypoints{i}.gm);
            OUnitVector = normVector(OUnitVector);
            [vInfRA,vInfDec,~] = cart2sph(OUnitVector(1),OUnitVector(2),OUnitVector(3));
            vInfRA = rad2deg(vInfRA);
            vInfDec = rad2deg(vInfDec);

            str{end+1} = hRule;
            str{end+1} = ['Outbound Hyperbolic Flyby Orbit from ', cap1stLetter(waypoints{i}.name)];
            str{end+1} = hRule;
            str{end+1} = [paddStr('Semi-major Axis = ',paddLen), num2str(orbitsOut(i-1,1), form), ' km'];
            str{end+1} = [paddStr('Eccentricity = ', paddLen), num2str(orbitsOut(i-1,2))];
            str{end+1} = [paddStr('Inclination = ',paddLen), num2str(rad2deg(AngleZero2Pi(orbitsOut(i-1,3))), form), ' deg'];
            str{end+1} = [paddStr('Right Ascension of AN = ',paddLen), num2str(rad2deg(AngleZero2Pi(orbitsOut(i-1,4))), form), ' deg'];
            str{end+1} = [paddStr('Argument of Periapse = ',paddLen), num2str(rad2deg(AngleZero2Pi(orbitsOut(i-1,5))), form), ' deg'];
            str{end+1} = [paddStr('Periapse Radius = ',paddLen), num2str(flyByRp, form), ' km'];
            str{end+1} = '---------------------';
            str{end+1} = [paddStr('Out. Hyp. Vel. Vect Rt. Asc. = ',paddLen), num2str(vInfRA, form), ' deg'];
            str{end+1} = [paddStr('Out. Hyp. Vel. Vect Declin. = ',paddLen), num2str(vInfDec, form), ' deg'];
            str{end+1} = [paddStr('Out. Hyp. Vel. Magnitude = ',paddLen), num2str(vInfMag, form2), ' km/s'];
        else
            [vInfRA,vInfDec,~] = cart2sph(vInfArrive(1),vInfArrive(2),vInfArrive(3));
            vInfRA = rad2deg(vInfRA);
            vInfDec = rad2deg(vInfDec);

            str{end+1} = hRule;
            str{end+1} = ['Inbound Hyperbolic Orbit to ', cap1stLetter(waypoints{i}.name)];
            str{end+1} = hRule;
            str{end+1} = [paddStr('Inb. Hyp. Vel. Vect Rt. Asc. = ',paddLen), num2str(vInfRA, form), ' deg'];
            str{end+1} = [paddStr('Inb. Hyp. Vel. Vect Declin. = ',paddLen), num2str(vInfDec, form), ' deg'];
            str{end+1} = [paddStr('Inb. Hyp. Vel. Magnitude = ',paddLen), num2str(norm(vInfArrive), form), ' km/s'];
%             str{end+1} = [paddStr('Hyperbolic Excess Vel. = ',paddLen), num2str(norm(vInfArrive), form), ' km/s'];
        end
    end

    set(hHyperbolicOrbitsText,'String',str);
end


function [wins] = identify_subj_wins_is(ekg_RSlinB_am_ELF, ekg_RSlinB_bw_ELF, ekg_RSlinB_fm_ELF, up)
%UNTITLED4 Summary of this function goes here
%   Detailed explanation goes here

%% Identify start and end times of each respiratory signal
respSigs.ekg_RSlinB_am_ELF = ekg_RSlinB_am_ELF; respSigs.ekg_RSlinB_bw_ELF = ekg_RSlinB_bw_ELF; respSigs.ekg_RSlinB_fm_ELF = ekg_RSlinB_fm_ELF;
respSig_names = fieldnames(respSigs);
[timings.start, timings.end] = deal(nan(length(respSig_names),1));
for sig_no = 1 : length(respSig_names)
    eval(['rel_data = respSigs.' respSig_names{sig_no} '.t;']);
    timings.start(sig_no) = rel_data(1);
    timings.end(sig_no) = rel_data(end);
end

latest_start = max(timings.start);
earliest_end = min(timings.end);

%% Define windows
duration_of_one_win = up.paramSet.winLeng;
no_of_secs_bet_con_wins = up.paramSet.winStep;
gap_between_win_starts = duration_of_one_win - no_of_secs_bet_con_wins;
wins.t_start = latest_start : gap_between_win_starts : (earliest_end - duration_of_one_win);
wins.t_end = wins.t_start + duration_of_one_win;

end


function tauxovertau = tau_prob ( fh, fhx, ch, chx )

%*****************************************************************************80
%
%% TAUPROB evaluates the derivative of TAU with respect to (X/TAU).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 November 2005
%
%  Parameters:
%
  global alpha1
  global alpha2
  global beta1
  global beta2
  global gamma1
  global gamma2

  cprod = ( ch + alpha1 ) * ( ch + alpha2 );
  fprod = ( fh + beta1 ) * ( fh + beta2 );
  dela = alpha2 - alpha1;
  delb = beta2 - beta1;
  tauxovertau = gamma1 * dela * chx / cprod + gamma2 * fhx * delb / fprod;

  return
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Forward FFT w.r.t. the second variable %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function fs=fty(s);
 fs=fftshift(fft(fftshift(s.'))).';


function [scanOut3M,bbox3M] = cropAroundCOM(scanNum,strName,outputImgSizeV,...
                              bkgVal,planC)
% cropAroundCOM.m
% Crop input scan to specified dimensions around center of mass.
%--------------------------------------------------------------------------
% INPUTS
% scanNum            : Input scan no.
% strName            : Structure to crop around
% outputImgSizeV     : Output dimensions [rows, cols, slcs]
% bkgVal             : User-input intensity assigned to voxels outside
%                      strName. Leave empty to skip.
% planC
%--------------------------------------------------------------------------
% AI 04/22/22

%% Get input scan array
indexS = planC{end};
scan3M = double(getScanArray(scanNum,planC));
CToffset = double(planC{indexS.scan}(scanNum).scanInfo(1).CTOffset);
scan3M = scan3M - CToffset;
origSizV = size(scan3M);

if length(outputImgSizeV)==2
    outputImgSizeV(3) = size(scan3M,3);
end

%% Get structure mask
strNum = getMatchingIndex(strName,...
    {planC{indexS.structures}.structureName},'exact');
assocScanV = getStructureAssociatedScan(strNum,planC);

% Check for associated scan num
if isempty(strNum)
    error('Structure ''%s'' not found.',strName)
else
    strNum = strNum(assocScanV == scanNum);
    if isempty(strNum)
        error('Structure ''%s'' not found.',strName);
    end
end
cropStr3M = getStrMask(strNum,planC);

%Assign bkg intensity
if ~isempty(bkgVal)
   scan3M(~cropStr3M) = bkgVal;
end

%% Crop around COM

%Compute COM (3D)
bbox3M = false(origSizV);
%[x3M, y3M, z3M] = ndgrid(1:origSizV(1), 1:origSizV(2), 1:origSizV(3));
%COMv = round(mean([x3M(cropStr3M), y3M(cropStr3M), z3M(cropStr3M)]));
[rV, cV, sV] = find3d(cropStr3M);
COMv = round(mean([rV; cV; sV],2));

%Compute crop extents around COM
rStart = max(1,COMv(1)-outputImgSizeV(1)/2);
cStart = max(1,COMv(2)-outputImgSizeV(2)/2);

rEnd = min(COMv(1)+outputImgSizeV(1)/2, origSizV(1));
cEnd = min(COMv(2)+outputImgSizeV(2)/2, origSizV(2));

if ~isequal(outputImgSizeV(3),origSizV(3))
    sEnd = min(COMv(3)+outputImgSizeV(3)/2,origSizV(3));
    sStart = max(1,COMv(3)-outputImgSizeV(3)/2);
else
    sStart = 1;
    sEnd = outputImgSizeV(3) + 1;
end

%% Calc. padding required for specified output dimensions where needed
cropSizV = [rEnd - rStart, cEnd - cStart, sEnd - sStart];
if cropSizV(1)<outputImgSizeV(1)
    xPad = floor(outputImgSizeV(1)/2 - cropSizV(1)/2);
else
    xPad = 1;
end
if cropSizV(2)<outputImgSizeV(2)
    yPad = floor(outputImgSizeV(2)/2 - cropSizV(2)/2);
else
    yPad = 1;
end
if cropSizV(3)<outputImgSizeV(3)
    zPad = floor(outputImgSizeV(3)/2 - cropSizV(3)/2);
else
    zPad = 1;
end

%% Populate output scan
% Initialize output scan array
cornerCube = scan3M(1:5,1:5,1:5);
bgMean = mean(cornerCube(:));
scanOut3M = bgMean*ones([outputImgSizeV(1:2),size(scan3M,3)]);

%Populate with cropped scan
bbox3M(rStart:rEnd-1,cStart:cEnd-1,sStart:sEnd-1) = true;
scanCropM = scan3M(rStart:rEnd-1,cStart:cEnd-1,sStart:sEnd-1);
scanOut3M(xPad:xPad+cropSizV(1)-1,yPad:yPad+cropSizV(2)-1,...
    zPad:zPad+cropSizV(3)-1) = scanCropM;

end


function [data_rec] = gtmexpimpute(net, data)
%GTMEXPIMPUTE Impute missing data using GTM expected values
%
%	Description
%	 DATA_REC = GTMEXPIMPUTE(NET, DATA) takes a GTM structure NET, and
%	imputes the missing values in DATA according to expectation of hidden
% variables given observed data.
%
%	See also
%	GTM, GTMEM, GTMLMEAN, GMLMODE, GMMPROB

% Copyright (c) Tommi Vatanen (2012)

% Check for consistency
errstring = consist(net, 'gtm', data);
if ~isempty(errstring)
  error(errstring);
end

data_rec = data;
missing = isnan(data_rec);

net.gmmnet.centres = rbffwd(net.rbfnet, net.X);
R = gmmpost(net.gmmnet, data);

rec = R*net.gmmnet.centres;
data_rec(missing) = rec(missing);


function g = sqrt(f)
%SQRT   Square root of a BALLFUN.
%   SQRT(F) is the square root of a BALLFUN F.

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

g = compose( f, @sqrt );

end


function [B,m,ps,Population] = UpdateParameter(Problem,Population)
% Update the parameters in ARSBX

%--------------------------------------------------------------------------
% 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".
%--------------------------------------------------------------------------

    PopDec = Population.decs;
    Flag   = Population.adds(zeros(length(Population),1));
    Ori    = sum(Flag == 1);
    Eig    = sum(Flag == 2);
    ps     = 1/(1+exp(-Problem.M*sqrt(Problem.D)*((Ori+1)/(Eig+Ori+2)-0.5)*Problem.FE/Problem.maxFE));
    C        = cov(PopDec);
    [B,E]    = eig(C);
    E        = diag(E);
    E        = sqrt(E);
    [~,Rank] = sort(E,'descend');
    B        = B(:,Rank);
    m        = mean(PopDec);
end


function [xi,yi,curvatures] = maxr(a)
%MAXR   Find interpolated maximizer(s) and max value(s)
%       for (each column of) a.
%
%               [xi,yi,curvatures] = maxr(a)
%
%       Calls max() followed by qint() for quadratic interpolation.
%
   [m,n] = size(a);
   if m==1, a=a'; t=m; m=n; n=t; end;
   [y,x] = max(a);
   xi=x;    % vector of maximizer locations, one per col of a
   yi=y;    % vector of maximum values, one per column of a
   if nargout>2, curvatures = zeros(1,n); end
   for j=1:n,   % loop over columns
     if x(j)>1, % only support interior maxima
       if x(j)<m,
         [xdelta,yij,cj] = qint(a(x(j)-1,j),y(j),a(x(j)+1,j));
         xi(j) = x(j) + xdelta;
         if nargout>2, curvatures(j) = cj; end
         if (nargout>1), yi(j) = yij; end
       end;
     end;
   end;


function out= proc_dBPercentiles(epo, varargin)
%PROC_DBAVERAGE - Classwise calculated averages for dB-scaled features
%
%This functions is exactly used as proc_average. It should be used
%for dB-scaled features (e.g. output of proc_power2dB; or
%proc_spectrum in the default setting 'scaling', 'dB').
if nargin==0,
  out= proc_average; return;
end

epo = misc_history(epo);
out= epo;
%% scale back
out.x= 10.^(epo.x/10);
out= rmfield(out, 'yUnit');  % otherwise we will enter an infinite recursion

%% average
out= proc_percentiles(out, varargin{:});

%% re-convert to dB
out.x= 10*log10(out.x);
out.yUnit= 'dB';


function E = evaluate_weighted_energy(uv, im, occ, bfhsz, mfsz, sigma_i)

% edge region: weighted median filtering, the weights are determined by
%  spatial distance, intensity distance, occlusion state
% smooth region:

%   Author: Deqing Sun, Department of Computer Science, Brown University
%   Contact: dqsun@cs.brown.edu
%   $Date: 2009$
%   $Revision $
%
% Copyright 2009-2010, Brown University, Providence, RI. USA
%
%                          All Rights Reserved
%
% All commercial use of this software, whether direct or indirect, is
% strictly prohibited including, without limitation, incorporation into in
% a commercial product, use in a commercial service, or production of other
% artifacts for commercial purposes.
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for research purposes is hereby granted without fee,
% provided that the above copyright notice appears in all copies and that
% both that copyright notice and this permission notice appear in
% supporting documentation, and that the name of the author and Brown
% University not be used in advertising or publicity pertaining to
% distribution of the software without specific, written prior permission.
%
% For commercial uses contact the Technology Venture Office of Brown University
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO
% THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
% FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR
% BROWN UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
% DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
% PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
% ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
% THIS SOFTWARE.

sigma_x = 7;   %  spatial distance (7)

dilate_sz = 5*[1 1];  % dilation window size for flow edge region [5 5]

sz = size(im);
sz = sz(1:2);

if nargin < 3
    occ = ones(sz);
end;

if nargin < 4
    bfhsz = 10; % half window size
end;

%mfsz = [7 7]; % for test

if nargin < 5
    uvo = uv;
else
%     uvo(:,:,1) = medfilt2(uv(:,:,1), mfsz, 'symmetric');
%     uvo(:,:,2) = medfilt2(uv(:,:,2), mfsz, 'symmetric');
end;

if nargin < 6
    sigma_i = 5; %3.5; % intensity distance (10) 5 better than 10 and 20
end;

% % % WMF first then MF
% % uvo = uv;

e1 = edge(uv(:,:,1), 'sobel');
e2 = edge(uv(:,:,2), 'sobel');
e  = e1|e2;
mask = imdilate(e, ones(dilate_sz) );

% nearest 4 neighbors smaller than [3 3]
% tmp = [ 0 1 0; 1 1 1; 0 1 0];
% mask = imdilate(e, tmp );

% mask = e; % no dilation

% Update non-edge regions first
% uv(repmat(mask, [1 1 2])) = uvo(repmat(mask, [1 1 2]));

% Uncomment below to apply WMF to all regions
% mask = ones(size(im));

% Select boundary regions
[indx_row, indx_col] = find(mask ==1); %

% [H W] = size(im);
pad_u  = padarray(uv(:,:,1), bfhsz*[1 1], 'symmetric', 'both');
pad_v  = padarray(uv(:,:,2), bfhsz*[1 1], 'symmetric', 'both');
pad_im = padarray(im, bfhsz*[1 1], 'symmetric', 'both');
pad_occ= padarray(occ, bfhsz*[1 1], 'symmetric', 'both');

% fprintf('%d\n', length(indx_row));

% Divide into several groups for memory reasons ~70,000 causes out of memory

Indx_Row = indx_row;
Indx_Col = indx_col;
N        = length(Indx_Row); % number of elements to process
n        = 4e4;              % number of elements per batch
nB       = ceil(N/n);

E = 0;

for ib = 1:nB;
    istart = (ib-1)*n + 1;
    iend   = min(ib*n, N);
    indx_row = Indx_Row(istart:iend);
    indx_col = Indx_Col(istart:iend);

    neighbors_u = zeros((bfhsz*2+1)^2, length(indx_row));
    neighbors_v = neighbors_u;
    weights     = neighbors_u;

    for i = 1:length(indx_row)

        % crop window
        r1 = indx_row(i);
        r2 = indx_row(i) + 2*bfhsz;
        c1 = indx_col(i);
        c2 = indx_col(i) + 2*bfhsz;

        rc = indx_row(i) + bfhsz; % row  center
        cc = indx_col(i) + bfhsz; % column center
        ic = pad_im(rc, cc, :);       % intensity of the center pixel

        tmp_u = pad_u(r1:r2, c1:c2);
        tmp_v = pad_v(r1:r2, c1:c2);
        tmp_i = pad_im(r1:r2, c1:c2, :);

        % spatial weight
        [C R] = meshgrid(c1:c2, r1:r2);
        w = exp( -((C-cc).^2+(R-rc).^2)/2/sigma_x^2 );
        % Uncomment below: no spatial weight for test
        % w = ones(size(w));

        % intensity weight; comment below to disable the term
        w = w.* mean( exp(- (tmp_i - repmat(ic, [size(tmp_i,1) size(tmp_i, 2) 1])).^2/2/sigma_i^2), 3);

        % occluded weight;  comment below to disable the term
        w = w.*pad_occ(r1:r2, c1:c2);

        % Normalize
        w = w/sum(w(:));

%         neighbors_u(:,i) = tmp_u(:);
%         neighbors_v(:,i) = tmp_v(:);
%         weights(:,i)     = w(:);

        E = E + sum( abs(tmp_u(:) - pad_u(rc, cc)).* w(:));
        E = E + sum( abs(tmp_v(:) - pad_v(rc, cc)).* w(:));

    end;

end;

% for 5x5 equal weight

% Select non-boundary regions
[indx_row, indx_col] = find(mask ~=1);
bfhsz = floor(mfsz(1)/2);

pad_u  = padarray(uv(:,:,1), bfhsz*[1 1], 'symmetric', 'both');
pad_v  = padarray(uv(:,:,2), bfhsz*[1 1], 'symmetric', 'both');
pad_im = padarray(im, bfhsz*[1 1], 'symmetric', 'both');
pad_occ= padarray(occ, bfhsz*[1 1], 'symmetric', 'both');

% fprintf('%d\n', length(indx_row));

% Divide into several groups for memory reasons ~70,000 causes out of memory

Indx_Row = indx_row;
Indx_Col = indx_col;
N        = length(Indx_Row); % number of elements to process
n        = 4e4;              % number of elements per batch
nB       = ceil(N/n);

for ib = 1:nB;
    istart = (ib-1)*n + 1;
    iend   = min(ib*n, N);
    indx_row = Indx_Row(istart:iend);
    indx_col = Indx_Col(istart:iend);

    neighbors_u = zeros((bfhsz*2+1)^2, length(indx_row));
    neighbors_v = neighbors_u;
    weights     = neighbors_u;

    for i = 1:length(indx_row)

        % crop window
        r1 = indx_row(i);
        r2 = indx_row(i) + 2*bfhsz;
        c1 = indx_col(i);
        c2 = indx_col(i) + 2*bfhsz;

        rc = indx_row(i) + bfhsz; % row  center
        cc = indx_col(i) + bfhsz; % column center
        ic = pad_im(rc, cc, :);       % intensity of the center pixel

        tmp_u = pad_u(r1:r2, c1:c2);
        tmp_v = pad_v(r1:r2, c1:c2);
        tmp_i = pad_im(r1:r2, c1:c2, :);

        % spatial weight
        [C R] = meshgrid(c1:c2, r1:r2);
        w = exp( -((C-cc).^2+(R-rc).^2)/2/sigma_x^2 );
        % Uncomment below: no spatial weight for test
        w = ones(size(w));

%         % intensity weight; comment below to disable the term
%         w = w.* mean( exp(- (tmp_i - repmat(ic, [size(tmp_i,1) size(tmp_i, 2) 1])).^2/2/sigma_i^2), 3);
%
%         % occluded weight;  comment below to disable the term
%         w = w.*pad_occ(r1:r2, c1:c2);

        % Normalize
        w = w/sum(w(:));

%         neighbors_u(:,i) = tmp_u(:);
%         neighbors_v(:,i) = tmp_v(:);
%         weights(:,i)     = w(:);

        E = E + sum( abs(tmp_u(:) - pad_u(rc, cc)).* w(:));
        E = E + sum( abs(tmp_v(:) - pad_v(rc, cc)).* w(:));

    end;

end;


function give_Me_Jelly()

L = 3;           % Length of Computational Domain
ds = L/(2*600);  % Makes Lagrangian Spaced based on 1024x1024 finest grid

frac = 0.5;

% Makes Geometry for EQUILIBRIUM State %
%
a1 = 0.63;  %Semi-major axis length for position ONE (Expanded State)
b1 = 0.45;  %Semi-minor axis length for position ONE (Expanded State)
a1 = frac*a1; b1 = frac*b1;
a1
b1
[X1 Y1 Ninfo arcL] = make_Geometry_Position_ONE(ds,a1,b1);

% Makes Geometry for OVER-CONTRACTED State for RIGHT side %
%
a2 = 0.325; %Semi-major axis length for position TWO (Contracted State)
b2 = 0.6;   %GUESS: Semi-minor axis length for position TWO (Contracted State)
a2 = frac*a2; b2 = frac*b2;
[X2 Y2 b2] = make_Geometry_Position_TWO(a2,b2,b1,Ninfo,arcL);

% Makes Geometry for LESS-CONTRACTED State for LEFT side %
%
a3 = 0.4;   %Semi-major axis length for position TWO (Contracted State)
b3 = 0.7;   %GUESS: Semi-minor axis length for position TWO (Contracted State)
a3 = frac*a3; b3 = frac*b3;
a3
b3
[X3 Y3 b3] = make_Geometry_Position_TWO(a3,b3,b1,Ninfo,arcL);

% Makes Geometry for OVER-EXPANDED State for LEFT SIDE %
%
a4 = 0.75;  %Semi-major axis length for position TWO (Contracted State)
b4 = 0.3;   %GUESS: Semi-minor axis length for position TWO (Contracted State)
a4 = frac*a4; b4 = frac*b4;
[X4 Y4 b4] = make_Geometry_Position_TWO(a4,b4,b1,Ninfo,arcL);

% Translate Points from [-L/2,L/2]x[-L/2,L/2] -> [0,L]x[0,L]
X1 = X1 + L/2; Y1 = Y1 + L/2;
X2 = X2 + L/2; Y2 = Y2 + L/2;
X3 = X3 + L/2; Y3 = Y3 + L/2;
X4 = X4 + L/2; Y4 = Y4 + L/2;

nArm = (length(X1)-1)/2;

% Plots Geometry for Both Phases %
val = frac*0.75;
plot(X1,Y1,'*',X2(1:nArm),Y2(1:nArm),'r*',X3(nArm+2:end),Y3(nArm+2:end),'g*',X4(nArm+2:end),Y4(nArm+2:end),'m*'); hold on;
axis([0 L 0 L]);
legend('1','2','3','4');

figure(2)
plot(X2,Y2,'r*'); hold on;
plot(X1,Y1,'b*'); hold on;

% Prints Useful Info about Geometry %
fprintf('\n\n');
fprintf('Number of Total Geometry Pts: %d\n',Ninfo(2));
fprintf('Number of Geometry Pts in EACH Arm: %d\n',Ninfo(1));
fprintf('Arc length of bell (one side): %d\n',arcL);
fprintf('\n');
fprintf('(X1,Y1): Equilibrium State\n');
fprintf('(X2,Y2): OVER-Contracted State for RIGHT Side\n');
fprintf('(X3,Y3): Contracted State for LEFT Side (slightly less than right side)\n');
fprintf('(X4,Y4): OVER-EXPANDED State for LEFT Side\n');
fprintf('\n');
fprintf('Idea: \n');
fprintf('RHS contracts further than LHS, rests & returns to equil. state after LHS begins expanding\n');
fprintf('LHS contracts less than RHS, then expands further than equil. state and then returns to equil. state\n');
fprintf('\n');
fprintf('PUT FOLLOWING IN UPDATE_TARGET_POINTS.C:\n');
fprintf('numPts (# of Total Geometry Pts): %d\n',Ninfo(2));
fprintf('NL_Start (FIRST Point in LEFT Arm): %d\n\n\n',Ninfo(1)+1);

% Prints INPUT files %
print_Vertex_Pts(X1,Y1,Ninfo);
target_force = 5e6;
print_Target_Pts(target_force,Ninfo);

% Prints all vectors to .TXT files %
%print_Text_Files(Ninfo,X1,Y1,X2,Y2,X3,Y3,X4,Y4)

% Prints 2-Position Right/Left Side vectors to .TXT files %
print_2_Position_Text_File(Ninfo,X1,Y1,X2,Y2,X3,Y3);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function: Prints 2 Position Phases:
%           XY(:,1) = original position x-Values
%           XY(:,3) = original position y-Values
%           XY(2:N+1,2) = 2nd position x-Values for RIGHT bell
%           XY(N+2:end,2) = 2nd position x-Values for LEFT bell
%           XY(2:N+1,4) = 2nd position y-Values for RIGHT bell
%           XY(N+2:end,4) = 2nd position y-Values for LEFT bell
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_2_Position_Text_File(Ninfo,X1,Y1,X2,Y2,X3,Y3)

N = Ninfo(1);    % Number of pts. in ONE arm
NTot = Ninfo(2); % Total # of Lag Pts. on Jelly Bell

% Initialization
XY = zeros(NTot,4);

% Construct Matrices For Storing Points
XY(:,1) = X1(1:NTot); XY(:,2) = X1(1:NTot);
XY(:,3) = Y1(1:NTot); XY(:,4) = Y1(1:NTot);

% 2nd Phase Right Arm
XY(2:N+1,2) = X2(2:N+1);
XY(2:N+1,4) = Y2(2:N+1);

% 2nd Phase Left Arm
XY(N+2:end,2) = X2(N+2:end);
XY(N+2:end,4) = Y2(N+2:end);

% PLOT TEST! %
%figure(3)
%plot(XY(:,1),XY(:,3),'k*'); hold on;
%plot(XY(:,2),XY(:,4),'g*'); hold on;

% PRINT x/y-Information %

fileID_XY = fopen('XY_2Pos.txt','w');

for i=1:length( XY(:,1) )
    fprintf(fileID_XY,'%1.16e %1.16e %1.16e %1.16e\n',XY(i,1),XY(i,2),XY(i,3),XY(i,4));
end

fclose(fileID_XY);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function to PRINT all TEXT files for both PHASES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Text_Files(Ninfo,X1,Y1,X2,Y2,X3,Y3,X4,Y4)

N = Ninfo(1); %Number of pts. in ONE arm

% x-Information %

fileID_x1 = fopen('x1.txt','w');
fprintf(fileID_x1,'%1.16e\n',X1);
fclose(fileID_x1);

fileID_x2 = fopen('x2.txt','w');
fprintf(fileID_x2,'%1.16e\n',X2);
fclose(fileID_x2);

fileID_x3 = fopen('x3.txt','w');
fprintf(fileID_x3,'%1.16e\n',X3);
fclose(fileID_x3);

fileID_x4 = fopen('x4.txt','w');
fprintf(fileID_x4,'%1.16e\n',X4);
fclose(fileID_x4);

% y-Information %

fileID_y1 = fopen('y1.txt','w');
fprintf(fileID_y1,'%1.16e\n',Y1);
fclose(fileID_y1);

fileID_y2 = fopen('y2.txt','w');
fprintf(fileID_y2,'%1.16e\n',Y2);
fclose(fileID_y2);

fileID_y3 = fopen('y3.txt','w');
fprintf(fileID_y3,'%1.16e\n',Y3);
fclose(fileID_y3);

fileID_y4 = fopen('y4.txt','w');
fprintf(fileID_y4,'%1.16e\n',Y4);
fclose(fileID_y4);

% xR1 = X1(2:2+N-1); % x-Pts. on RHS of center point for Position ONE
% xL1 = X1(2+N:end); % x-Pts. on LHS of center point for Position ONE
%
% xR2 = X2(2:2+N-1); % x-Pts. on RHS of center point for Position TWO
% xL2 = X2(2+N:end); % x-Pts. on LHS of center point for Position TWO
%
% yR1 = Y1(2:2+N-1); % y-Pts. on RHS of center point for Position ONE
% yL1 = Y1(2+N:end); % y-Pts. on RHS of center point for Position ONE
%
% yR2 = Y2(2:2+N-1); % y-Pts. on LHS of center point for Position TWO
% yL2 = Y2(2+N:end); % y-Pts. on LHS of center point for Position TWO
%
%
% fileID_xR1 = fopen('xR_1.txt','w');
% fprintf(fileID_xR1,'%1.16e\n',xR1);
% fclose(fileID_xR1);
%
% fileID_xR2 = fopen('xR_2.txt','w');
% fprintf(fileID_xR2,'%1.16e\n',xR2);
% fclose(fileID_xR2);
%
% fileID_xL1 = fopen('xL_1.txt','w');
% fprintf(fileID_xL1,'%1.16e\n',xL1);
% fclose(fileID_xL1);
%
% fileID_xL2 = fopen('xL_2.txt','w');
% fprintf(fileID_xL2,'%1.16e\n',xL2);
% fclose(fileID_xL2);
%
%
% fileID_yR1 = fopen('yR_1.txt','w');
% fprintf(fileID_yR1,'%1.16e\n',yR1);
% fclose(fileID_yR1);
%
% fileID_yR2 = fopen('yR_2.txt','w');
% fprintf(fileID_yR2,'%1.16e\n',yR2);
% fclose(fileID_yR2);
%
% fileID_yL1 = fopen('yL_1.txt','w');
% fprintf(fileID_yL1,'%1.16e\n',yL1);
% fclose(fileID_yL1);
%
% fileID_yL2 = fopen('yL_2.txt','w');
% fprintf(fileID_yL2,'%1.16e\n',yL2);
% fclose(fileID_yL2);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Makes the Oblate Geometry (via ellipses)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [X1 Y1 Ninfo arcL] = make_Geometry_Position_ONE(ds,a,b)

%a: Semi-major axis (along horizontal)
%b: Semi-minor axis (along vertical)

%Finding elliptical arc length
h = ( (a-b)/(a+b) )^2;
arcL = (1/4)* pi*(a+b)*(1 + 3*h/ (10 + sqrt(4-3*h) ) ); % (1/4)th of the entire ELLIPTICAL ARC

n = 1;        %counting for array
X(n) = 0;     %first x-value at (0,-b)
Y(n) = -b;    %first y-value at (0,-b)
tprev = -pi/2;  %initial angle

tol = ds / 10; %error tolerance for root-finding algorithm

maxy = max(a,b);

    while tprev < 0

        n = n+1;
        tnext = tprev + ds/maxy; %Guess for next angle value

        if tprev < -pi/4
            tfar =  0.0;%abs(2*tprev);      %Far guess
        else
            tfar = pi/4;
        end

        %initiating guess for bisection-algorithm
        xn = a*cos(tnext);
        yn = b*sin(tnext);
        errSign = ( ds - sqrt( (xn-X(n-1))^2 + (yn-Y(n-1))^2 ) );
        err = abs(errSign);

        %Bisection algorithm to make points equally spaced
        while ( err > tol )

            if errSign < 0
                tfar = tnext;
                tnext = (tnext+tprev)/2;
            elseif errSign > 0
                tprev = tnext;
                tnext = (tnext+tfar)/2;
            end

            if tnext<tprev
                fprintf('NOT CONVERGING AT ANGLE %d\n',tprev)
                break;
            end

            xn = a*cos(tnext);
            yn = b*sin(tnext);
            errSign = ( ds - sqrt( (xn-X(n-1))^2 + (yn-Y(n-1))^2 ) );
            err = abs(errSign);
        end

        X(n) = xn;   %Store X-value
        Y(n) = yn;   %Store Y-value
        tprev = tnext; %Update previous angle

        %plot(xn,yn,'*'); hold on;

    end

 N = length(X);
 X(N+1) = a; %Add one more pt.
 Y(N+1) = 0; %Add one more pt.

 X1 = [X -X(2:end)]; %Reflects geometry
 Y1 = -[Y  Y(2:end)]; %Y-values for reflected X-value points

 Ninfo(1) = N;          % # of pts. along one arm (NOT counting center pt.)
 Ninfo(2) = length(X1); % Total # of pts. in geometry

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Makes the Oblate Geometry (via ellipses)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [X2 Y2 b] = make_Geometry_Position_TWO(a,bguess,b1,Ninfo,L)

%Find correct b to give same length arm
b = Newtons_Give_Me_Semi_Minor(a,bguess,L);

%Finding elliptical arc length
h = ( (a-b)/(a+b) )^2;
arcL = (1/4)* pi*(a+b)*(1 + 3*h/ (10 + sqrt(4-3*h) ) ); % (1/4)th of the entire ELLIPTICAL ARC

ds2 = arcL / Ninfo(1); %Ensures same number of pts on arm for position ONE and TWO

[X Y Ninfo] = make_Elliptic_Geometry_Position_TWO(ds2,a,b,Ninfo);

dV = b1-b;   %Makes sure first pt is the same as in position ONE

Y2 = -(Y-dV);%Minus sign to put jelly into right orientation
X2 = X;

%Ninfo
%plot(X2,Y2,'r*'); hold on;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Makes the Oblate Geometry (via ellipses)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function b = Newtons_Give_Me_Semi_Minor(a,bn,L)

tol = 1e-6;

bprev = 0.2*bn; %"Previous Guess" (left side of guess)
bnext = bn;     % First "Guess" at b
bfar =  1.5*bn; %"Far Guess" (right side of guess)

%Finding elliptical arc length
h = ( (a-bn)/(a+bn) )^2;
arcL = (1/4)* pi*(a+bn)*(1 + 3*h/ (10 + sqrt(4-3*h) ) ); % (1/4)th of the entire ELLIPTICAL ARC

errSign = L - arcL;
err = abs( errSign );

%Bisection algorithm to make points equally spaced
while ( err > tol )

    if errSign < 0
        bfar = bnext;
        bnext = (bnext+bprev)/2;
    elseif errSign > 0
        bprev = bnext;
        bnext = (bnext+bfar)/2;
    end

    %if bnext<bprev
    %    fprintf('NOT CONVERGING AT ANGLE %d\n',tprev)
    %    break;
    %end

    %Finding elliptical arc length
    h = ( (a-bnext)/(a+bnext) )^2;
    arcL = (1/4)* pi*(a+bnext)*(1 + 3*h/ (10 + sqrt(4-3*h) ) ); % (1/4)th of the entire ELLIPTICAL ARC

    errSign = ( L - arcL );
    err = abs(errSign);
end

b = bnext; %Assign value

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Makes the Oblate Geometry (via ellipses)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [X1 Y1 Ninfo] = make_Elliptic_Geometry_Position_TWO(ds,a,b,Ninfo)

%a: Semi-major axis (along horizontal)
%b: Semi-minor axis (along vertical)

n = 1;        %counting for array
X(n) = 0;     %first x-value at (0,-b)
Y(n) = -b;    %first y-value at (0,-b)
tprev = -pi/2;  %initial angle

tol = ds / 10; %error tolerance for root-finding algorithm

maxy = max(a,b);

    while n < Ninfo(1)+1

        n = n+1;
        tnext = tprev + ds/maxy; %Guess for next angle value

        if tprev < -pi/4
            tfar =  0.0;%abs(2*tprev);      %Far guess
        else
            tfar = pi/4;
        end

        %initiating guess for bisection-algorithm
        xn = a*cos(tnext);
        yn = b*sin(tnext);
        errSign = ( ds - sqrt( (xn-X(n-1))^2 + (yn-Y(n-1))^2 ) );
        err = abs(errSign);

        %Bisection algorithm to make points equally spaced
        while ( err > tol )

            if errSign < 0
                tfar = tnext;
                tnext = (tnext+tprev)/2;
            elseif errSign > 0
                tprev = tnext;
                tnext = (tnext+tfar)/2;
            end

            if tnext<tprev
                fprintf('NOT CONVERGING AT ANGLE %d\n',tprev)
                break;
            end

            xn = a*cos(tnext);
            yn = b*sin(tnext);
            errSign = ( ds - sqrt( (xn-X(n-1))^2 + (yn-Y(n-1))^2 ) );
            err = abs(errSign);
        end

        X(n) = xn;   %Store X-value
        Y(n) = yn;   %Store Y-value
        tprev = tnext; %Update previous angle

        %plot(xn,yn,'*'); hold on;

    end

 N = length(X)-1;
 %X(N+1) = a; %Add one more pt.
 %Y(N+1) = 0; %Add one more pt.

 %plot(X,Y,'*'); hold on;

 X1 = [X -X(2:end)]; %Reflects geometry
 Y1 = [Y  Y(2:end)]; %Y-values for reflected X-value points

 Ninfo(1) = N;          % # of pts. along one arm (NOT counting center pt.)
 Ninfo(2) = length(X1); % Total # of pts. in geometry

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to print VERTEX points
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Vertex_Pts(X,Y,Ninfo)

%Ninfo(1): # of pts. on one arm on Jellyfish
%Ninfo(2): # of total pts. in Jellyfish Geometry

Ntot = Ninfo(2);

vertex_fid = fopen('jellyfish.vertex', 'w');

% first line is the number of vertices in the file
fprintf(vertex_fid, '%d\n', Ntot);

for i=1:Ntot
    fprintf(vertex_fid, '%1.16e %1.16e\n', X(i), Y(i) );
end

fclose(vertex_fid);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Function to print TARGET pts.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function print_Target_Pts(target_force,Ninfo)

%Ninfo(1): # of pts. on one arm on Jellyfish
%Ninfo(2): # of total pts. in Jellyfish Geometry

Ntot = Ninfo(2);

% Write out the target point information
target_fid = fopen('jellyfish.target', 'w');

% First line is the number of target pts. in the file
fprintf(target_fid, '%d\n', Ntot);

for s=1:Ntot
        fprintf(target_fid, '%d %1.16e\n', s , target_force);
end

fclose(target_fid);


function ADEM_lorenz_entropy
% This demo shows how structure can be instilled from an environment. It
% uses an agent that optimises its recognition density over successive
% epochs of exposure to an environment. This environment causes the agent
% to flow on a Lorenz attractor with random perturbations. As the agent
% learns the causal regularities in its environment, it is better able to
% predict them and act to oppose the random effect. The result is that it
% is more robust to random forces and therefore exhibits states with lower
% entropy. This routine takes several minutes to run.
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: ADEM_lorenz_entropy.m 4804 2012-07-26 13:14:18Z karl $

% generative process (environment)
%==========================================================================

% set up
%--------------------------------------------------------------------------
G(1).E.s = 1/4;                             % smoothness
G(1).E.n = 4;                               % embedding
G(1).E.d = 2;                               % embedding

% dynamics
%--------------------------------------------------------------------------
fG      = '[v + a; 0; 0] + [-P(1) P(1) 0; P(3) -1 -x(1); x(2) 0 P(2)]*x/64';
fM      = '[v    ; 0; 0] + [-P(1) P(1) 0; P(3) -1 -x(1); x(2) 0 P(2)]*x/64';

% parameters
%--------------------------------------------------------------------------
PG      = [10; -8/3; 32];                   % Target parameters
PM      = [10;    0;  0];                   % initial parameters

% level 1
%--------------------------------------------------------------------------
G(1).x  = [1; 1; 24];
G(1).f  = inline(fG ,'x','v','a','P');
G(1).g  = inline('x','x','v','a','P');
G(1).pE = PG;
G(1).V  = exp(8);                           % error precision
G(1).W  = exp(16);                          % error precision

% level 2
%--------------------------------------------------------------------------
G(2).a  = 0;                                % action variables
G(2).v  = 0;                                % inputs
G(2).V  = exp(16);
G       = spm_ADEM_M_set(G);

% % plot flow fields and equilibrium densities
% %==========================================================================
% spm_figure('GetWin','Figure 1');
%
% x{1}    = linspace(-20,20,32);
% x{2}    = linspace(-32,32,32);
% x{3}    = linspace(  10,40,8);
%
%
% % controlled flow (P0)
% %--------------------------------------------------------------------------
% subplot(3,2,1)
% spm_fp_display_density(G,x);
% xlabel('position','Fontsize',12)
% ylabel('velocity','Fontsize',12)
% title('controlled','Fontsize',16)

% recognition model: learn the controlled environmental dynamics
%==========================================================================

% make a naive model (M)
%--------------------------------------------------------------------------
M       = G;
M(1).f  = inline(fM ,'x','v','P');
M(1).g  = inline('x','x','v','P');
M(1).pE = PM;
M(1).pC = eye(3)*4;
M(1).V  = exp(8);
M(1).W  = exp(8);
M       = spm_DEM_M_set(M);

% teach naive model by exposing it to a controlled environment (G)
%==========================================================================

% length of realization
%--------------------------------------------------------------------------
n     = 256;
U     = sparse(n,1);

DEM.M = M;
DEM.G = G;
DEM.C = U;
DEM.U = U;

% optimise recognition model in epochs
%--------------------------------------------------------------------------
DEM.M(1).E.nE = 1;
H     = sparse(128,128);
for i = 1:32

        % random perturbations
        %------------------------------------------------------------------
        DEM.C       = spm_conv(randn(n,1)*8,8);

        % integrate and update priors
        %------------------------------------------------------------------
        DEM         = spm_ADEM(DEM);
        DEM.M(1).pE = DEM.qP.P{1};
        DEM.M(1).x  = DEM.qU.x{1}(:,end);
        DEM.M(2).a  = DEM.qU.a{2}(:,end);

        % save free-energy and conditional expectations
        %------------------------------------------------------------------
        qP(:,i) = DEM.qP.P{1};
        F(i)    = DEM.F;

        % display states at the beginning and end
        %------------------------------------------------------------------
        spm_figure('GetWin','Figure 1');

        if i < 8
            subplot(3,2,3)
            x = DEM.pU.v{1}(2,:);
            y = DEM.pU.v{1}(3,:);
            plot(x,y); hold on
            title('states before','FontSize',16)
            a = axis;

        elseif i > 24
            subplot(3,2,4)
            x = DEM.pU.v{1}(2,:);
            y = DEM.pU.v{1}(3,:);
            H = H + sparse(64 + fix(x)',64 + fix(y)',1,128,128);
            plot(x,y); hold on
            title('and after','FontSize',16)
            axis(a)

        end
    end

% graphics
%==========================================================================
spm_figure('GetWin','Figure 1');

% plot free-energy
%--------------------------------------------------------------------------
t   = 1:length(F);
subplot(3,1,1)
plot(t,-F)
xlabel('time (epochs)','FontSize',12)
title('Free-energy','FontSize',16)
axis square

% and underlying conditional expectations
%--------------------------------------------------------------------------
subplot(3,2,5)
plot(t,qP,t,kron(ones(1,length(t)),PG),'-.')
xlabel('time (epochs)','FontSize',12)
title('conditional parameters','FontSize',16)
axis square

subplot(3,2,6)
imagesc(H')
xlabel('first state','FontSize',12)
ylabel('second state','FontSize',12)
title('ensemble density','FontSize',16)
axis square xy


function h=framemul(f,Fa,Fs,s,varargin)
%FRAMEMUL  Frame multiplier
%   Usage:  h=framemul(f,Fa,Fs,s);
%
%   Input parameters:
%          Fa   : Analysis frame
%          Fs   : Synthesis frame
%          s    : Symbol
%          f    : Input signal
%
%   Output parameters:
%          h    : Output signal
%
%   `framemul(f,Fa,Fs,s)` applies the frame multiplier with symbol *s*
%   to the signal *f*. The frame *Fa* is used for analysis and the frame
%   *Fs* for synthesis.
%
%   Examples:
%   ---------
%
%   In the following example Gabor coefficients obtained through the DGT
%   of pink noise are multiplied by the symbol batmask before resynthesis.
%   The result of this operation is an output signal *h* that is constructed
%   through a Gabor expansion of the modified coefficients.:::
%
%      f = pinknoise(400);
%      a = 10;
%      M = 40;
%      [Fa, Fs] = framepair('dgt', 'gauss', 'dual', a, M);
%      s = framenative2coef(Fa, batmask);
%      fhat = framemul(f, Fa, Fs, s);
%      figure(1);
%      plotframe(Fa,frana(Fa,f),'clim',[-100,-20]);
%      figure(2);
%      plotframe(Fa,s,'lin');
%      figure(3);
%      plotframe(Fa,frana(Fa,fhat),'clim',[-100,-20]);
%
%   See also: iframemul, framemuladj

% Author: Peter L. Søndergaard

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

if size(s,2)>1
    error(['%s: Symbol should be a column vecor i.e. ',...
           'in the common Frames framework coefficient format. ',...
           'See FRAMENATIVE2COEF and FRAMECOEF2NATIVE.' ],upper(mfilename));
end

% Check for compatibility
L1=framelength(Fa,size(f,1));
L2=framelengthcoef(Fs,size(s,1));
if L1~=L2
    error(['%s: The symbol and signal lengths are incompatible.'],upper(mfilename));
end;

% This is not *strictly* necessary, but we cannot check that the symbol
% is complex-valued in just the right way.
if Fa.realinput && ~isreal(s)
    error(['%s: For real-valued-input-only frames, the symbol must also ' ...
           'be real.'],upper(mfilename));
end;

h=frsyn(Fs,bsxfun(@times,frana(Fa,f),s));