% *********************************************************************
%    Workflow for reconstruction involving variant refinement
% *********************************************************************
home; close all; clear variables;
currentFolder;
startup_mtex;
setMTEXpref('xAxisDirection','east');
setMTEXpref('zAxisDirection','outOfPlane');
setMTEXpref('FontSize',14)
ebsd = mtexdata('martensite');
%% Compute, filter and smooth grains
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'angle',2*degree);
ebsd(grains(grains.grainSize < 3)) = [];
[grains,ebsd.grainId] = calcGrains(ebsd('indexed'),'angle',2*degree);
grains = smooth(grains,5);
%% Define and refine parent-to-child orientation relationship
job_temp = parentGrainReconstructor(ebsd,grains);
job_temp.p2c = orientation.GreningerTrojano(job_temp.csParent, job_temp.csChild);
job_temp.calcParent2Child;
%% Reconstruct parent microstructure and plot the results
job_temp.calcHyperGraph3('threshold',5*degree,'c2c','mergeSimilar','mergethreshold',8*degree,'keepGraph');
job_temp.clusterHyperGraph3('numIter',20,'inflationPower',1,'merged','mergethreshold',8*degree,'keepGraph');
job_temp.calcParentFromVote;
figure;
plot(job_temp.parentGrains,job_temp.parentGrains.meanOrientation,'linewidth',2);
%% Calculate variants and reconstruct new grains based on variants
job_temp.calcVariants;
ebsdC = job_temp.ebsdPrior(job_temp.grainsPrior(job_temp.isTransformed));
oriP = job_temp.grains(job_temp.mergeId(ebsdC.grainId)).meanOrientation;
[varIds,packIds] = calcVariantId(oriP,ebsdC.orientations,job_temp.p2c,...
                                 'variantMap', job_temp.variantMap);
varPids = [varIds,job_temp.grains(job_temp.mergeId(ebsdC.grainId)).id];
[laths,ebsdC.grainId] = calcGrains(ebsdC,'variants',varPids);
laths(ebsdC.grainId).prop.packetId = packIds;
%% Redo the reconstruction with refined child grains
job = parentGrainReconstructor(ebsdC,laths);
job.p2c = orientation.GreningerTrojano(job_temp.csParent, job_temp.csChild);
job.calcParent2Child;
%% Reconstruct parent microstructure and plot the results
job.calcHyperGraph3('threshold',5*degree,'c2c','mergeSimilar','mergethreshold',8*degree,'keepGraph');
job.clusterHyperGraph3('numIter',20,'inflationPower',1,'merged','mergethreshold',8*degree,'keepGraph');
job.calcParentFromVote;
figure;
plot(job.parentGrains,job.parentGrains.meanOrientation,'linewidth',2);
%% Clean reconstructed grains
job.mergeSimilar('threshold',7.5*degree);
job.mergeInclusions('maxSize',150);
figure;
plot(job.parentGrains,job.parentGrains.meanOrientation,'linewidth',2)
%% Variant analysis
job_temp.calcVariants;
plotMap_variants(job,'linewidth',3);
plotMap_packets(job,'linewidth',3);


function [A,x,y,I]=geoimread_lcg_matlab2020a(filename,varargin)
%GEOIMREAD reads a sub region of a geotiff or geojp2 image.
%
%
%% Syntax
%
% A = geoimread(filename)
% A = geoimread(filename,xlim,ylim)
% A = geoimread(filename,latlim,lonlim)
% A = geoimread(...,buffer)
% [A,x,y,I] = geoimread(...)
% geoimread(...)
%
%
%% Description
%
% A = geoimread(filename) returns the full image given by a filename. This
% syntax is equivalent to A = geotiffread(filename).
%
% A = geoimread(filename,xlim,ylim) limits the region of the geotiff file to
% the limits given by xlim and ylim, which are map units (usually meters) relative
% to the data projection. For example, if the geotiff is projected in Texas Centric
% Mapping System/Lambert Conformal coordinates, xlim and ylim will have units of
% meters relative to the origin (100 W, 18 N). xlim and ylim can be multimensional,
% in which case the limits of the map will be taken as the limits of the limits of
% the distribution of all points in xlim, ylim.
%
% A = geoimread(filename,latlim,lonlim) if no values in xlim, ylim exceed
% normal values of latitudes and longitudes, geoimread assumes you've entered
% limits in geographic coordinates of degrees latitude and longitude. The first
% input is latitude, the second input is longitude.
%
% A = geoimread(...,buffer) adds a buffer in map units (usually meters or feet) to the
% limits of the region of interest.  This may be useful if you want to load an image
% surrounding scattered lat/lon data.  If you'd like an extra 2 kilometers of image around
% your data, enter 2000 as the buffer.  If buffer is a two-element vector, the first
% element is applied to the left and right extents of the image, and the second element
% is applied to the top and bottom extents of the image.
%
% [A,x,y,I] = geoimread(...) also returns pixel center coordinates (x,y) of the
% output image and a geotiff info structure I. I is a useful input for projfwd and projinv.
%
% geoimread(...) without any outputs shows the output image A without loading
% any data into the workspace.
%
%
%% Examples:
%
% % Show a whole geotiff:
% geoimread('boston.tif');
%
% % Compare results from above to a subset geotiff:
% mapx = [765884 766035 766963]; % units are feet
% mapy = [2959218 2957723 2958972];
% geoimread('boston.tif',mapx,mapy)
%
% % Or if you have coordinates in lat/lon and you want a 500 foot buffer:
% lat = [42.3675288 42.3634246 42.3668397];
% lon = [-71.0940009 -71.0934685 -71.0900125];
%
% geoimread('boston.tif',lat,lon,500);
%
%% Author Info:
%
% (c) Aslak Grinsted 2014- (http://www.glaciology.net/)
%     & Chad A. Greene (http://chadagreene.com/)
%
%%
%
% See also GEOTIFFREAD, GEOTIFFINFO, PIXCENTERS, and PROJFWD.

%%  CHAD'S CHANGES:
% The following changes were made by Chad A. Greene (http://chadagreene.com/)
% of the University of Texas Institute for Geophysics (UTIG) on Sept 17, 2014:
%
% * More input checking and error messages.
%
% * Clarified syntax and description in header.
%
% * The fileparts line now only writes the file extension because other outputs went unused.
%
% * If geographic coordinate limits are inferred, they are now ordered latlim,lonlim. <-- **FUNCTIONALITY CHANGE**
%
% * Limits xlim, ylim or latlim, lonlim can be scalar, vector, or matrix-- xlim is now taken
%   as xlim = [min(xlim(:)) max(xlim(:))]. This will save a small step if you have some data points
%   given by x,y.  Now you can simply enter your data coordinates and geoimread will
%   figure out the limits.
%
% * Output variable I now has correct corner coordinates for the subset image instead of
%   the previous version which returned corner coordinates of the full original image.
%
% * A buffer can be specified around input limits.
%
%
% Syntax before the changes:
% geoimread('myimage.tif',[min(easting)-buffer_m max(easting)+buffer_m],...
%     [min(northing)-buffer_m max(northing)+buffer_m]);
%
% Syntax after the changes:
% geoimread('myimage.tif',easting,northing,buffer_m)
%
%

%TODO: support downsampling (ReductionLevel parameter in imread)
%TODO: use map2pix and latlon2pix instead of projfwd and pixcenters. more robust if it is a rotational coordinate system.

%% Set defaults:

usegeocoordinates = false;
returnNONsubsetImage = true;
buffer_x = 0;
buffer_y = 0;

%% Input checks:

% Check for mapping toolbox:
% assert(license('test','map_toolbox')==1,'geoimread requires Matlab''s Mapping Toolbox.')

% Check file type:
assert(isnumeric(filename)==0,'Input filename must be a string.')
[~,~,ext] = fileparts(filename);
switch upper(ext)
    case {'.JP2' '.JPEG2000' '.GEOJP2'}
        I = jp2tiffinfo(filename);
    case {'.TIF' '.TIFF' '.GTIF' '.GTIFF'}
        I = robustgeotiffinfo(filename);
    otherwise
        error('Unrecognized image file type. Must be tif, tiff, gtif, gtiff, jp2, jpeg2000, or geojp2.')
end

% Parse optional inputs:
if nargin>1
    returnNONsubsetImage = false;
    assert(nargin>2,'If you specify an xlim or latlim, you must specify a corresponding ylim or lonlim.')

    % Parse limits:
    xlimOrLatlim = varargin{1}(:);
    ylimOrLonlim = varargin{2}(:);

    assert(isnumeric(xlimOrLatlim)==1,'Input xlim or latlim must be numeric.')
    assert(isnumeric(ylimOrLonlim)==1,'Input ylim or lonlim must be numeric.')

    % Assume geo coordinates if no input limits exceed normal lat/lon values:
    if max(abs(xlimOrLatlim))<=90 && max(abs(ylimOrLonlim))<=360
        usegeocoordinates = true;
    end

    % Parse buffer:
    if nargin>3
        buffer_m = varargin{3};
        assert(isnumeric(buffer_m)==1,'Buffer value must be either a scalar or a two-element array.')
        assert(numel(buffer_m)<3,'Buffer value must be either a scalar or a two-element array.')
        buffer_x = buffer_m(1);
        if isscalar(buffer_m)
            buffer_y = buffer_m(1);
        else
            buffer_y = buffer_m(2);
        end
    end

    if nargin>4
        error('Too many inputs in geoimread.')
    end

end

%% Begin work:

% Get pixel coordinates of full (non-subset) image:
[x,y]=robustpixcenters(I);

if nargout==0
    fprintf('No outputs specified.\n')
    fprintf('X-range: %.1f:%.1f:%.1f\n',x(1),x(2)-x(1),x(end))
    fprintf('Y-range: %.1f:%.1f:%.1f\n',y(1),y(2)-y(1),y(end))
    clear A x y I
    return
end

% Set xlim and ylim depending on user inputs:
if returnNONsubsetImage
    xlimOrLatlim = x(:);
    ylimOrLonlim = y(:);
end

if usegeocoordinates
    % lat/lon limits switch to x/y limits here:
    if ~strcmp(I.ModelType,'ModelTypeGeographic')
        assert(license('test','map_toolbox')==1,'Mapping toolbox needed to project between lat/lon limits and x,y limits. Specify limits in x,y coordinates.')
        [xlimOrLatlim,ylimOrLonlim]=projfwd(I,xlimOrLatlim,ylimOrLonlim);
    end
end

xlim = [min(xlimOrLatlim)-buffer_x max(xlimOrLatlim)+buffer_x];
ylim = [min(ylimOrLonlim)-buffer_y max(ylimOrLonlim)+buffer_y];

% Rows and columns of pixels to read:
rows=find((y>=ylim(1))&(y<=ylim(2)));
cols=find((x>=xlim(1))&(x<=xlim(2)));

%% Display messages if region of interest is partly or wholly outside the image region:

if xlim(1)<min(x)||xlim(2)>max(x)
    disp('geoimread limits extend beyond the available image output in the x direction.')
end

if ylim(1)<min(y)||ylim(2)>max(y)
    disp('geoimread limits extend beyond the available image output in the y direction.')
end

if isempty(rows)||isempty(cols)
    error('No image coordinates can be found inside the specified limits.')
end

%% Load region of interest:
reductionlevel=0;
if reductionlevel==0
    rows=sort(rows([1 end]));
    cols=sort(cols([1 end]));
else
    %% Load region of interest:
    dpx=2^reductionlevel;
    rows=round(rows/dpx);cols=round(cols/dpx);

    rows=sort(rows([1 end]));
    cols=sort(cols([1 end]));
end
x=x(cols(1):cols(end));
y=y(rows(1):rows(end));

A=imread(filename,'PixelRegion',{rows cols});

%% Update info structure to more accurately reflect the new image:

if nargout == 4
    I.FileSize = numel(A);
    I.Height = size(A,1);
    I.Width = size(A,2);
    try
        I.TiePoints.WorldPoints.X = x(1);
        I.TiePoints.WorldPoints.Y = y(1);
        I.SpatialRef.RasterSize = [size(A,1),size(A,2)];
        I.RefMatrix(3,1) = x(1);
        I.RefMatrix(3,2) = y(1);
        I.BoundingBox = [min(x) min(y); max(x) max(y)];
        I.CornerCoords.X = [min(x) max(x) max(x) min(x)];
        I.CornerCoords.Y = [max(y) max(y) min(y) min(y)];
        %TODO: check whether GTRasterTypeGeoKey is RasterPixelIsArea or RasterPixelIsPoint
        I.CornerCoords.Row = .5 + [0 0 size(A,1) size(A,1)]; %TODO: is this .5 always true?
        I.CornerCoords.Col = .5 + [0 size(A,2) size(A,2) 0];
        [I.CornerCoords.Lat,I.CornerCoords.Lon] = projinv(I,I.CornerCoords.X,I.CornerCoords.Y);
        I.GeoTIFFTags.ModelTiepointTag(4) = x(1);
        I.GeoTIFFTags.ModelTiepointTag(5) = y(1);
        I.SpatialRef.XLimWorld = [min(x),max(x)];
        I.SpatialRef.YLimWorld = [min(y),max(y)];
    catch,end
end

%% Clean up:

function I=jp2tiffinfo(fname)
%
% This is a function that attempts to extract the geo-info from a jp2 file.
% There are two "standards" for how this can be stored:
% * GeoJP2: an embedded geotiff is stored in a "uuid" box with a specific id.
% * GMLJP2: an embedded gml file is in an asoc box.
% (extremely annoying that there are multiple "standards".)
%

%Documents:
% JP2 standard: http://www.jpeg.org/public/15444-1annexi.pdf
% GEOJP2 standard: http://wiki.opf-labs.org/download/attachments/11337762/15444-1annexi.pdf
% GMLJP2 standard: http://www.opengeospatial.org/standards/gmljp2

fid=fopen(fname,'r','ieee-be');
lblcontents='';
while ~feof(fid)
    lbox=fread(fid,1,'uint32');
    type=fread(fid,[1 4],'uint8=>char');
    switch lbox
        case 1
            lbox=fread(fid,1,'uint64');lbox=lbox-16;
        case 2:7 %"reserved reserved for ISO use" (????)
            lbox=8;%No idea why ... there is no info on how to interpret values 2-7.
            %Setting this to 8 works for sentinel-2 images.
        otherwise
            lbox=lbox-8;
    end

    switch type
        case 'asoc'
            %the asoc box is a container with other boxes. Set lbox to zero
            %so that we also parse the containing boxes.
            lbox=0;
        case 'lbl '
            %in gmljp2 the xml box is preceded by a lbl box. Read the
            %lbl box contents for later...
            lblcontents=fread(fid,[1 lbox],'uint8=>char');
            lbox=0;
        case 'xml '
            if (strfind(lblcontents,'gml')>0) %gmljp2:
                gmlcontents=fread(fid,[1 lbox],'uint8=>char');
                fout=fopen('.temp.xml','w');
                fwrite(fout,gmlcontents);
                fclose(fout);
                X=xmlread('.temp.xml');
                delete('.temp.xml');

                Elements=X.getElementsByTagName('gml:origin');
                origin=str2num(Elements.item(0).getTextContent());
                Elements=X.getElementsByTagName('gml:offsetVector');
                R=[];
                for ii=1:Elements.getLength
                    R{ii}=str2num(Elements.item(ii-1).getTextContent());
                end
                R=cell2mat(R');
                %ModelPixelScaleTag: [15 15 0]
                %ModelTiepointTag: [0 0 0 4.695e+05 7240500 0]
                assert((R(1,2)==0)&(R(2,1)==0),'unexpected offsetvector in GML');
                I=imfinfo(fname);
                I.GML=gmlcontents;
                I.ModelPixelScaleTag=[R(1,1) -R(2,2) 0]; %order and sign..
                I.ModelTiepointTag=[0 0 0 origin 0];
                fclose(fid);
                return %we have what we need - return
            end
        case 'uuid' %
            uuid=fread(fid,[1 16],'uint8=>char');
            lbox=lbox-16;
            geo=[177 75 248 189 8 61 75 67 165 174 140 215 213 166 206 3];
            if all(uuid==geo)
                fout=fopen('.temp.tif','w');
                contents=fread(fid,lbox,'uint8');lbox=0;
                fwrite(fout,contents);
                fclose(fout);
                fclose(fid);
                I=geotiffinfo_lcog_matlab2020a('.temp.tif');
                m=imfinfo(fname); % a little silly to use imfinfo when I already have a tag reader
                I.Height=m.Height;
                I.Width=m.Width;
                delete('.temp.tif');

                fclose(fid);
                return %we have what we need - return
            end
    end

    fseek(fid,lbox,0);

end
fclose(fid);

%--- BELOW is to make geoimread work even if no mapping toolbox (but with reduced functionality) ---

function I = robustgeotiffinfo(fname)
if license('test','map_toolbox')
    I=geotiffinfo_lcog_matlab2020a(fname);
else
    I=imfinfo(fname);
    % I.ModelType='ModelTypeProjected';  %TODO: fix
    %     %TODO: generate home-made refmatrix(?)....
    %     if isfield(tags, 'ModelTransformationTag') && numel(tags.ModelTransformationTag) >= 8
    %         geoimread does not work for rotated systems
    %
    %     else %use ModelPixelScaleTag instead
    %         dx =  I.ModelPixelScaleTag(1); dy = -I.ModelPixelScaleTag(2);
    %         x0 = I.ModelTiepointTag(4) - dx * I.ModelTiepointTag(1);
    %         y0 = I.ModelTiepointTag(5) - dy * I.ModelTiepointTag(2);
    %         J = [dx 0; 0 dy];
    %     end
    %     I.RefMatrix=[flipud(J); x0-J(1,1)-J(1,2)];
end

function [x,y]=robustpixcenters(I)
if license('test','map_toolbox') && isfield(I,'GeoTIFFCodes')
    [x,y]=pixcenters(I);
else
    %I have not read documentation... but this only works for rectilinear systems.
    assert(I.ModelPixelScaleTag(3)==0,'unexpected ModelPixelScaleTag format.');
    assert(all(I.ModelTiepointTag(1:3)==0),'unexpected ModelTiepointTag format.');
    x=((0:I.Width-1)-I.ModelTiepointTag(1))*I.ModelPixelScaleTag(1)+I.ModelTiepointTag(4);
    y=((0:I.Height-1)-I.ModelTiepointTag(2))*-I.ModelPixelScaleTag(2)+I.ModelTiepointTag(5);
end


% Converts a frequency to some scale and back again
%
% Copyright (c) 2018 Department of Computer Science,
%                    University of Toronto, Canada,
%                    Vector Institute, Canada
%
% License
% This file is under the LGPL license,  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. This file 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.
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Author
%  Yingxue Wang <yingxue@cs.toronto.edu>
%  Sean Robertson <sdrobert@cs.toronto.edu>
%

classdef ScalingFunction < handle
    methods (Abstract)
        scale_to_hertz(obj, scale)
        hertz_to_scale(obj, hertz)
    end

end


classdef ComparingSuperEllipseVsRectangle < handle

    properties (Access = private)
       mesh
       dataRes
       m1S
       m2S
       m1R
       m2R
    end

    properties (Access = private)
        path
        fileNameMesh
        fileResName
        pNorm
        microCase
    end

    methods (Access = public)

        function obj = ComparingSuperEllipseVsRectangle()
            obj.init()
            obj.wrapResAndMesh();
            obj.computeDesignParams();
            obj.computeStresses();
        end

    end

    methods (Access = private)

        function init(obj)
            obj.microCase = 'SuperEllipse';'Rectangle';
            meshType  = 'Medium';'Small';
            finalIter = '589';'485';'405';'250';'296';
            fCase = [obj.microCase,'Rotation',meshType];
            obj.path = ['/media/alex/My Passport/LatticeResults/StressNorm',fCase,'/'];
            obj.fileResName  = ['ExperimentingPlot',finalIter];
            obj.fileNameMesh = ['CantileverSquare',meshType];
            obj.pNorm = 2:2:32;
        end

        function wrapResAndMesh(obj)
            s.folderPath = obj.path;
            s.fileName   = obj.fileResName;
            w = WrapperMshResFiles(s);
            w.compute();
            obj.mesh    = w.mesh;
            obj.dataRes = w.dataRes;
        end

        function computeDesignParams(obj)
            switch obj.microCase
                case 'Rectangle'
                   obj.computeDesignParamsFromrectangleExample();
                case 'SuperEllipse'
                   obj.computeDesignParamsFromSuperEllipseExample();
            end
        end

        function computeDesignParamsFromSuperEllipseExample(obj)
            obj.m1S = obj.dataRes.DesignVar1;
            obj.m2S = obj.dataRes.DesignVar2;
            [obj.m1R,obj.m2R] = obj.computeRectangleM1M2FromSuperEllipseM1M2(obj.m1S,obj.m2S);
        end

        function computeDesignParamsFromrectangleExample(obj)
            obj.m1S = obj.dataRes.DesignVar1;
            obj.m2S = obj.dataRes.DesignVar2;
            [obj.m1R,obj.m2R] = obj.computeRectangleM1M2FromSuperEllipseM1M2(obj.m1S,obj.m2S);
        end

        function computeStresses(obj)
           valueR = obj.computeStressNormRectangle();
           valueS = obj.computeStressNormSuperEllipse();
           f = figure();
           hold on
           p{1} = plot(obj.pNorm,valueR);
           p{2} = plot(obj.pNorm,valueS);
           legend({'Rectangle','SuperEllipse'},'Location','Best');
           xlabel('p');
           ylabel('||\sigma||_p');
           pP = plotPrinter(f,p);
           fName = '/home/alex/Dropbox/GregMeeting30Octubre/Comparison';
           pP.print(fName)
        end

        function value = computeStressNormSuperEllipse(obj)
            s.m1            = obj.m1S;
            s.m2            = obj.m2S;
            s.alpha         = obj.dataRes.AlphaGauss';
            s.vademecumName = 'SuperEllipseQOptAnalytic';
            s.mesh          = obj.mesh;
            s.fileName      = obj.fileNameMesh;
            s.pNorm         = obj.pNorm;
            sC = StressNormFromVademecumComputer(s);
            value = sC.compute();
        end

        function value = computeStressNormRectangle(obj)
            s.m1            = obj.m1R;
            s.m2            = obj.m2R;
            s.alpha         = obj.dataRes.AlphaGauss';
            s.vademecumName = 'SuperEllipseQMax';
            s.mesh          = obj.mesh;
            s.fileName      = obj.fileNameMesh;
            s.pNorm         = obj.pNorm;
            sC = StressNormFromVademecumComputer(s);
            value = sC.compute();
        end

    end

    methods (Access = private, Static)

        function [m1R,m2R] = computeRectangleM1M2FromSuperEllipseM1M2(m1S,m2S)
            sE   = SuperEllipseParamsRelator;
            s.type  = 'Optimal';
            s.m1    = m1S;
            s.m2    = m2S;
            sM = SmoothingExponentComputer.create(s);
            qS(:,1) = sM.compute();
            rho  = sE.rho(m1S,m2S,qS);
            xi   = sE.xi(m1S,m2S);
            s.type  = 'Given';
            s.q    = 32*ones(size(m1S));
            sM = SmoothingExponentComputer.create(s);
            qR(:,1) = sM.compute();
            m1R = sE.mx(xi,rho,qR);
            m2R = sE.my(xi,rho,qR);
        end

        function [m1S,m2S] = computeSuperEllipseM1M2FromRectangleM1M2(m1R,m2R)
            sE   = SuperEllipseParamsRelator;
            rho  = sE.rho(m1R,m2R,q);
            xi   = sE.xi(m1R,m2R);
            s.type  = 'Optimal';
            s.m1    = [];
            s.m2    = [];
            sM = SmoothingExponentComputer.create(s);
            qS(:,1) = sM.computeQ(rho,xi);
            m1S = sE.mx(xi,rho,qS);
            m2S = sE.my(xi,rho,qS);
        end

    end

end


function [ pred,model,prob ] = classf_( methodName,X,Y,param,Xtest )
%CLASSF_ Classification, such as KNN, SVM, ...
%	[ pred,model,prob ] = classf_( methodName,X,Y,param,Xtest )
%   A wrapper to call classf_methodName_tr/te. Returns the predicted labels
%   PRED for XTEST and its confidence PROB, the MODEL of the classifier for later
%   test data. The parameters PARAM is optional. PROB may only be available
%   for some methods.
%	METHODNAME is case insensitive.

%   Example:
%		[pred,model,prob] =	classf_('svm',X,Y,struct('c',10),Xtest);

%	Copyright 2015 Ke YAN, Tsinghua Univ. http://yanke23.tk, xjed09@gmail.com

if ~exist('param','var')
	param = [];
end

methodName = lower(methodName);
code = sprintf('model=classf_%s_tr(X,Y,param);', methodName);
eval(code);
code = sprintf('[pred,prob]=classf_%s_te(model,Xtest);', methodName);
eval(code);

end


%SERIALLINK.TRCHAIN Convert to elementary transform sequence
%
% S = R.TRCHAIN(OPTIONS) is a sequence of elementary transforms that describe the
% kinematics of the serial link robot arm.  The string S comprises a number
% of tokens of the form X(ARG) where X is one of Tx, Ty, Tz, Rx, Ry, or Rz.
% ARG is a joint variable, or a constant angle or length dimension.
%
% For example:
%        >> mdl_puma560
%        >> p560.trchain
%        ans =
%        Rz(q1)Rx(90)Rz(q2)Tx(0.431800)Rz(q3)Tz(0.150050)Tx(0.020300)Rx(-90)
%        Rz(q4)Tz(0.431800)Rx(90)Rz(q5)Rx(-90)Rz(q6)
%
% Options::
% '[no]deg'    Express angles in degrees rather than radians (default deg)
% 'sym'        Replace length parameters by symbolic values L1, L2 etc.
%
% See also trchain, trotx, troty, trotz, transl, DHFactor.

% Copyright (C) 1993-2017, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB 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.
%
% RTB 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 RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

function s = trchain(robot, varargin)

    opt.sym = false;
    opt.deg = true;
    opt = tb_optparse(opt, varargin);

    if opt.deg
        conv = 180/pi;
    else
        conv = 1;
    end

    s = '';
    varcount = 1;

    for j=1:robot.n
        L = robot.links(j);

        if robot.ismdh()
            % Method for modified DH parameters

            % Append Tx(a)
            if L.a ~= 0
                if opt.sym
                    s = append(s, 'Tx(L%d)', varcount);
                    varcount = varcount+1;
                else
                    s = append(s, 'Tx(%g)', L.a);
                end

            end

            % Append Rx(alpha)
            if L.alpha ~= 0
                s = append(s, 'Rx(%g)', (L.alpha*conv));
            end

            if L.isrevolute()

                % Append Tz(d)
                if L.d ~= 0
                    if opt.sym
                        s = append(s, 'Tz(L%d)', varcount);
                        varcount = varcount+1;
                    else
                        s = append(s, 'Tz(%g)', L.d);
                    end
                end

                % Append Rz(q)
                s = append(s, 'Rz(q%d)', j);
            else

                % Append Rz(theta)
                if L.theta ~= 0
                    s = append(s, 'Rz(%g)', (L.alpha*conv));
                end

                % Append Tz(q)
                s = append(s, 'Tz(q%d)', j);
            end

        else
            % Method for standard DH parameters

            if L.isrevolute()

                % Append Rz(q)
                s = append(s, 'Rz(q%d)', j);

                % Append Tz(d)
                if L.d ~= 0
                    if opt.sym
                        s = append(s, 'Tz(L%d)', varcount);
                        varcount = varcount+1;
                    else
                        s = append(s, 'Tz(%g)', L.d);
                    end
                end
            else

                % Append Rz(theta)
                if L.theta ~= 0
                    s = append(s, 'Rz(%g)', (L.alpha*conv));
                end

                % Append Tz(q)
                s = append(s, 'Tz(q%d)', j);
            end

            % Append Tx(a)
            if L.a ~= 0
                if opt.sym
                    s = append(s, 'Tx(L%d)', varcount);
                    varcount = varcount+1;
                else
                    s = append(s, 'Tx(%g)', L.a);
                end

            end

            % Append Rx(alpha)
            if L.alpha ~= 0
                s = append(s, 'Rx(%g)', (L.alpha*conv));
            end
        end
    end
end

    function s = append(s, fmt, j)
        s = strcat(s, sprintf(fmt, j));
    end


function inspect_pull1946

% WALLTIME 00:10:00
% MEM 2gb
% DEPENDENCY ft_databrowser

%%
% create some uniform data

nchan = 10;
ntrial = 30;
nsample = 1000;
fsample = 1000;

data = [];
for i=1:nchan
  data.label{i} = num2str(i);
end

for i=1:ntrial
  data.trial{i} = randn(nchan,nsample);
  data.time{i}  = (1:nsample)/fsample;
end

data.sampleinfo(:,1) = ((1:ntrial)-1)*nsample+1;
data.sampleinfo(:,2) = ((1:ntrial)  )*nsample;

% add an artifact to channel 2, trial 2
data.trial{2}(2,:) = 3 * data.trial{2}(2,:);

%%

cfg = [];
cfg.method = 'summary';
cfg.keeptrials = 'yes';
cfg.keepchannels = 'yes';
cfg.channel = setdiff(1:nchan, 2);
cfg.trials = setdiff(1:ntrial, 2);
dataclean = ft_rejectvisual(cfg, data);


function [ fea, out ] = ex_navierstokes12( varargin )
%EX_NAVIERSTOKES12 3D Example flow over a backwards facing step
%
%   [ FEA, OUT ] = EX_NAVIERSTOKES12( VARARGIN ) Sets up and solves stationary and
%   laminar 3D flow over a backwards facing step. Accepts the following property/value pairs.
%
%       Input       Value/{Default}        Description
%       -----------------------------------------------------------------------------------
%       rho         scalar {1}             Density
%       miu         scalar {2/3/389}       Molecular/dynamic viscosity
%       uin         scalar {1}             Magnitude of inlet velocity
%       sf_u        string {sflag1}        Shape function for velocity
%       sf_p        string {sflag1}        Shape function for pressure
%       solver      string 'openfoam'/{''} Use OpenFOAM or default solver
%       iplot       scalar 0/{1}           Plot solution and error (=1)
%                                                                                .
%       Output      Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       fea         struct                 Problem definition struct
%       out         struct                 Output struct
%
%   See also EX_NAVIERSTOKES4

% Copyright 2013-2022 Precise Simulation, Ltd.

cOptDef = {   ...
  'rho',      1;
  'miu',      2/3/389;
  'uin',      1;
  'igrid',    1;
  'sf_u',     'sflag1';
  'sf_p',     'sflag1';
  'solver',   '';
  'iplot',    1;
  'tol',      0.55;
  'fid',      1 };
[got,opt] = parseopt(cOptDef,varargin{:});
fid       = opt.fid;

% Geometry.
h_step = 0.0049/0.0101;
l_inlet = 0.02/0.0101;
l_channel = 0.08/0.0101;
fea.sdim = { 'x', 'y', 'z' };
gobj1 = gobj_block( -l_inlet, l_channel, -0.5, 0.5, -h_step, 1-h_step, 'B1' );
gobj2 = gobj_block( -l_inlet, 0, -0.5, 0.5, -h_step, 0, 'B2' );
fea.geom.objects = { gobj1, gobj2 };
fea = geom_apply_formula( fea, 'B1-B2' );

% Grid generation.
if( opt.igrid>=1 )
  n = 4;
  fea.grid = rectgrid(10*n,n,[-l_inlet, l_channel; -0.5, 0.5]);
  fea.grid = delcells( fea.grid, selcells(fea.grid,'(y<=0).*(x<=0)') );
  ix = find( fea.grid.p(2,:) <= -0.5 + sqrt(eps) );
  fea.grid.p(2,ix) = -h_step;
  ix = find( fea.grid.p(2,:) >= 0.5 - sqrt(eps) );
  fea.grid.p(2,ix) = 1-h_step;

  fea.grid = gridextrude( fea.grid, n, 1, -2 );
  fea.grid.p(2,:) = fea.grid.p(2,:) + 0.5;
  fea.grid = assign_bdr( fea.grid, fea.geom );
  for i=1:opt.igrid
    fea.grid = gridrefine( fea.grid, fid );
  end
else
  fea.grid = gridgen( fea, 'hmax', 0.1, 'fid', fid );
  % fea.grid = gridsmooth( tet2hex( fea.grid ), 5 );
end

% Problem definition.
fea = addphys( fea, @navierstokes );
fea.phys.ns.eqn.coef{1,end} = { opt.rho };
fea.phys.ns.eqn.coef{2,end} = { opt.miu };
fea.phys.ns.sfun            = { opt.sf_u opt.sf_u opt.sf_u opt.sf_p };
% fea.phys.ns.prop.artstab.iupw = 4;
if( any(strcmp(opt.solver,{'openfoam','su2'})) )
  [fea.phys.ns.sfun{:}] = deal('sflag1');
end

% Boundary conditions.
i_inflow  = findbdr( fea, ['x<',num2str(-l_inlet+1e-3)] );   % Inflow boundary number.
i_outflow = findbdr( fea, ['x>',num2str( l_channel-1e-3)] );   % Outflow boundary number.
% s_inflow  = ['4*',num2str(umax),'*(y*(',num2str((1-y)*h),'-y))/',num2str((1-y)*h),'^2'];   % Definition of inflow profile.
s_inflow  = ['4*',num2str(opt.uin),'*(z*(',num2str(1-h_step),'-z))/(1-',num2str(1-h_step),')^2'];
u_init    = [s_inflow,'*(z>0)'];
fea.phys.ns.bdr.sel(i_inflow) = 2;
fea.phys.ns.bdr.sel(i_outflow) = 4;
fea.phys.ns.bdr.coef{2,end}{1,i_inflow} = s_inflow;
if( ~strcmp(opt.solver,'openfoam') )
  fea.phys.ns.eqn.coef{6,end} = { u_init };
end

% Parse and solve problem.
fea  = parsephys( fea );
fea  = parseprob( fea );
if( strcmp(opt.solver,'openfoam') )
  logfid = fid; if( ~got.fid ), fid = []; end
  fea.sol.u = openfoam( fea, 'fid', fid, 'logfid', logfid );
  fid = logfid;
elseif( strcmp(opt.solver,'su2') )
  logfid = fid; if( ~got.fid ), fid = []; end
  fea.sol.u = su2( fea, 'fid', fid, 'logfid', logfid );
  fid = logfid;
else
  fea.sol.u = solvestat( fea, 'maxnit',50, 'nlrlx',1, 'tolchg',1e-3, 'fid', fid );
end

% Postprocessing.
if( opt.iplot>0 )
  postplot( fea, 'sliceexpr', 'sqrt(u^2+v^2+w^2)' )
end

% Error checking.
[~,slen] = minmaxsubd( ['(u<-eps)*x/',num2str(h_step),'*(z<0)*(y<0.01)*(y>-0.01)'], fea );
if( ~isempty(fid) )
  fprintf(fid,'\nRecirculation zone length: %3f (Ref: 7.93)\n\n',slen)
  fprintf(fid,'\n\n')
end

out.slen = [slen, 7.93];
out.err  = abs(diff(out.slen))/out.slen(end);
out.pass = out.err<opt.tol;

if ( nargout==0 )
  clear fea out
end


function [posterior] = tapas_sem_hier_prepare_posterior(data, model, ...
    inference, states)
%%
%
% aponteeduardo@gmail.com
% copyright (C) 2016
%

T = model.graph{1}.htheta.T;

posterior = struct('data', data, 'model', model, 'inference', inference, ...
    'samples_theta', [], 'fe', [], 'llh', []);

np = numel(states);

theta = cell(floor(np/inference.thinning), 1);
nc = 1;
for i = 1:inference.thinning:np
    theta{nc} = states{i}.graph{2}(:, end);
    nc = nc + 1;
end

% Contains all the terms related to the likelihood
cllh = cell(2, 1);

[ns, nc] = size(states{1}.llh{1});

% Log likelihood under the posteriors
llh = zeros(ns, nc, floor(np/inference.thinning));
nc = 1;

for i = 1:inference.thinning:np
    llh(:, :, nc) = states{i}.llh{1};
    nc = nc + 1;
end

cllh{1} = llh;

posterior.llh = cllh;
if size(T, 2) > 1
    fe = trapz(T(1, :), mean(squeeze(sum(cllh{1}, 1)), 2));
else
    fe = nan;
end

posterior.fe = fe;

% Compute the WAIC / sum of the variance of the log likelihood
% (gradient of the FE) Take only the last chain (second dimension)
[waic, accuracy] = tapas_waic(squeeze(llh(:, end, :)));

posterior.waic = waic;
posterior.accuracy = accuracy;

posterior.T = T;

theta = horzcat(theta{:});
jm = model.graph{1}.htheta.model.jm;
p0 = model.graph{1}.htheta.model.p0;

for i = 1:numel(theta)
    theta{i} = p0 + jm * theta{i};
end

posterior.ps_theta = theta;

% Add the summaries automatically
posterior.summary = tapas_sem_posterior_summary(posterior);

end


function xyz = bvh2xyz(skel, channels, noOffset)

% BVH2XYZ Compute XYZ values given structure and channels.
% FORMAT
% DESC Computes X, Y, Z coordinates given a BVH skeleton structure and
% an associated set of channels.
% ARG skel : a skeleton for the bvh file.
% ARG channels : the channels for the bvh file.
% ARG noOffset : don't add the offset in.
% RETURN xyz : the point cloud positions for the skeleton.
%
% COPYRIGHT : Neil D. Lawrence, 2005, 2008, 2012
%
% SEEALSO : acclaim2xyz, skel2xyz

% MOCAP

if nargin< 3
  noOffset = false;
end
for i = 1:length(skel.tree)
  if ~isempty(skel.tree(i).posInd)
    xpos = channels(skel.tree(i).posInd(1));
    ypos = channels(skel.tree(i).posInd(2));
    zpos = channels(skel.tree(i).posInd(3));
  else
    xpos = 0;
    ypos = 0;
    zpos = 0;
  end
  xyzStruct(i) = struct('rotation', [], 'xyz', []);
  if nargin < 2 | isempty(skel.tree(i).rotInd)
    xangle = 0;
    yangle = 0;
    zangle = 0;
  else
    xangle = deg2rad(channels(skel.tree(i).rotInd(1)));
    yangle = deg2rad(channels(skel.tree(i).rotInd(2)));
    zangle = deg2rad(channels(skel.tree(i).rotInd(3)));
  end
  thisRotation = rotationMatrix(xangle, yangle, zangle, skel.tree(i).order);
  thisPosition = [xpos ypos zpos];
  if ~skel.tree(i).parent
      xyzStruct(i).rotation = thisRotation;
      xyzStruct(i).xyz = thisPosition + skel.tree(i).offset;
  else
      if ~noOffset
          thisPosition = skel.tree(i).offset + thisPosition;
      end
      xyzStruct(i).xyz = ...
          thisPosition*xyzStruct(skel.tree(i).parent).rotation ...
          + xyzStruct(skel.tree(i).parent).xyz;
      xyzStruct(i).rotation = thisRotation*xyzStruct(skel.tree(i).parent).rotation;

  end
end
xyz = reshape([xyzStruct(:).xyz], 3, length(skel.tree))';


%%**********************************************************************
%% NTpred: Compute (dX,dy,dZ) for NT direction.
%%
%% compute SVD of Xchol*Zchol via eigenvalue decompostion of
%%     Zchol * X * Zchol' = V * diag(sv2) * V'.
%% compute W satisfying W*Z*W = X.
%%     W = G'*G,  where G = diag(sqrt(sv)) * (invZchol*V)'
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%**********************************************************************

function [par,dX,dy,dZ,coeff,L,hRd] = ...
    NTpred(blk,At,par,rp,Rd,sigmu,X,Z,Zchol,invZchol)

global schurfun schurfun_par
%%
%% compute NT scaling matrix
%%
[par.W,par.G,par.sv,par.gamx,par.gamz,par.dd,par.ee,par.ff] = ...
    NTscaling(blk,X,Z,Zchol,invZchol);
%%
%% compute schur matrix
%%
m = length(rp);
schur = sparse(m,m);
UU = []; EE = []; Afree = [];
%%
for p = 1:size(blk,1)
    pblk = blk(p,:);
    if strcmp(pblk{1},'l')
        [schur,UU,EE] = schurmat_lblk(blk,At,par,schur,UU,EE,p,par.dd);
    elseif strcmp(pblk{1},'q');
        [schur,UU,EE] = schurmat_qblk(blk,At,par,schur,UU,EE,p,par.dd,par.ee);
    elseif strcmp(pblk{1},'s')
        if isempty(schurfun{p})
            schur = schurmat_sblk(blk,At,par,schur,p,par.W);
        elseif ischar(schurfun{p})
            if ~isempty(par.permZ{p})
                Wp = par.W{p}(par.permZ{p},par.permZ{p});
            else
                Wp = par.W{p};
            end
            schurtmp = feval(schurfun{p},Wp,Wp,schurfun_par(p,:));
            schur = schur + schurtmp;
        end
    elseif strcmp(pblk{1},'u')
        Afree = [Afree, At{p}']; %#ok
    end
end
%%
%% compute rhs
%%
[rhs,EinvRc,hRd] = NTrhsfun(blk,At,par,X,Z,rp,Rd,sigmu);
%%
%% solve linear system
%%
[xx,coeff,L] = linsysolve(par,schur,UU,Afree,EE,rhs);
%%
%% compute (dX,dZ)
%%
[dX,dy,dZ] = NTdirfun(blk,At,par,Rd,EinvRc,xx,m);
%%**********************************************************************


function [TrainData, TestData, TrainLabel, TestLabel] = createData_TriTL()
    % source domain (train)
    A = load(strcat('data/TrainSelect_8.data'));
    B = spconvert(A);
    n1 = size(B,2);
    for i = 1:n1
        TrainY1(1,i) = 1;
    end
    A1 = load(strcat('data/TrainSelect_12.data'));
    B1 = spconvert(A1);
    n2 = size(B1,2);
    for i = 1:n2
        TrainY1(1,i+n1) = 2;
    end
    TrainX1 = [B,B1];
    clear A B A1 B1;

    A = load(strcat('data/TrainSelect_9.data'));
    B = spconvert(A);
    n1 = size(B,2);
    for i = 1:n1
        TrainY2(1,i) = 1;
    end
    A1 = load(strcat('data/TrainSelect_13.data'));
    B1 = spconvert(A1);
    n2 = size(B1,2);
    for i = 1:n2
        TrainY2(1,i+n1) = 2;
    end
    TrainX2 = [B,B1];
    clear A B A1 B1;

    A = load(strcat('data/TrainSelect_10.data'));
    B = spconvert(A);
    n1 = size(B,2);
    for i = 1:n1
        TrainY3(1,i) = 1;
    end
    A1 = load(strcat('data/TrainSelect_14.data'));
    B1 = spconvert(A1);
    n2 = size(B1,2);
    for i = 1:n2
        TrainY3(1,i+n1) = 2;
    end
    TrainX3 = [B,B1];
    clear A B A1 B1;

    % target domain (test)
    A = load(strcat('data/TrainSelect_11.data'));
    B = spconvert(A);
    n1 = size(B,2);
    for i = 1:n1
        TestY(1,i) = 1;
    end
    A1 = load(strcat('data/TrainSelect_15.data'));
    B1 = spconvert(A1);
    n2 = size(B1,2);
    for i = 1:n2
        TestY(1,i+n1) = 2;
    end
    TestX = [B,B1];
    clear A B A1 B1;

    TrainData{1,1} = TrainX1;
    TrainLabel{1,1} = TrainY1;
    TrainData{1,2} = TrainX2;
    TrainLabel{1,2} = TrainY2;
    TrainData{1,3} = TrainX3;
    TrainLabel{1,3} = TrainY3;
    TestData{1,1} = TestX;
    TestLabel{1,1} = TestY;
    save inputData.mat TrainData TrainLabel TestData TestLabel
end


function A = myACF(V)
%%
%% Provides all N-1 autocovariance estimates from a vector of observations
%%
N = length(V);
A = xcov(V(~isnan(V)), 'biased')';
NV = sum(~isnan(V));
A = [repmat(NaN, 1, N-NV+1) A(NV:(2*(NV-1)))];


% Clear Matlab command window.
clc;

% Example #1: Basic usage.
% Note: Filters are computed for each run.
disp('Example #1: Basic Usage');
theta = [0:15:360];
for i = [1:length(theta)]
   [J,H] = steerGauss([],theta(i),3,true);
   filters{i} = H;
   pause(0.1);
end
disp('   Press any key to continue.'); pause;

% Load "mandrill" test image.
I = imread('mandrill.jpg');

% Example #2: Using pre-computed filters.
disp('Example #2: Using pre-computed filters.');
for i = [1:length(filters)]
   [J,H] = steerGauss(I,filters{i},true);
   pause(0.1);
end


function obj = extras_autonn_custom_fn(block, inputs, params)
% EXTRAS_AUTONN_CUSTOM_FN autonn custom layer converter for extra
% layers
%
% Copyright (C) 2017 Samuel Albanie
% Licensed under The MIT License [see LICENSE.md for details]

  switch class(block)
    case 'dagnn.Normalize'
      obj = Layer.create(@vl_nnscalenorm, {inputs{1}, params{1}}) ;
    case 'dagnn.Permute'
      obj = Layer.create(@permute, {inputs{1}, block.order}) ;
    case 'dagnn.Flatten'
      obj = Layer.create(@vl_nnflatten, {inputs{1}, block.axis}) ;
    case 'dagnn.GlobalPooling'
      obj = Layer.create(@vl_nnglobalpool, inputs(1)) ;
    case 'dagnn.Reshape'
      obj = Layer.create(@vl_nnreshape, {inputs{1}, block.shape}) ;
    case 'dagnn.Max'
      obj = Layer.create(@vl_nnmax, [{numel(inputs)}, inputs]) ;
    case 'dagnn.Crop'
      obj = vl_nncrop_wrapper(inputs{1}, inputs{2}, block.crop) ;
    case 'dagnn.Axpy'
      obj = Layer.create(@vl_nnaxpy, inputs(1:3)) ;
    case 'dagnn.Interp'
      obj = Layer.create(@vl_nninterp, {inputs{1}, block.shrinkFactor, ...
                        block.zoomFactor, 'padBeg', block.padBeg, ...
                        'padEnd', block.padEnd}) ;
    case 'dagnn.SoftMaxTranspose'
      obj = Layer.create(@vl_nnsoftmaxt, {inputs{1}, 'dim', block.dim}) ;
    case 'dagnn.Scale'
      args = {'numInputDer', 3} ; hasBias = block.hasBias ; % simplify interface
      if hasBias, ins = inputs(1:3) ; else, ins = [inputs(1:2) {[]}] ; end
      obj = Layer.create(@vl_nnscale, [ins {'size', block.size}], args{:}) ;
    case 'dagnn.PriorBox'
      obj = Layer.create(@vl_nnpriorbox, {inputs{1}, inputs{2}, ...
                                  'aspectRatios', block.aspectRatios, ...
                                  'pixelStep', block.pixelStep, ...
                                  'variance', block.variance, ...
                                  'minSize', block.minSize, ...
                                  'maxSize', block.maxSize, ...
                                  'offset', block.offset, ...
                                  'flip', block.flip, ...
                                  'clip', block.clip}, ...
                                  'numInputDer', 0) ;
    case 'dagnn.MultiboxDetector'
      numClasses = double(block.numClasses) ; % fixes weird bug
      obj = Layer.create(@vl_nnmultiboxdetector, ...
                                 {inputs{1}, inputs{2}, inputs{3}...
                                 'numClasses', numClasses, ...
                                 'nmsThresh', block.nmsThresh}, ...
                                 'numInputDer', 0) ;
    case 'SpatialSoftMax'
      obj = Layer.create(@vl_nnspatialsoftmax, inputs) ;
    otherwise, keyboard
  end


function out = SC_fastdfa(y)
% SC_fastdfa   Matlab wrapper for Max Little's ML_fastdfa code
%
% Measures the scaling exponent of the time series using a fast implementation
% of detrended fluctuation analysis (DFA).
%
%---INPUT:
% y, the input time series, is fed straight into the fastdfa script.

% The original fastdfa code is by Max A. Little and publicly-available at
% http://www.maxlittle.net/software/index.php
% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This function 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/>.
% ------------------------------------------------------------------------------

if size(y,2) > size(y,1);
    y = y'; % Ensure input time series is a column vector
end

out = ML_fastdfa(y);

end


function F = vertcat(F , G)
%VERTCAT   Vertical concatenation of SPHEREFUNV objects.
%   [F ; f] where F is a SPHEREFUNV with two components, and f is a SPHEREFUN or
%   scalar then returns a SPHEREFUNV with three components. The first and second
%   component remain unchanged and the third component is f.
%
%   [f ; F] where F is a SPHEREFUNV with two components, and f is a SPHEREFUN or
%   scalar then returns a SPHEREFUNV with three components. The first is f, and
%   the second and third are the first and second components of F.

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

if ( isempty(F) || isempty(G) )
    F = spherefunv;
    return
end

if ( isa(G, 'double') )
    Fc = F.components;
    dom = Fc{1}.domain;
    G = spherefun(G, Fc{1}.domain);
elseif ( isa(F, 'double') )
    Gc = G.components;
    dom = Gc{1}.domain;
    F = spherefun(F, Gc{1}.domain);
elseif ( isa(G, 'spherefun') )
    if ( ~domainCheck(F.components{1}, G) )
        error('SPHEREFUN:SPHEREFUNV:vertcat:domain', 'Inconsistent domains.')
    end
    dom = G.domain;
else
    error('SPHEREFUN:SPHEREFUNV:vertcat:notSupported', ...
        'Vertical concatenation of these objects is not supported.')
end

if ( isa(F, 'spherefunv') )
    op = [ F.components, {G} ];
else
    op = [ {F}, G.components ];
end

F = spherefunv(op, dom);

end


function pde = TorusTimeInitial3(mum,mup,sigm,sigp,epsm,epsp,omega,x0,y0,z0,r1,r2,a,b,intPt)
%% USAGE: polynomial solution for Poisson equation
%  Last Modified: 02/21/2020 by Xu Zhang

%% PDE Structure
pde = struct('intf',@intf,...
    'f1',@f1,'f2',@f2,'f3',@f3,...
    'fm1',@fm1,'fm2',@fm2,'fm3',@fm3,...
    'fp1',@fp1,'fp2',@fp2,'fp3',@fp3,...
    'Mu',@Mu,'Mum',@Mum,'Mup',@Mup,'one',@one,...
    'Epslon',@Epslon,'Epslonm',@Epslonm,'Epslonp',@Epslonp,...
    'Sig',@Sig,'Sigm',@Sigm,'Sigp',@Sigp,...
    'E1',@E1,'E2',@E2,'E3',@E3,...
    'Et1',@Et1,'Et2',@Et2,'Et3',@Et3);

pde.mum = mum;
pde.mup = mup;
pde.sigm = sigm;
pde.sigp = sigp;
pde.epsm = epsm;
pde.epsp = epsp;
%% interface function
    function u = intf(x,y,z)
        u = (sqrt((x-x0).^2+(y-y0).^2)-r2).^2 + (z-z0).^2 - r1^2;
    end

%% exact solution

%% right hand side function
    function u = f1(x,y,z,t)
        u = fm1(x,y,z,t);
        id = intf(x,y,z) > 0;
        u(id) = fp1(x(id),y(id),z(id),t);
    end
    function u = f2(x,y,z,t)
        u = fm2(x,y,z,t);
        id = intf(x,y,z) > 0;
        u(id) = fp2(x(id),y(id),z(id),t);
    end
    function u = f3(x,y,z,t)
        u = fm3(x,y,z,t);
        id = intf(x,y,z) > 0;
        u(id) = fp3(x(id),y(id),z(id),t);
    end

    function u = fm1(x,y,z,t)
        u = zeros(size(x));
    end
    function u = fm2(x,y,z,t)
        u = zeros(size(x));
    end
    function u = fm3(x,y,z,t)
        u = zeros(size(x));
    end
    function u = fp1(x,y,z,t)
        u = zeros(size(x));
    end
    function u = fp2(x,y,z,t)
        u = zeros(size(x));
    end
    function u = fp3(x,y,z,t)
        u = zeros(size(x));
    end

%%%%% intial condition
    function u = E1(x,y,z,t)
        u = exp(-b*(a*(x-intPt)-omega*t).^2);
%         id = pulregion(x,y,z) > 0;
%         u(id) = zeros(size(x(id)));
    end
    function u = E2(x,y,z,t)
        u = -exp(-b*(a*(x-intPt)-omega*t).^2);
    end
    function u = E3(x,y,z,t)
        u = zeros(size(x));
    end
    function u = Et1(x,y,z,t)
        u = exp(-b*(a*(x-intPt)-omega*t).^2)*2*omega*b.*(a*(x-intPt)-omega*t);
    end
    function u = Et2(x,y,z,t)
        u = -exp(-b*(a*(x-intPt)-omega*t).^2)*2*omega*b.*(a*(x-intPt)-omega*t);
    end
    function u = Et3(x,y,z,t)
        u = zeros(size(x));
    end
%     function u = pulregion(x,y,z)
%        u = (x-intPt).^2/(0.15)^2 - 1;
%     end
%% Diffusion coefficient function
    function u = Mu(x,y,z)
        u = Mum(x,y,z);
        id = intf(x,y,z) > 0;
        u(id) = Mup(x(id),y(id),z(id));
    end
    function u = Mum(x,y,z)
        u = mum^(-1)*ones(size(x));
    end
    function u = Mup(x,y,z)
        u = mup^(-1)*ones(size(x));
    end

%% Mass coefficient function
    function u = Epslon(x,y,z)
        u = Epslonm(x,y,z);
        id = intf(x,y,z) > 0;
        u(id) = Epslonp(x(id),y(id),z(id));
    end
    function u = Epslonm(x,y,z)
        u = epsm*ones(size(x));
    end
    function u = Epslonp(x,y,z)
        u = epsp*ones(size(x));
    end

    function u = Sig(x,y,z)
        u = Sigm(x,y,z);
        id = intf(x,y,z) > 0;
        u(id) = Sigp(x(id),y(id),z(id));
    end
    function u = Sigm(x,y,z)
        u = sigm*ones(size(x));
    end
    function u = Sigp(x,y,z)
        u = sigp*ones(size(x));
    end

%% Other function
    function u = one(x,y,z)
        u = ones(size(x));
    end
end


% Function to derive short term power contour as is done in Ishi et al 2008
%
% Description
% Function to derive short term power contour as is done in Ishi et al 2008
%
%
% Inputs
%  x        : [samples] [Nx1]  Speech signal
%  fs       : [Hz]      [1x1]  Sampling frequency
%
% Outputs
%  pow      : [dB]      [Mx1]  Power contour
%  pow_std  : [samples] [Px1]  Standard deviation of power contour
%
% Example
%  Please see the HOWTO_glottalsource.m example file.
%
% References
%  [1] Ishi, C., Sakakibara, K-I, Ishiguro, H., (2008) `A method for
%       automatic detection of vocal fry', IEEE TASLP, 16(1), 47-56.
%  [2] Drugman, T., Kane, J., Gobl, C., `Automatic Analysis of Creaky
%       Excitation Patterns', Submitted to Computer Speech and
%       Language.
%  [3] Kane, J., Drugman, T., Gobl, C., (2013) `Improved automatic
%       detection of creak', Computer Speech and Language 27(4), pp.
%       1028-1047.
%  [4] Drugman, T., Kane, J., Gobl, C., (2012) `Resonator-based creaky
%       voice detection', Interspeech 2012, Portland, Oregon, USA.
%
% Copyright (c) 2013 University of Mons, FNRS & 2013 Trinity College Dublin
%
% License
%  This code is a part of the GLOAT toolbox with the following
%  licence:
%  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.
%
% This function is part of the Covarep project: http://covarep.github.io/covarep
%
% Authors
%  Thomas Drugman <thomas.drugman@umons.ac.be> & John Kane <kanejo@tcd.ie>

function [pow,pow_std,pow_std_inter] = get_short_pow(x,fs)

% Get very short term power contour
veryShort_len = 4*(fs/1000); % 4ms frame length for "very short-term" analysis
veryShort_shift = 2*(fs/1000); % 2ms shift for "very short-term" analysis
veryShort_powCont = zeros(1,ceil((length(x)-veryShort_len)/veryShort_shift));
start=1;
finish=start+veryShort_len-1;

n=1;
x2 = x.^2;
while finish <= length(x)
    veryShort_powCont(n) = mean(x2(start:finish));
    start = start + veryShort_shift;
    finish=start+veryShort_len-1;
    n=n+1;
end
clear x2;

pow = 20*log10(veryShort_powCont);
inf_idx=isinf(pow);
pow(inf_idx)=min(pow(~inf_idx));

pow_std=zeros(1,length(pow));
std_len=16;

for n=std_len+1:length(pow)-std_len

    pow_std(n) = std(pow(n-std_len:n+std_len));
end
pow_std=medfilt1(pow_std,13);

pow_std_inter=interp1(linspace(1,length(x),length(pow)),pow_std,1:length(x));


%% SectoralCylinder
% Concrete subclass of <GenericCylinder.html |GenericCylinder|> representing a
% cylinder with a sectoral cross section.

%%% Description
% |SectoralCylinder| represents the shape of a sectoral cylinder.  Its cross
% section is a circular sector (angular portion of a disk).  The axis of the
% cylinder should be aligned with one of the axes of the Cartesian coordinate
% system.

%%% Construction
%  shape = SectoralCylinder(normal_axis, height, center, radius, theta, d_theta)
%  shape = SectoralCylinder(normal_axis, height, center, radius, theta, d_theta, dl_max)
%
% *Input Arguments*
%
% * |normal_axis|: axis of the cylinder.  It should be one of |Axis.x|,
% |Axis.y|, |Axis.z|.
% * |height|: size of the cylinder along its axis.
% * |center|: center of the cylinder in the format of |[x y z]|.  For
% |normal_axis = Axis.z|, |(x, y)| is the coordinate of the center of the
% circle.
% * |radius|: radius of the circle
% * |theta|: beginning angle of the sector in radian
% * |d_theta|: angular width of the sector in radian between -2*pi and 2*pi.
% * |dl_max|: maximum grid size allowed in the cylinder.  It can be either |[dx
% dy dz]| or a single real number |dl| for |dx = dy = dz|.  If unassigned,
% |dl_max = Inf| is used.

%%% Example
%   % Create an instance of SectoralCylinder.
%   shape = SectoralCylinder(Axis.z, 100, [0 0 50], 50, pi/6, pi/3);
%
%   % Use the constructed shape in maxwell_run().
%   [E, H] = maxwell_run({INITIAL ARGUMENTS}, 'OBJ', {'vacuum', 'none', 1.0}, shape, {REMAINING ARGUMENTS});

%%% See Also
% <SectoralCylinder.html |CircularCylinder|>, <CircularCylinder.html
% |CircularCylinder|>, <CircularShellCylinder.html
% |CircularShellCylinder|>, <EllipticCylinder.html |EllipticCylinder|>,
% <PolyognalCylinder.html |PolygonalCylinder|>, <Shape.html |Shape|>,
% <maxwell_run.html |maxwell_run|>

classdef SectoralCylinder < GenericCylinder

	properties (SetAccess = immutable)
		lsf_th  % level set function for angles
	end

	methods
        function this = SectoralCylinder(normal_axis, height, center, radius, theta, d_theta, dl_max)
			chkarg(istypesizeof(normal_axis, 'Axis'), '"normal_axis" should be instance of Axis.');
			chkarg(istypesizeof(height, 'real') && height > 0, '"height" should be positive.');
			chkarg(istypesizeof(center, 'real', [1, Axis.count]), ...
				'"center" should be length-%d row vector with real elements.', Axis.count);
			chkarg(istypesizeof(radius, 'real') && radius > 0, '"radius" should be positive.');
			chkarg(istypesizeof(theta, 'real'), '"theta" should be real.');
			chkarg(istypesizeof(d_theta, 'real') && (d_theta <= 2*pi || d_theta >= -2*pi), '"d_theta" should be real between -pi and pi.');

			thetas = sort([theta, theta + d_theta]);
			cth = mean(thetas);  % center of theta range
			cth = mod(cth + pi, 2*pi) - pi;  % -pi <= c_th < pi (range of atan2(y,x))
			sth = diff(thetas) / 2;  % semiwidth of theta range

			cr = radius/2;  % center of radius range
			sr = radius/2;  % semiwidth of radius range

			function level = lsf_th(th)
				dth = th - cth;
				dth = mod(dth + pi, 2*pi) - pi;
				level = 1 - abs(dth./sth);
			end

			[h, v, n] = cycle(normal_axis);

			% lsf2d() can handle rho = [p q] with column vectors p and q.  The
			% level set function is the one for a rectangle defined in the
			% (theta, radius) domain.
			function level = lsf2d(p, q)
				chkarg(istypeof(p, 'real'), '"p" should be array with real elements.');
				chkarg(istypeof(q, 'real'), '"q" should be array with real elements.');
				chkarg(isequal(size(p), size(q)), '"p" and "q" should have same size.');

				lc = {p - center(h), q - center(v)};  % locations in center-of-mass coordinates

				theta_pt = atan2(lc{Dir.v}, lc{Dir.h});  % -pi <= theta_rho < pi
				r_pt = sqrt(lc{Dir.h}.^2 + lc{Dir.v}.^2);
				zero_r_pt = (r_pt==0);  % atan2(0,0) is not well-defined; handle such cases separately

				dr = r_pt - cr;
				level = min(lsf_th(theta_pt), 1 - abs(dr./sr));
				level(zero_r_pt) = 0;
			end

			lprim = cell(1, Axis.count);
			lprim{h} = [radius * cos(thetas) + center(h), center(h)];
			lprim{v} = [radius * sin(thetas) + center(v), center(v)];
			lprim{n} = [-height height]/2 + center(n);

			if lsf_th(0) > 0  % sector contains +x-direction from center
				lprim{h} = [lprim{h}, center(h) + radius];
			end
			if lsf_th(pi/2) > 0  % sector contains +y-direction from center
				lprim{v} = [lprim{v}, center(v) + radius];
			end
			if lsf_th(pi) > 0  % sector contains -x-direction from center
				lprim{h} = [lprim{h}, center(h) - radius];
			end
			if lsf_th(3*pi/2) > 0  % sector contains -y-direction from center
				lprim{v} = [lprim{v}, center(v) - radius];
			end

			if nargin < 7  % no dl_max
				super_args = {normal_axis, @lsf2d, lprim};
			else
				super_args = {normal_axis, @lsf2d, lprim, dl_max};
			end

			this = this@GenericCylinder(super_args{:});
			this.lsf_th = @lsf_th;
		end
	end
end


function ds_dsm = cosmo_dissimilarity_matrix_measure(ds, varargin)
% Compute a dissimilarity matrix measure
%
% ds_dsm = cosmo_dissimilarity_matrix_measure(ds[, varargin])
%
% Inputs:
%  dataset            dataset struct with fields .samples (PxQ) and
%                     .sa.targets (Px1) for P samples and Q features.
%                     each target should occur exactly once
%  args               optional struct:
%      .metric        a string with the name of the distance
%                     metric to be used by pdist (default: 'correlation')
%      .center_data   If true, then data is centered before the pair-wise
%                     distances are computed. The default is false; when
%                     used with the 'correlation' metric, it is recommended
%                     to use center_data, 'true'.
%
%   Returns
%
% Output:
%    ds_sa            Struct with fields:
%      .samples       Nx1 flattened lower triangle of a dissimilarity
%                     matrix as returned by [cosmo_]pdist, where
%                     N=P*(P-1)/2 is the number of pairwise distances
%                     between all samples in the dataset.
%      .a.sdim.labels Set to
%      .sa            Struct with field:
%        .targets1    } Nx1 vectors indicating the pairs of indices in the
%        .targets2    } lower part of the square form of the dissimilarity
%                       matrix. if .dsm_pairs(k,:)==[i,j] then .samples(k)
%                     the dissimlarity between the i-th and j-th sample
%                     target.
%
%
% Example:
%     % ds is a dataset struct with ds.sa.targets=(11:16)';
%     ds=struct();
%     ds.samples=[1 2 3; 1 2 3; 1 0 1; 1 1 2; 1 1 2];
%     ds.sa.targets=(11:15)';
%     %
%     % compute dissimilarity with centered data
%     dsm_ds=cosmo_dissimilarity_matrix_measure(ds,'center_data',true);
%     cosmo_disp(dsm_ds);
%     %|| .sa
%     %||   .targets1
%     %||     [ 2
%     %||       3
%     %||       4
%     %||       :
%     %||       4
%     %||       5
%     %||       5 ]@10x1
%     %||   .targets2
%     %||     [ 1
%     %||       1
%     %||       1
%     %||       :
%     %||       3
%     %||       3
%     %||       4 ]@10x1
%     %|| .a
%     %||   .sdim
%     %||     .labels
%     %||       { 'targets1'  'targets2' }
%     %||     .values
%     %||       { [ 11    [ 11
%     %||           12      12
%     %||           13      13
%     %||           14      14
%     %||           15 ]    15 ] }
%     %|| .samples
%     %||   [         0
%     %||             2
%     %||             2
%     %||         :
%     %||      1.11e-16
%     %||      1.11e-16
%     %||     -2.22e-16 ]@10x1
%     %
%     % map results to matrix. values of 0 mean perfect correlation
%     [samples, labels, values]=cosmo_unflatten(dsm_ds,1,...
%                                           'set_missing_to',NaN);
%     cosmo_disp(samples)
%     %|| [ NaN       NaN       NaN       NaN       NaN
%     %||     0       NaN       NaN       NaN       NaN
%     %||     2         2       NaN       NaN       NaN
%     %||     2         2  1.11e-16       NaN       NaN
%     %||     2         2  1.11e-16 -2.22e-16       NaN ]
%     %
%     cosmo_disp(labels)
%     %|| { 'targets1'  'targets2' }
%     %
%     cosmo_disp(values)
%     %|| { [ 11    [ 11
%     %||     12      12
%     %||     13      13
%     %||     14      14
%     %||     15 ]    15 ] }
%
%     % Searchlight using this measure
%     ds=cosmo_synthetic_dataset('ntargets',6,'nchunks',1);
%     % (in this toy example there are only 6 voxels, and the radius
%     %  of the searchlight is 1 voxel. Real-life examples use larger
%     %  datasets and a larger radius)
%     nbrhood=cosmo_spherical_neighborhood(ds,'radius',1,'progress',false);
%     opt=struct();
%     opt.progress=false;          % do not show progress
%     opt.metric='euclidean'; % (instead of default 'correlation')
%     measure=@cosmo_dissimilarity_matrix_measure;
%     sl_ds=cosmo_searchlight(ds, nbrhood, measure, opt);
%     cosmo_disp(sl_ds);
%     %|| .a
%     %||   .fdim
%     %||     .labels
%     %||       { 'i'  'j'  'k' }
%     %||     .values
%     %||       { [ 1         2         3 ]  [ 1         2 ]  [ 1 ] }
%     %||   .vol
%     %||     .mat
%     %||       [ 2         0         0        -3
%     %||         0         2         0        -3
%     %||         0         0         2        -3
%     %||         0         0         0         1 ]
%     %||     .dim
%     %||       [ 3         2         1 ]
%     %||     .xform
%     %||       'scanner_anat'
%     %||   .sdim
%     %||     .labels
%     %||       { 'targets1'  'targets2' }
%     %||     .values
%     %||       { [ 1    [ 1
%     %||           2      2
%     %||           3      3
%     %||           4      4
%     %||           5      5
%     %||           6 ]    6 ] }
%     %|| .fa
%     %||   .nvoxels
%     %||     [ 3         4         3         3         4         3 ]
%     %||   .radius
%     %||     [ 1         1         1         1         1         1 ]
%     %||   .center_ids
%     %||     [ 1         2         3         4         5         6 ]
%     %||   .i
%     %||     [ 1         2         3         1         2         3 ]
%     %||   .j
%     %||     [ 1         1         1         2         2         2 ]
%     %||   .k
%     %||     [ 1         1         1         1         1         1 ]
%     %|| .samples
%     %||   [  3.1      3.68      3.56      1.47      2.96      2.27
%     %||     6.06      6.39      3.29      6.54      4.43       4.1
%     %||     5.85       4.2      2.11      6.47      6.18      3.47
%     %||       :         :        :          :         :         :
%     %||     4.62      3.18     0.829      5.53      5.53      3.14
%     %||      3.7      3.08      1.75      4.71      4.95      3.39
%     %||     1.23      0.83      1.48      1.03      1.75      1.31 ]@15x6
%     %|| .sa
%     %||   .targets1
%     %||     [ 2
%     %||       3
%     %||       4
%     %||       :
%     %||       5
%     %||       6
%     %||       6 ]@15x1
%     %||   .targets2
%     %||     [ 1
%     %||       1
%     %||       1
%     %||       :
%     %||       4
%     %||       4
%     %||       5 ]@15x1
%     %||
%
%     % limitation: cannot have repeated targets
%     ds=cosmo_synthetic_dataset('nchunks',2,'ntargets',3);
%     cosmo_dissimilarity_matrix_measure(ds);
%     %|| error('...')
%
%     % averaging the samples for each unique target resolves the issue of
%     % repeated targets
%     ds=cosmo_synthetic_dataset('nchunks',2,'ntargets',3);
%     ds_avg=cosmo_fx(ds,@(x)mean(x,1),'targets');
%     ds_dsm=cosmo_dissimilarity_matrix_measure(ds_avg);
%     cosmo_disp(ds_dsm);
%     ||.sa
%||  .targets1
%||    [ 2
%||      3
%||      3 ]
%||  .targets2
%||    [ 1
%||      1
%||      2 ]
%||.a
%||  .sdim
%||    .labels
%||      { 'targets1'  'targets2' }
%||    .values
%||      { [ 1    [ 1
%||          2      2
%||          3 ]    3 ] }
%||.samples
%||  [  1.68
%||     1.71
%||    0.711 ]
%
% Notes:
%   - it is recommended to set the 'center_data' to true when using
%     the default 'correlation' metric, as this removes a main effect
%     common to all samples; but note that this option is disabled by
%     default due to historical reasons.
%  -  [cosmo_]pdist defaults to 'euclidean' distance, but correlation
%     distance is preferable for neural dissimilarity matrices, hence it
%     is used as the default here
%  -  Results from this function, when used with the default 'correlation'
%     metric, should *not* be Fisher transformed (using atanh) because
%     the output ranges from 0 to 2 (=one minus Pearson correlation)
%     and the Fisher transform of a value >1 is complex (non-real). This is
%     generally a Bad Thing.
%
% See also: cosmo_pdist, pdist
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #

    % check input
    check_input(ds);
    args=get_args(varargin);

    % make new dataset
    ds_dsm=struct();

    % if center_data, then subtract the mean first
    samples=ds.samples;
    if args.center_data
        samples=bsxfun(@minus,samples,mean(samples,1));
    end

    % compute pair-wise distances between all samples using cosmo_pdist,
    % then store them as samples in ds_dsm
    % >@@>
    dsm = cosmo_pdist(samples, args.metric)';

    % store dsm
    ds_dsm=get_sample_attributes(ds.sa.targets);
    ds_dsm.samples=dsm;
    % <@@<

function check_input(ds)
    if ~(isstruct(ds) && ...
                isfield(ds,'samples') && ...
                isfield(ds,'sa') && ...
                isfield(ds.sa,'targets'))
        error(['require dataset structure with fields '...
                    '.samples and .sa.targets']);
    end

function args=get_args(varargin)
    persistent cached_varargin;
    persistent cached_args;

    if ~isequal(varargin, cached_varargin)
        cached_args=cosmo_structjoin('metric','correlation',...
                            'center_data',false,...
                            varargin);
        cached_varargin=varargin;
    end

    args=cached_args;

function ds_skeleton=get_sample_attributes(targets)
    persistent cached_targets;
    persistent cached_ds_skeleton;

    if ~isequal(targets, cached_targets)
        ntargets=numel(targets);

        % unique targets
        classes=unique(targets);
        nclasses=numel(classes);

        % each should occur exactly once
        if nclasses~=ntargets
            error(['.sa.targets should be permutation of unique targets; '...
                    'to average samples with the same targets, consider '...
                    'ds_mean=cosmo_fx(ds,@(x)mean(x,1),''targets'')'],...
                        nclasses);
        end

        % store single sample attribute: the pairs of sample attribute indices
        % used to compute the dsm.
        [i,j]=find(triu(repmat(1:nclasses,nclasses,1),1)');
        cached_ds_skeleton.sa=struct();
        cached_ds_skeleton.sa.targets1=i;
        cached_ds_skeleton.sa.targets2=j;

        % set sample dimensions
        add_labels={'targets1','targets2'};
        add_values={targets, targets};

        cached_ds_skeleton.a.sdim=struct();
        cached_ds_skeleton.a.sdim.labels=add_labels;
        cached_ds_skeleton.a.sdim.values=add_values;

        cached_targets=targets;
    end

    ds_skeleton=cached_ds_skeleton;


function SRout = SR(VAR,SIGN,VARopt)
% =======================================================================
% Compute IRs, VDs, and HDs for a VAR model estimated with VARmodel and
% identified with sign restrictions
% =======================================================================
% SRout = SR(VAR,R,VARopt)
% -----------------------------------------------------------------------
% INPUT
%   - VAR: structure, result of VARmodel function
%   - SIGN: matrix containing the sign restrictions (nvar,nshocks). 1
%       stands for positive, -1 for negative, 0 for unrestricted. For
%       example the following identifies only one shock with positive
%       impact on the VAR1, and negative imnpact on VAR2 and VAR3
%
%             shock1      shock2     shock3
%  SIGN = [     1           0           0          % VAR1
%              -1           0           0          % VAR2
%              -1           0           0];        % VAR3
%
%   - VARopt: options of the VAR (see VARoption from VARmodel)
% -----------------------------------------------------------------------
% OUTPUT
%   - SRout
%       * IRall : 4-D matrix of IRs  (nsteps,nvar,nshocks,ndraws)
%       * IRmed : median of IRall
%       * IRinf : lower bound of IRall
%       * IRsup : upper bound of IRall
%       * IR    : IR based on true B matrix that is closest to median B
%       * (similar structure for VD, B, and HD)
% -----------------------------------------------------------------------
% EXAMPLE
%   - See VARToolbox_Code.m in "../Primer/"
% =======================================================================
% VAR Toolbox 3.0
% Ambrogio Cesa-Bianchi
% ambrogiocesabianchi@gmail.com
% March 2012. Updated November 2020
% -----------------------------------------------------------------------

%% Check inputs
%==========================================================================
if ~exist('SIGN','var')
    error('You have not provided sign restrictions (SIGN)')
end

if ~exist('VARopt','var')
    error('You need to provide VAR options (VARopt from VARmodel)');
end

%% Retrieve parameters and preallocate variables
%==========================================================================
nvar    = VAR.nvar;
nvar_ex = VAR.nvar_ex;
nsteps  = VARopt.nsteps;
ndraws  = VARopt.ndraws;
nobs    = VAR.nobs;
nlag    = VAR.nlag;
pctg    = VARopt.pctg;

% Initialize empty matrix for the IR draws
IRall  = nan(nsteps,nvar,nvar,ndraws);
VDall = nan(nsteps,nvar,nvar,ndraws);
HDall.shock  = zeros(nobs+nlag,nvar,nvar,ndraws);
HDall.init   = zeros(nobs+nlag,nvar,ndraws);
HDall.const  = zeros(nobs+nlag,nvar,ndraws);
HDall.trend  = zeros(nobs+nlag,nvar,ndraws);
HDall.trend2 = zeros(nobs+nlag,nvar,ndraws);
HDall.endo   = zeros(nobs+nlag,nvar,ndraws);
HDall.exo    = zeros(nobs+nlag,nvar,nvar_ex,ndraws);
Ball = nan(nvar,nvar,ndraws);

%% Sign restriction routine
%==========================================================================
jj = 0; % accepted draws
tt = 0; % total draws
ww = 1; % index for printing on screen
while jj < ndraws

    % Check total number of draws
    if tt>VARopt.sr_draw
        disp('------------------------------------------------------------')
        disp( 'Total number of draws for finding sign restrictions exceeed')
        disp( 'Change the restrictions or increase VARopt.sr_draw');
        disp('------------------------------------------------------------')
        error('See details above')
    end

    % Set up VAR_draw.(draw{j}) for rotations: Only identification uncertainty
    label  = {['draw' num2str(jj)]};
    VAR_draw.(label{1}) = VAR;
    VARopt.ident = 'sign';
    % If selected, set up VAR_draw.(draw{j}) to consider identification + model uncertainty
    if VARopt.sr_mod==1
        % Draw F and sigma from the posterior and
        [sigma_draw, Ft_draw, F_draw, Fcomp_draw] = VARdrawpost(VAR);
        VAR_draw.(label{1}).Ft = Ft_draw;
        VAR_draw.(label{1}).F = F_draw;
        VAR_draw.(label{1}).Fcomp = Fcomp_draw;
        VAR_draw.(label{1}).sigma = sigma_draw;
    end

    % Compute rotated B matrix
    B = SignRestrictions(SIGN,VAR_draw.(label{1}),VARopt);

    % Note: e = (inv(B)*VAR_draw.(draw{j}).resid')';
    % Check orthogonality:
    % round(corr((inv(B)*VAR_draw.(draw{j}).resid')'))

    if ~isempty(B)
        % Store B
        jj = jj+1; tt = tt+1;
        Ball(:,:,jj) = B;

        % Update VAR_draw.(draw{j}) with the rotated B matrix for IR, VD, and HD
        VAR_draw.(label{1}).B = B;

        % Compute and store IR, VD, HD
        [aux_irf, VAR_draw.(label{1})] = VARir(VAR_draw.(label{1}),VARopt);
        IRall(:,:,:,jj)  = aux_irf;
        aux_fevd = VARvd(VAR_draw.(label{1}),VARopt);
        VDall(:,:,:,jj)  = aux_fevd;
        aux_hd = VARhd(VAR_draw.(label{1}),VARopt);
        HDall.shock(:,:,:,jj) = aux_hd.shock;
        HDall.init(:,:,jj)    = aux_hd.init;
        HDall.const(:,:,jj)   = aux_hd.const;
        HDall.trend(:,:,jj)   = aux_hd.trend;
        HDall.trend2(:,:,jj)  = aux_hd.trend2;
        HDall.endo(:,:,jj)    = aux_hd.endo;
        if nvar_ex>0; HDall.exo(:,:,:,jj) = aux_hd.exo; end

        % Display number of loops
        if jj==VARopt.mult*ww
            disp(['Rotation: ' num2str(jj) ' / ' num2str(ndraws)]);
            ww=ww+1;
        end
    else
        tt=tt+1;
    end
end
disp('-- Done!');
disp(' ');

%% Store results
%==========================================================================
% Store all accepted IRs and VDs
SRout.IRall = IRall;
SRout.VDall = VDall;
SRout.Ball  = Ball;
SRout.HDall = HDall;

% Compute and save median B matrix
SRout.Bmed = median(Ball,3);

% Compute and save true B matrix that is closer to median
aux = sum(sum((Ball-SRout.Bmed).^2,1),2);
sel = find(aux==min(aux));
sel = sel(1);
SRout.B = Ball(:,:,sel);

% Compute IR and VD based on all rotations
pctg_inf = (100-pctg)/2;
pctg_sup = 100 - (100-pctg)/2;
SRout.IRmed = median(IRall,4);
aux = prctile(IRall,[pctg_inf pctg_sup],4);
SRout.IRinf = aux(:,:,:,1);
SRout.IRsup = aux(:,:,:,2);
SRout.VDmed = median(VDall,4);
aux = prctile(VDall,[pctg_inf pctg_sup],4);
SRout.VDinf = aux(:,:,:,1);
SRout.VDsup = aux(:,:,:,2);

% Compute IR, VD, and HD based on the VARdraw that is closest to the median
% B matrix
VARopt.ident = 'sign';
label = {['draw' num2str(sel)]};  % Recover the position in VARdraw
VAR = VAR_draw.(label{1});        % Set a VAR based on the selected VARdraw
SRout.IR = VARir(VAR,VARopt);     % Compute IR
SRout.VD = VARvd(VAR,VARopt);     % Compute VD
SRout.HD = VARhd(VAR,VARopt);     % Compute HD


% CVX: Matrix structure definitions and utilities.
%    CVX provides a keyword-based method for definiting matrices
%    with one or more types of structure; e.g.
%        variable X(n,n) symmetric toeplitz tridiagonal;
%    CVX automatically computes an efficient basis for the requested
%    structure. The files in this directory implement those computations.
%
%    None of these files should be called directly---matrix structure is
%    selected in the VARIABLE declaration; see VARIABLE for more details.
%    Below are the keywords that are available, and the structures they
%    represent. Keywords can be freely combined (see the above example),
%    but of course some combinations are degenerate, yielding only the
%    all-zero matrix; e.g.,
%       variable X(n,n)
%
% Structures:
%   banded            - (U,L)-banded matrices.
%   complex           - Complex variables of all sizes.
%   diagonal          - Diagonal matrices.
%   hankel            - Hankel matrices.
%   hermitian         - Complex Hermitian matrices.
%   lower_bidiagonal  - Lower bidiagonal matrices.
%   lower_hessenberg  - Lower Hessenberg matrices.
%   lower_triangular  - Lower triangular matrices.
%   scaled_identity   - Scaled identity: t*eye(n).
%   skew_symmetric    - Skew-symmetric matrices.
%   sparse            - Matrices with a fixed sparsity pattern.
%   symmetric         - Symmetric matrices.
%   toeplitz          - Toeplitz matrices.
%   tridiagonal       - Tridiagional matrices.
%   upper_bidiagonal  - Upper bidiagonal matrices.
%   upper_hankel      - Upper Hankel matrices.
%   upper_hessenberg  - Upper Hessenberg matrices.
%   upper_triangular  - Upper triangular matrices.

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


function export_generic(SO3F,filename,varargin)
% export an SO3F to an ASCII file
%
% Syntax
%   export(SO3F,'file.txt',S3G)
%   export(SO3F,'file.txt',regular,'resolution',2.5*degree)
%   export(SO3F,'file.txt',regular,'resolution',2.5*degree)
%
% Input
%  SO3F     - @SO3Fun to be exported
%  filename - name of the ascii file
%
% Options
%  weights   - export weights of the ODF components
%  ZYZ, ABG  - Matthies (alpha, beta, gamma) convention (default)
%  ZXZ,BUNGE - Bunge (phi1,Phi,phi2) convention
%
% See also
% ODFImport ODFExport

% open the file
if nargin == 1, filename = uigetfile;end
fid = fopen(filename,'w');

% write intro
fprintf(fid,'%% MTEX ODF\n');

% symmetries
CS = SO3F.CS; SS = SO3F.SS;
fprintf(fid,'%% crystal symmetry: %s\n',char(CS));
fprintf(fid,'%% specimen symmetry: %s\n',char(SS));

% get SO3Grid
if any(cellfun(@(x) isa(x,'SO3Grid'),varargin))
  S3G = getClass(varargin,'SO3Grid');
  S3G = orientation(S3G);
  d = Euler(S3G,varargin{:});
else
  [S3G,~,~,d] = regularSO3Grid(CS,SS,varargin{:});
end

% evaluate ODF
v = eval(SO3F,S3G,varargin{:});

% build up matrix to be exported
d = mod(d,2*pi);
if ~check_option(varargin,'radians'), d = d./degree;end

% convention
if check_option(varargin,{'Bunge','ZXZ'})
  convention = 'ZXZ';
elseif check_option(varargin,{'ABG','ZYZ'})
  convention = 'ZYZ';
else
  convention = 'ZXZ';
end

% save matrix
if strcmp(convention,'ZXZ')
  fprintf(fid,'%% phi1    Phi     phi2    value\n');
else
  fprintf(fid,'%% alpha   beta    gamma   value\n');
end

fprintf(fid,'%3.5f %3.5f %3.5f %3.5f\n',[d,v(:)].');

fclose(fid);


function [f] = spm_cost_SHC_fxa(x,v,a,P)
% equations of motion for a foraging problem
% FORMAT [f] = spm_cost_SHC_fxa(x,v,a,P)
%
% x   - hidden states
% v   - exogenous inputs
% a   - action
% P   - parameters for mountain car
%
% returns f = dx/dt (see spm_cost_SHC_fx)
% These equations of motion model dissipative flow x.x and x.v on a flat
% potential and increases in physiological states x.q as radial basis
% functions of secrete locations. The agent has to discover these
% locations % using an appropriate policy. This generative process would
% also substitute for Morris water-maze simulations or unbounded saccades.
%__________________________________________________________________________
% Copyright (C) 2010 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_cost_SHC_fxa.m 3757 2010-03-08 11:41:53Z guillaume $

% location and radius of attractors A (only A.q attractors deliver reward)
%--------------------------------------------------------------------------
global A; X   = A.x(:,A.q);

% physical flow
%--------------------------------------------------------------------------
f   = x;
f.x = x.v;
f.v = a - x.x*2 - x.v*4;

% physiological flow
%--------------------------------------------------------------------------
for i = 1:size(X,2)
    f.q(i) = (norm(x.x - X(:,i)) < A.d) - x.q(i)/2;
end

% flow
%--------------------------------------------------------------------------
dt  = 1/8;
f.x = f.x*dt;
f.v = f.v*dt;
f.q = f.q*dt;