function [vtx,elt,col,data] = mshReadMsh(filename)
%+========================================================================+
%|                                                                        |
%|                 OPENMSH - LIBRARY FOR MESH MANAGEMENT                  |
%|           openMsh is part of the GYPSILAB toolbox for Matlab           |
%|                                                                        |
%| COPYRIGHT : Matthieu Aussal (c) 2017-2018.                             |
%| PROPERTY  : Centre de Mathematiques Appliquees, Ecole polytechnique,   |
%| route de Saclay, 91128 Palaiseau, France. All rights reserved.         |
%| LICENCE   : This program is free software, distributed in the hope that|
%| it will be useful, but WITHOUT ANY WARRANTY. Natively, you can use,    |
%| redistribute and/or modify it under the terms of the GNU General Public|
%| License, as published by the Free Software Foundation (version 3 or    |
%| later,  http://www.gnu.org/licenses). For private use, dual licencing  |
%| is available, please contact us to activate a "pay for remove" option. |
%| CONTACT   : matthieu.aussal@polytechnique.edu                          |
%| WEBSITE   : www.cmap.polytechnique.fr/~aussal/gypsilab                 |
%|                                                                        |
%| Please acknowledge the gypsilab toolbox in programs or publications in |
%| which you use it.                                                      |
%|________________________________________________________________________|
%|   '&`   |                                                              |
%|    #    |   FILE       : mshReadMsh.m                                  |
%|    #    |   VERSION    : 0.42                                          |
%|   _#_   |   AUTHOR(S)  : Matthieu Aussal                               |
%|  ( # )  |   CREATION   : 14.03.2017                                    |
%|  / 0 \  |   LAST MODIF : 31.12.2018                                    |
%| ( === ) |   SYNOPSIS   : Read .msh files (particle, edge, triangular   |
%|  `---'  |                and tetrahedral                               |
%+========================================================================+

% Open
fid = fopen(filename,'r');
if (fid==-1)
    error('mshReadMsh.m : cant open the file');
end

% Read file using keywords
str = fgets(fid);
while ~(str==-1)
    if contains(str,'$Nodes')
        vtx = readNodes(fid);
    elseif contains(str,'$Elements')
        [elt,col] = readElements(fid);
    elseif contains(str,'$NodeData')
        data = readNodesData(fid,size(vtx,1));
    end
    str = fgets(fid);
end

% Close file
fclose(fid);

% Only keep higher elements (tetra > triangle > edge > particles)
ord = sum(elt>0,2);
dim = max(ord);
elt = elt(ord==dim,1:dim);
col = col(ord==dim);
end

function vtx = readNodes(fid)
% Nodes
Nvtx = str2double(fgets(fid));
vtx  = zeros(Nvtx,3);
for i = 1:Nvtx
    tmp      = str2num(fgets(fid));
    vtx(i,:) = tmp(2:4);
end

% Verify nodes ending
str = fgets(fid);
if ~contains(str,'$EndNodes')
    error('mshReadMsh.m : unavailable case');
end
end

function [elt,col] = readElements(fid)
% Initialize
Nelt = str2double(fgets(fid));
elt  = zeros(Nelt,4);
col  = zeros(Nelt,1);

% Elements (up to tetra)
for i = 1:Nelt
    tmp    = str2num(fgets(fid));
    col(i) = tmp(4);
    if (tmp(2) == 15)    % particles
        elt(i,1)   = tmp(6);
    elseif (tmp(2) == 1) % segment
        elt(i,1:2) = tmp(6:7);
    elseif (tmp(2) == 2) % triangles
        elt(i,1:3) = tmp(6:8);
    elseif (tmp(2) == 4) % tetrahedra
        elt(i,1:4) = tmp(6:9);
    end
end

% Verify elements ending
str = fgets(fid);
if ~contains(str,'$EndElements')
    error('mshReadMsh.m : unavailable case');
end
end

function data = readNodesData(fid,Nvtx)
% Go to Node Data
str = fgets(fid);
while ~contains(str,num2str(Nvtx))
    str = fgets(fid);
end

% Initialization with first row
tmp       = str2num(fgets(fid));
data      = zeros(Nvtx,length(tmp)-1);
data(1,:) = tmp(2:end);

% Nodes data
for i = 2:Nvtx
    tmp       = str2num(fgets(fid));
    data(i,:) = tmp(2:end);
end

% Verify node data ending
str = fgets(fid);
if ~contains(str,'$EndNodeData')
    error('mshReadMsh.m : unavailable case');
end
end


%   AUTHORSHIP
%   Primary Developer: Stephen Meehan <swmeehan@stanford.edu>
%   Math Lead & Secondary Developer:  Connor Meehan <connor.gw.meehan@gmail.com>
%   Bioinformatics Lead:  Wayne Moore <wmoore@stanford.edu>
%   Provided by the Herzenberg Lab at Stanford University
%   License: BSD 3 clause
%

classdef UmapExamples
    methods(Static)
        function DisplayPub(which)
            disp('PLEASE NOTE:The sample data for this example is made public with the publication');
            fprintf('%s\n\n', UmapExamples.SampleURL(which));
        end

        function url=SampleURL(which)
            switch which
                case 1
                    url='https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4896314/';
                case 2
                    url='https://www.frontiersin.org/articles/10.3389/fimmu.2019.01194/full';
                otherwise
                    url='https://www.pnas.org/content/107/6/2568';

            end
        end
        function sample=SolveClue(sampleClue)
            if isnumeric(sampleClue)
                switch sampleClue
                    case 27
                        UmapExamples.DisplayPub(2);
                        sample='genentech_d1_27D.csv';
                    case 29
                        UmapExamples.DisplayPub(1);
                        sample='s1s2_samusikImported_29D.csv';
                    case 11
                        UmapExamples.DisplayPub(3);

                        sample='balbc_Bcells_Macrophages.csv';
                    case 11.12
                        UmapExamples.DisplayPub(3);
                        sample='sampleBalbcLabeled12k.csv';

                    otherwise
                        error('Do not understand sample clue %d',...
                            sampleClue );
                end
            else
                sample=sampleClue;
            end
        end

        function SplitSlow(sampleClue)
           if nargin<1
               sampleClue=29;
           end
            UstTest.Split(...
                UmapExamples.SolveClue(sampleClue),...
                'ust_test_components', [3 2], ...
                'ust_test_basic_reduction', true, ...
                'cluster_detail', {'most high', 'low'}, ...
                'match_html', 1, 'ust_test_cases', [ 1 4]);
        end

        function SplitFast(sampleClue)
            if nargin<1
               sampleClue=29;
           end
            UstTest.Split(...
                UmapExamples.SolveClue(sampleClue),...
               'ust_test_cases', 1, 'ust_test_basic_reduction', true, ...
                'cluster_detail', {'most high', 'low'}, 'match_html', 1);
        end

        function SplitFastest(sampleClue)
            if nargin<1
                sampleClue=29;
            end
            UstTest.Split(...
                UmapExamples.SolveClue(sampleClue),...
                'cluster_detail', 'most high',...
                'ust_test_components', 3,...
                'ust_test_cases', 1, 'ust_test_basic_reduction', false, ...
                'match_html', 1, 'match_supervisors', 3 , ...
                'match_scenarios', 4);
        end

        %The sample data for this example is made public with the publication
        %https://www.frontiersin.org/articles/10.3389/fimmu.2019.01194/full
        function Genentech(clusterDetail, scenarios, matchTypes)
            if nargin<3
                matchTypes=1;
                if nargin<2
                    scenarios=[];
                    if nargin<1
                        clusterDetail={};
                    end
                end
            end
            if isempty(scenarios)
                scenarios=[1 4];
            end
            if isempty(clusterDetail)
                clusterDetail={'most high', 'low'};
            end
            if ischar(clusterDetail)
                clusterDetail={clusterDetail};
            end
            UmapExamples.DisplayPub(2);
            run_umap('genentech_d1_27D_70k.csv', ...
                'label_file', 'genentech_d1_27D.properties', ...
                'label_column', 'end', ...
                'template_file', 'genentech_d1_27D_3D.mat',...
                'see_training', true, ...
                'cluster_detail', clusterDetail, ...
                'color_file', 'colorsByName.properties',...
                'match_supervisors', matchTypes, ...
                'match_histogram_fig', false,...
                'match_html', -1, 'match_scenarios', scenarios);
        end

        function Samusik(clusterDetail, scenarios, matchTypes, ...
                sampleSetClue, sampleClue, templateClue, nn, D)
            if nargin<8
                D=3;
                if nargin<7
                    nn=15;
                    if nargin<6
                        templateClue=1;
                        if nargin<5
                            sampleClue=2;
                            if nargin<4
                                sampleSetClue=29;
                                if nargin<3
                                    matchTypes=3;
                                    if nargin<2
                                        scenarios=[];
                                        if nargin<1
                                            clusterDetail={};
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if isempty(scenarios)
                scenarios=[1 4];
            end
            if isempty(clusterDetail)
                clusterDetail='most high';
            end
            if ischar(clusterDetail)
                clusterDetail={clusterDetail};
            end
            [tmplt, ss]=UstTest.Supervise(sampleSetClue, templateClue, ...
                true, D, nn);
            smpl=['s' num2str(sampleClue) '_' ss ];
            rf=fullfile(UmapUtil.LocalSamplesFolder, 'ustTest.pair');
            mf=sprintf('%s_s%d_t%d__mt%s__ms%s_%dnn_%dD', ss, ...
                sampleClue, templateClue, String.Num2Str(matchTypes), ...
                String.Num2Str(scenarios),  nn, D);
            run_umap([smpl '.csv'], ...
                'label_file', [smpl '.properties'], ...
                'label_column', 'end', ...
                'template_file', tmplt ,...
                'see_training', true, ...
                'cluster_detail', clusterDetail, ...
                'color_file', 'colorsByName.properties',...
                'match_supervisors', matchTypes, ...
                'match_histogram_fig', false,...
                'match_html', 1, ...
                'result_folder', rf,...
                'match_file', mf, ...
                'match_scenarios', scenarios);
        end

        %The sample data for this example is made public with the publication
        %https://www.pnas.org/content/107/6/2568
        function Balbc12(clusterDetail, scenarios, matchTypes)
            if nargin<3
                matchTypes=1;
                if nargin<2
                    scenarios=[];
                    if nargin<1
                        clusterDetail={};
                    end
                end
            end
            if isempty(scenarios)
                scenarios=4;
            end
            if isempty(clusterDetail)
                clusterDetail={'most high'};
            end
            if ischar(clusterDetail)
                clusterDetail={clusterDetail};
            end
            rf=fullfile(UmapUtil.LocalSamplesFolder, 'ustTest.pair');
            [~,~,~,extras]=run_umap('sampleBalbcLabeled12k.csv', ...
                'label_file', 'balbcLabels.properties', ...
                'label_column', 'end', ...
                'template_file', 'ustBalbc3D.mat',...
                'see_training', true, ...
                'cluster_detail', clusterDetail, ...
                'color_file', 'colorsByName.properties',...
                'match_supervisors', matchTypes, ...
                'match_histogram_fig', false,...
                'result_folder', rf, ...
                'match_html', -1, ...
                'match_scenarios', scenarios);
            records=extras.getFalsePosNeg;
            if ~isempty(records)
                extras.getFalsePosNeg(true);
                extras.saveMatchFiles;
                FalsePositiveNegative.Plot([0 1], extras.falsePosNegFile);
            end
        end

        %The sample data for this example is made public with the publication
        %https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4896314/
        function PairSamusikManual(D, nn)
            if nargin<2
                D=3;
                if nargin<1
                    nn=15;
                end
            end
            UmapExamples.DisplayPub(1);
            UstTest.Pair(1, [2 10], 29.2, 'verbose', 'text', 'match_supervisors', 1:4, 'ust_test_basic_reduction', false, 'match_table_fig', true, 'match_scenarios', [1 2 3 4], 'ust_test_components', D, 'n_neighbors', nn);
        end

        %The sample data for this example is made public with the publication
        %https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4896314/
        function PairSamusikImport(nn, D, testSets, synthesize, templateClue)
            if nargin<5
                templateClue=1;
                if nargin<4
                    synthesize=0;
                    if nargin<3
                        testSets=[2 10];
                        if nargin<2
                            D=3;
                            if nargin<1
                                nn=30;
                            end
                        end
                    end
                end
            end
            UmapExamples.DisplayPub(1);
            UstTest.Pair(templateClue, testSets, 29, ...
                'ust_test_synthesize', synthesize, ...
                'verbose', 'text', ...
                'match_supervisors', 3, ...
                'ust_test_basic_reduction', false, ...
                'match_scenarios', 4, ...
                'ust_test_components', D, 'n_neighbors', nn);
        end

        %The sample data for this example is made public with the publication
        %https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4896314/
        function PairSamusikImport19(nn, D)
            if nargin<2
                D=3;
                if nargin<1
                    nn=15;
                end
            end
            UmapExamples.DisplayPub(1);
            UstTest.Pair(1, [2 10], 19, 'verbose', 'text', 'match_supervisors', 3, 'ust_test_basic_reduction', false, 'match_table_fig', true, 'match_scenarios', 4, 'ust_test_components', D, 'n_neighbors', nn);
        end

        %The sample data for this example is made public with the publication
        %https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4896314/
        function PairSamusikNn(nn)
            if nargin<1
                nn=20;
            end
            UmapExamples.DisplayPub(1);
            UstTest.Pair(1, 2, 29, 'verbose', 'graphic', 'match_supervisors', 1:4, 'ust_test_basic_reduction', true, 'match_table_fig', true, 'match_scenarios', 4, 'ust_test_components', 3, 'n_neighbors', nn);
        end

        %The sample data for this example is made public with the publication
        %https://www.pnas.org/content/107/6/2568
        function SplitBalbc55
            UmapExamples.DisplayPub(3);
            UstTest.Split('sampleBalbcLabeled55k.csv',...
                'ust_test_cases', 1, 'ust_test_basic_reduction', false, ...
                'cluster_detail', {'most high', 'low'}, 'match_html', 1, ...
                'match_scenarios', [ 1 3 4 ], 'match_supervisors', [1 3]);
        end

        %The sample data for this example is made public with the publication
        %https://www.pnas.org/content/107/6/2568
        function SplitBalbc55withBasic
            UmapExamples.DisplayPub(3);
            UstTest.Split('sampleBalbcLabeled55k.csv',...
                'ust_test_cases', 1, 'ust_test_basic_reduction', false, ...
                'cluster_detail', {'most high', 'low'}, 'match_html', 1, ...
                'match_scenarios', [ 1 3 4 ], 'ust_test_basic_reduction', ...
                true);
        end

        %The sample data for this example is made public with the publication
        %https://www.pnas.org/content/107/6/2568
        function Split5
            UmapExamples.DisplayPub(3);
            UstTest.Split('sampleBalbcLabeled55k.csv',...
                'ust_test_cases', 1, 'ust_test_basic_reduction', true, ...
                'cluster_detail', {'most high', 'low'}, 'match_html', 1, ...
                'match_scenarios', [ 1 2 3 4 ], 'ust_test_components', [3 2]);
        end

       %The sample data for this example is made public with the publication
        %https://www.pnas.org/content/107/6/2568
        function EliverSplitFast
            UmapExamples.DisplayPub(3);
            UstTest.Split('sampleBalbcLabeled12k.csv',...
                'ust_test_cases', 4, 'ust_test_basic_reduction', false, ...
                'cluster_detail', 'most high', 'match_html', 1, ...
                'match_supervisors', [3 4], ...
                'match_scenarios', 4, 'ust_test_basic_reduction', ...
                false, 'ust_test_components', 2);
        end

        function Split6
            UmapExamples.DisplayPub(3);
            UstTest.Split('sampleBalbcLabeled55k.csv',...
                'ust_test_cases', 1, 'ust_test_basic_reduction', false, ...
                'cluster_detail', {'most high', 'low'}, 'match_html', 1, ...
                'match_scenarios', [ 1 4 ], 'ust_test_basic_reduction', ...
                true, 'ust_test_components', [3 2],'ust_test_cases',...
                3);
        end
        function SplitGenenTech(synthesize, matchTypes)
            if nargin<2
                matchTypes=[3 4];
                if nargin<1
                    synthesize=0;
                end
            end
            UmapExamples.DisplayPub(2);
            UstTest.Split('genentech_d1_27D.csv', ...
                'ust_test_synthesize', synthesize, ...
                'ust_test_components', 2, ...
                'ust_test_basic_reduction', false, ...
                'cluster_detail', 'most high', ...
                'match_html', 1, ...
                'n_neighbors', 30, ...
                'match_supervisors', matchTypes, ...
                'match_scenarios', 4, ...
                'ust_test_cases', [ 1 2 4]);
        end

        function RunTest1
            UstTest.RunBig(10);
        end

    end
end


classdef DescriptorMatcher < handle
    %DESCRIPTORMATCHER  Common interface for matching keypoint descriptors
    %
    % Class for matching keypoint descriptors.
    %
    % Matchers of keypoint descriptors in OpenCV have wrappers with a common
    % interface that enables you to easily switch between different algorithms
    % solving the same problem. This section is devoted to matching
    % descriptors that are represented as vectors in a multidimensional space.
    % All objects that implement vector descriptor matchers inherit the
    % DescriptorMatcher interface.
    %
    % It has two groups of match methods: for matching descriptors of an image
    % with another image or with an image set.
    %
    % ## Example
    %
    %     X = rand(100,10);
    %     Y = rand(100,10);
    %     matcher = cv.DescriptorMatcher('BruteForce');
    %     matcher.add(X);
    %     matcher.train();  % Optional for BruteForce matcher
    %     matches = matcher.match(Y);
    %
    % See also: cv.DescriptorExtractor, cv.FeatureDetector, cv.drawMatches,
    %  matchFeatures
    %

    properties (SetAccess = private)
        % Object ID
        id
        % Type of the matcher
        Type
    end

    methods
        function this = DescriptorMatcher(matcherType, varargin)
            %DESCRIPTORMATCHER  Creates a descriptor matcher by name
            %
            %     matcher = cv.DescriptorMatcher(type)
            %     matcher = cv.DescriptorMatcher(type, 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __type__ In the first variant, it creates a descriptor matcher
            %   of a given type with the default parameters (using default
            %   constructor). The following types are recognized:
            %
            %   * __BruteForce__ (default) L2 distance
            %   * __BruteForce-SL2__ L2SQR distance
            %   * __BruteForce-L1__ L1 distance
            %   * __BruteForce-Hamming__, __BruteForce-HammingLUT__
            %   * __BruteForce-Hamming(2)__
            %   * __FlannBased__ Flann-based indexing
            %
            %   In the second variant, it creates a matcher of the given type
            %   using the specified parameters. The following descriptor
            %   matcher types are supported:
            %
            %   * __BFMatcher__ Brute-force descriptor matcher. For each
            %     descriptor in the first set, this matcher finds the closest
            %     descriptor in the second set by trying each one. This
            %     descriptor matcher supports masking permissible matches of
            %     descriptor sets.
            %   * __FlannBasedMatcher__ Flann-based descriptor matcher. This
            %     matcher trains `flann::Index_` on a train descriptor
            %     collection and calls its nearest search methods to find the
            %     best matches. So, this matcher may be faster when matching a
            %     large train collection than the brute force matcher.
            %     `FlannBasedMatcher` does not support masking permissible
            %     matches of descriptor sets because `flann::Index` does not
            %     support this.
            %
            % ## Options
            % The Brute-force matcher constructor (`BFMatcher`) accepts the
            % following options:
            %
            % * __NormType__ See cv.DescriptorExtractor.defaultNorm, default
            %   'L2'. One of:
            %   * __L1__, __L2__ L1 and L2 norms are preferable choices for
            %     cv.SIFT and cv.SURF descriptors.
            %   * __Hamming__ should be used with cv.ORB, cv.BRISK and
            %     cv.BriefDescriptorExtractor.
            %   * __Hamming2__ should be used with cv.ORB when `WTA_K` equals
            %     3 or 4 (see cv.ORB.WTA_K description).
            % * __CrossCheck__ If it is false, this is will be default
            %   `BFMatcher` behaviour when it finds the `k` nearest neighbors
            %   for each query descriptor. If `CrossCheck==true`, then the
            %   cv.DescriptorMatcher.knnMatch method with `k=1` will only
            %   return pairs `(i,j)` such that for i-th query descriptor the
            %   j-th descriptor in the matcher's collection is the nearest and
            %   vice versa, i.e. the `BFMatcher` will only return consistent
            %   pairs. Such technique usually  produces best results with
            %   minimal number of outliers when there are enough matches. This
            %   is alternative to the ratio test, used by *D. Lowe* in SIFT
            %   paper. default false
            %
            % The Flann-based matcher constructor (`FlannBasedMatcher`) takes
            % the following optional arguments:
            %
            % * __Index__ Type of indexer, default 'KDTree'. One of the below.
            %   Each index type takes optional arguments (see IndexParams
            %   options below). You can specify the indexer by a cell array
            %   that starts from the type name followed by option arguments:
            %   `{'Type', 'OptionName',optionValue, ...}`.
            %   * __Linear__ Brute-force matching, linear search
            %   * __KDTree__ Randomized kd-trees, parallel search
            %   * __KMeans__ Hierarchical k-means tree
            %   * __HierarchicalClustering__ Hierarchical index
            %   * __Composite__ Combination of KDTree and KMeans
            %   * __LSH__ Multi-probe LSH
            %   * __Autotuned__ Automatic tuning to one of the above
            %     (`Linear`, `KDTree`, `KMeans`)
            %   * __Saved__ Load saved index from a file
            %
            % * __Search__ Option in matching operation. Takes a cell array of
            %   option pairs:
            %   * __Checks__ The number of times the tree(s) in the index
            %     should be recursively traversed. A higher value for this
            %     parameter would give better search precision, but also take
            %     more time. If automatic configuration was used when the
            %     index was created, the number of checks required to achieve
            %     the specified precision was also computed, in which case
            %     this parameter is ignored. -1 for unlimited. default 32
            %   * __EPS__ search for eps-approximate neighbours. default 0
            %   * __Sorted__ only for radius search, require neighbours sorted
            %     by distance. default true
            %
            % ## IndexParams Options for `FlannBasedMatcher`
            %
            % The following are the options for FLANN indexers
            % (Fast Library for Approximate Nearest Neighbors):
            %
            % ### `Linear`
            % Linear index takes no options.
            %
            % ### `Saved`
            % Saved index takes only one argument specifying the filename.
            %
            % ### `KDTree` and `Composite`
            % * __Trees__ The number of parallel kd-trees to use. Good values
            %   are in the range [1..16]. default 4
            %
            % ### `KMeans` and `Composite`
            % * __Branching__ The branching factor to use for the hierarchical
            %   k-means tree. default 32
            % * __Iterations__ The maximum number of iterations to use in the
            %   k-means clustering stage when building the k-means tree. A
            %   value of -1 used here means that the k-means clustering should
            %   be iterated until convergence. default 11
            % * __CentersInit__ The algorithm to use for selecting the initial
            %   centers when performing a k-means clustering step. The
            %   possible values are (default is 'Random'):
            %   * __Random__ picks the initial cluster centers randomly
            %   * __Gonzales__ picks the initial centers using Gonzales
            %     algorithm
            %   * __KMeansPP__ picks the initial centers using the algorithm
            %     suggested in [ArthurKmeansPP2007]
            %   * __Groupwise__ chooses the initial centers in a way inspired
            %     by Gonzales (by Pierre-Emmanuel Viel).
            % * __CBIndex__ This parameter (cluster boundary index) influences
            %   the way exploration is performed in the hierarchical kmeans
            %   tree. When `CBIndex` is zero the next kmeans domain to be
            %   explored is chosen to be the one with the closest center. A
            %   value greater then zero also takes into account the size of
            %   the domain. default 0.2
            %
            % ### `HierarchicalClustering`
            % * __Branching__ same as above.
            % * __CentersInit__ same as above.
            % * __Trees__ same as above.
            % * __LeafSize__ maximum leaf size. default 100
            %
            % ### `LSH`
            % * __TableNumber__ The number of hash tables to use (usually
            %   between 10 and 30). default 20
            % * __KeySize__ The length of the key in the hash tables (usually
            %   between 10 and 20). default 15
            % * __MultiProbeLevel__ Number of levels to use in multi-probe
            %   (0 is regular LSH, 2 is recommended). default 0
            %
            % ### `Autotuned`
            % * __TargetPrecision__ Is a number between 0 and 1 specifying the
            %   percentage of the approximate nearest-neighbor searches that
            %   return the exact nearest-neighbor. Using a higher value for
            %   this parameter gives more accurate results, but the search
            %   takes longer. The optimum value usually depends on the
            %   application. default 0.8
            % * __BuildWeight__ Specifies the importance of the index build
            %   time raported to the nearest-neighbor search time. In some
            %   applications it is acceptable for the index build step to take
            %   a long time if the subsequent searches in the index can be
            %   performed very fast. In other applications it is required that
            %   the index be build as fast as possible even if that leads to
            %   slightly longer search times. default 0.01
            % * __MemoryWeight__ Is used to specify the tradeoff between time
            %   (index build time and search time) and memory used by the
            %   index. A value less than 1 gives more importance to the time
            %   spent and a value greater than 1 gives more importance to the
            %   memory usage. default 0
            % * __SampleFraction__ Is a number between 0 and 1 indicating what
            %   fraction of the dataset to use in the automatic parameter
            %   configuration algorithm. Running the algorithm on the full
            %   dataset gives the most accurate results, but for very large
            %   datasets can take longer than desired. In such case using just
            %   a fraction of the data helps speeding up this algorithm while
            %   still giving good approximations of the optimum parameters.
            %   default 0.1
            %
            % ## Example
            % For example, `KDTree` with tree size = 4 is specified by:
            %
            %     matcher = cv.DescriptorMatcher('FlannBasedMatcher', ...
            %         'Index',  {'KDTree', 'Trees', 4}, ...
            %         'Search', {'Sorted', true})
            %
            % Here is an example for loading a saved index:
            %
            %     matcher = cv.DescriptorMatcher('FlannBasedMatcher', ...
            %         'Index', {'Saved', '/path/to/saved/index.xml'})
            %
            % ## References
            % [ArthurKmeansPP2007]:
            % > Arthur and S. Vassilvitskii
            % > *"k-means++: the advantages of careful seeding"*,
            % > Proceedings of the eighteenth annual ACM-SIAM symposium
            % > on Discrete algorithms, 2007
            %
            % [LSH]:
            % > *Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search*
            % > by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li.,
            % > Proceedings of the 33rd International Conference on
            % > Very Large Data Bases (VLDB). Vienna, Austria. September 2007
            %
            % See also: cv.DescriptorMatcher
            %
            if nargin < 1, matcherType = 'BruteForce'; end
            this.Type = matcherType;
            this.id = DescriptorMatcher_(0, 'new', matcherType, varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     matcher.delete()
            %
            % See also: cv.DescriptorMatcher
            %
            if isempty(this.id), return; end
            DescriptorMatcher_(this.id, 'delete');
        end

        function typename = typeid(this)
            %TYPEID  Name of the C++ type (RTTI)
            %
            %     typename = matcher.typeid()
            %
            % ## Output
            % * __typename__ Name of C++ type
            %
            typename = DescriptorMatcher_(this.id, 'typeid');
        end
    end

    %% Algorithm
    methods
        function clear(this)
            %CLEAR  Clears the train descriptor collection
            %
            %     matcher.clear()
            %
            % See also: cv.DescriptorMatcher.empty
            %
            DescriptorMatcher_(this.id, 'clear');
        end

        function status = empty(this)
            %EMPTY  Returns true if there are no train descriptors in the collection
            %
            %     status = matcher.empty()
            %
            % ## Output
            % * __status__ boolean status
            %
            % See also: cv.DescriptorMatcher.clear
            %
            status = DescriptorMatcher_(this.id, 'empty');
        end

        function save(this, filename)
            %SAVE  Saves the algorithm parameters to a file
            %
            %     matcher.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in the specified
            % XML or YAML file.
            %
            % See also: cv.DescriptorMatcher.load
            %
            DescriptorMatcher_(this.id, 'save', filename);
        end

        function load(this, fname_or_str, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     matcher.load(fname)
            %     matcher.load(str, 'FromString',true)
            %     matcher.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from the specified XML or
            % YAML file (either from disk or serialized string). The previous
            % algorithm state is discarded.
            %
            % See also: cv.DescriptorMatcher.save
            %
            DescriptorMatcher_(this.id, 'load', fname_or_str, varargin{:});
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = matcher.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.DescriptorMatcher.save, cv.DescriptorMatcher.load
            %
            name = DescriptorMatcher_(this.id, 'getDefaultName');
        end
    end

    %% DescriptorMatcher
    methods
        function status = isMaskSupported(this)
            %ISMASKSUPPORTED  Returns true if the descriptor matcher supports masking permissible matches
            %
            %     status = matcher.isMaskSupported()
            %
            % ## Output
            % * __status__ boolean status.
            %
            % Brute-force matchers support masking, while Flann-based matchers
            % do no support masking.
            %
            % See also: cv.DescriptorMatcher.match
            %
            status = DescriptorMatcher_(this.id, 'isMaskSupported');
        end

        function descriptors = getTrainDescriptors(this)
            %GETTRAINDESCRIPTORS  Returns the train descriptor collection
            %
            %     descriptors = matcher.getTrainDescriptors()
            %
            % ## Output
            % * __descriptors__ Set of train descriptors. A cell array of
            %   matrices.
            %
            % See also: cv.DescriptorMatcher.add
            %
            descriptors = DescriptorMatcher_(this.id, 'getTrainDescriptors');
        end

        function add(this, descriptors)
            %ADD  Adds descriptors to train a descriptor collection
            %
            %     matcher.add(descriptors)
            %
            % If the collection is not empty, the new descriptors are added
            % to existing train descriptors.
            %
            % ## Input
            % * __descriptors__ Descriptors to add. Each `descriptors{i}` is a
            %   set of descriptors from the same train image. Can be either a
            %   matrix or a cell array of matrices (matrices of type `uint8`
            %   or `single`)
            %
            % See also: cv.DescriptorMatcher.getTrainDescriptors
            %
            DescriptorMatcher_(this.id, 'add', descriptors);
        end

        function train(this)
            %TRAIN  Trains a descriptor matcher
            %
            %     matcher.train()
            %
            % Trains a descriptor matcher (for example, the flann index). In all
            % methods to match, the method `train` is run every time before
            % matching. Some descriptor matchers (for example,
            % `BruteForceMatcher`) have an empty implementation of this method.
            % Other matchers really train their inner structures (for example,
            % `FlannBasedMatcher` trains `flann::Index`).
            %
            DescriptorMatcher_(this.id, 'train');
        end

        function matches = match(this, queryDescriptors, varargin)
            %MATCH  Finds the best match for each descriptor from a query set
            %
            %     matches = matcher.match(queryDescriptors, trainDescriptors)
            %     matches = matcher.match(queryDescriptors)
            %     [...] = matcher.match(..., 'OptionName', optionValue, ...)
            %
            % ## Input
            % * __queryDescriptors__ Query set of descriptors.
            % * __trainDescriptors__ Train set of descriptors. This set is not
            %   added to the train descriptors collection stored in the class
            %   object.
            %
            % ## Output
            % * __matches__ Matches. If a query descriptor is masked out in
            %   `Mask`, no match is added for this descriptor. So,
            %   `matches` size may be smaller than the query descriptors
            %   count. A 1-by-N structure array with the following fields:
            %   * __queryIdx__ query descriptor index (zero-based index)
            %   * __trainIdx__ train descriptor index (zero-based index)
            %   * __imgIdx__ train image index (zero-based index)
            %   * __distance__ distance between descriptors (scalar)
            %
            % ## Options
            % * __Mask__ default empty
            %   * In the first form, mask specifying permissible matches
            %   between an input query and train matrices of descriptors.
            %   Matrix of size
            %   `[size(queryDescriptors,1),size(trainDescriptors,1)]`.
            %   * In the second form, set of masks. Each `masks{i}` specifies
            %   permissible matches between the input query descriptors and
            %   stored train descriptors from the i-th image
            %   `trainDescCollection{i}`. Cell array of length
            %   `length(trainDescriptors)`, each a matrix of size
            %   `[size(queryDescriptors,1),size(trainDescriptors{i},1)]`.
            %
            % In the first variant of this method, the train descriptors are
            % passed as an input argument. In the second variant of the
            % method, train descriptors collection that was set by
            % cv.DescriptorMatcher.add is used. Optional mask (or masks) can
            % be passed to specify which query and training descriptors can be
            % matched. Namely, `queryDescriptors(i,:)` can be matched with
            % `trainDescriptors(j,:)` only if `mask(i,j)` is non-zero.
            %
            % See also: cv.DescriptorMatcher.knnMatch,
            %  cv.DescriptorMatcher.radiusMatch
            %
            matches = DescriptorMatcher_(this.id, 'match', queryDescriptors, varargin{:});
        end

        function matches = knnMatch(this, queryDescriptors, varargin)
            %KNNMATCH  Finds the k best matches for each descriptor from a query set
            %
            %     matches = matcher.knnMatch(queryDescriptors, trainDescriptors, k)
            %     matches = matcher.knnMatch(queryDescriptors, k)
            %     [...] = matcher.knnMatch(..., 'OptionName', optionValue, ...)
            %
            % ## Input
            % * __queryDescriptors__ Query set of descriptors.
            % * __trainDescriptors__ Train set of descriptors. This set is not
            %   added to the train descriptors collection stored in the class
            %   object.
            % * __k__ Count of best matches found per each query descriptor or
            %   less if a query descriptor has less than `k` possible matches
            %   in total.
            %
            % ## Output
            % * __matches__ Matches. Each `matches{i}` is `k` or less matches
            %   for the same query descriptor. A cell array of length
            %   `size(queryDescriptors,1)`, each cell is a 1-by-(k or less)
            %   structure array that has the following fields:
            %   * __queryIdx__ query descriptor index (zero-based index)
            %   * __trainIdx__ train descriptor index (zero-based index)
            %   * __imgIdx__ train image index (zero-based index)
            %   * __distance__ distance between descriptors (scalar)
            %
            % ## Options
            % * __Mask__ default empty
            %   * In the first form, mask specifying permissible matches
            %   between an input query and train matrices of descriptors.
            %   Matrix of size
            %   `[size(queryDescriptors,1),size(trainDescriptors,1)]`.
            %   * In the second form, set of masks. Each `masks{i}` specifies
            %   permissible matches between the input query descriptors and
            %   stored train descriptors from the i-th image
            %   `trainDescCollection{i}`. Cell array of length
            %   `length(trainDescriptors)`, each a matrix of size
            %   `[size(queryDescriptors,1),size(trainDescriptors{i},1)]`.
            % * __CompactResult__ Parameter used when the mask (or masks) is
            %   not empty. If `CompactResult` is false, the `matches` vector
            %   has the same size as `queryDescriptors` rows. If
            %   `CompactResult` is true, the matches vector does not contain
            %   matches for fully masked-out query descriptors. default false
            %
            % This extended variant of cv.DescriptorMatcher.match method finds
            % several best matches for each query descriptor. The matches are
            % returned in the distance increasing order. See
            % cv.DescriptorMatcher.match for the details about query and train
            % descriptors.
            %
            % See also: cv.DescriptorMatcher.match,
            %  cv.DescriptorMatcher.radiusMatch, cv.batchDistance
            %
            matches = DescriptorMatcher_(this.id, 'knnMatch', ...
                queryDescriptors, varargin{:});
        end

        function matches = radiusMatch(this, queryDescriptors, varargin)
            %RADIUSMATCH  For each query descriptor, finds the training descriptors not farther than the specified distance
            %
            %     matches = matcher.radiusMatch(queryDescriptors, trainDescriptors, maxDistance)
            %     matches = matcher.radiusMatch(queryDescriptors, maxDistance)
            %     [...] = matcher.radiusMatch(..., 'OptionName', optionValue, ...)
            %
            % ## Input
            % * __queryDescriptors__ Query set of descriptors.
            % * __trainDescriptors__ Train set of descriptors. This set is not
            %   added to the train descriptors collection stored in the class
            %   object.
            % * __maxDistance__ Threshold for the distance between matched
            %   descriptors. Distance here means metric distance (e.g. Hamming
            %   distance), not the distance between coordinates (which is
            %   measured in Pixels)!
            %
            % ## Output
            % * __matches__ Found matches. A cell array of length
            %   `size(queryDescriptors,1)`, each cell is a structure array
            %   that has the following fields:
            %   * __queryIdx__ query descriptor index (zero-based index)
            %   * __trainIdx__ train descriptor index (zero-based index)
            %   * __imgIdx__ train image index (zero-based index)
            %   * __distance__ distance between descriptors (scalar)
            %
            % ## Options
            % * __Mask__ default empty
            %   * In the first form, mask specifying permissible matches
            %   between an input query and train matrices of descriptors.
            %   Matrix of size
            %   `[size(queryDescriptors,1),size(trainDescriptors,1)]`.
            %   * In the second form, set of masks. Each `masks{i}` specifies
            %   permissible matches between the input query descriptors and
            %   stored train descriptors from the i-th image
            %   `trainDescCollection{i}`. Cell array of length
            %   `length(trainDescriptors)`, each a matrix of size
            %   `[size(queryDescriptors,1),size(trainDescriptors{i},1)]`.
            % * __CompactResult__ Parameter used when the mask (or masks) is
            %   not empty. If `CompactResult` is false, the `matches` vector
            %   has the same size as `queryDescriptors` rows. If
            %   `CompactResult` is true, the matches vector does not contain
            %   matches for fully masked-out query descriptors. default false
            %
            % For each query descriptor, the methods find such training
            % descriptors that the distance between the query descriptor and
            % the training descriptor is equal or smaller than `maxDistance`.
            % Found matches are returned in the distance increasing order.
            %
            % See also: cv.DescriptorMatcher.match,
            %  cv.DescriptorMatcher.knnMatch, cv.batchDistance
            %
            matches = DescriptorMatcher_(this.id, 'radiusMatch',...
                queryDescriptors, varargin{:});
        end
    end

end


function r = subSet(r,ind)
% indexing of rotation
%
% Syntax
%   subSet(q,ind) %
%

r = subSet@quaternion(r,ind);
r.i = r.i(ind);


function res = saveResTxt(bboxes_tracked)

frame_num = size(bboxes_tracked, 2);
track_bbox = zeros(1, 6);
res = [];
for frame = 1:frame_num
    bboxes = bboxes_tracked(1,frame).bbox;
    id_num = size(bboxes, 1);
    for id = 1:id_num
        track_bbox(1) = frame;
        track_bbox(2) = bboxes(id, 5);
        track_bbox(3) = bboxes(id, 1);
        track_bbox(4) = bboxes(id, 2);
        track_bbox(5) = bboxes(id, 3) - bboxes(id, 1);
        track_bbox(6) = bboxes(id, 4) - bboxes(id, 2);
        res = cat(1, res, [track_bbox, 1, -1, -1, -1]);
    end
end

if(~isempty(res))
    res = sortrows(res,1);
end


function GRIDobj2geotiff(A,file)

%GRIDobj2geotiff Exports an instance of GRIDobj to a geotiff file
%
% Syntax
%
%     GRIDobj2geotiff(DEM)
%     GRIDobj2geotiff(DEM,filename)
%
% Description
%
%     GeoTIFF is a common image file format that stores coordinates and
%     projection information to be read by most GIS software.
%     GRIDobj2geotiff writes an instance of GRIDobj to a GeoTIFF file.
%
%     GRIDobj2geotiff requires the function geotiffwrite available with
%     the Mapping Toolbox. If geotiffwrite does not exist on the search
%     path, the function will write a standard tif together with a
%     '.tfw'-file (worldfile, http://en.wikipedia.org/wiki/World_file ) to
%     the disk.
%
%     GRIDobj2geotiff(DEM) opens a dialogue box to save the GeoTIFF
%
%     GRIDobj2geotiff(DEM,filename) saves the DEM to the specified
%     filename
%
% Input arguments
%
%     DEM        instance of GRIDobj
%     filename   absolute or relative path and filename
%
% See also: GRIDobj
%
% Author: Wolfgang Schwanghart (w.schwanghart[at]geo.uni-potsdam.de)
% Date: 17. August, 2017

narginchk(1,2)

% if only 1 argument, open file dialog box
if nargin == 1
    [FileName,PathName] = uiputfile({'*.tif'});
    if FileName == 0
        disp('     no output written to disk')
        return
    end
    file = [PathName FileName];
end

% try to use geotiffwrite, which comes with the Mapping Toolbox
try
    if isempty(A.georef);
        geotiffwrite(file,A.Z,A.refmat);
    else
        geotiffwrite(file,A.Z,A.georef.SpatialRef,...
            'GeoKeyDirectoryTag',A.georef.GeoKeyDirectoryTag);
    end
catch ME
    warning('TopoToolbox:GRIDobj',...
        ['GRIDobj2geotiff is unable to write a geotiff. Either you don''t \n'...
         'have the mapping toolbox, or there was another issue with geotiffwrite. \n'...
         'GRIDobj2geotiff instead writes a tif-image together with a world \n'...
         'file (*.tfw) which contains data on spatial referencing of the \n' ...
         'image, yet which lacks information on the type of projection used.']);

    % if geotiffwrite is not available or any other error occurs
    % a tif file will be written to the disk together with a worldfile
    % .tfw-file.
    [pathstr, name, ~] = fileparts(file);
    k = refmat2worldfile(A.refmat);
    dlmwrite(fullfile(pathstr,[name '.tfw']),k,'precision', '%.10f');
    A = A.Z;

    siz = size(A);
    cla = class(A);

    switch cla;
        case 'double'
            BpS = 64;
            TSF = Tiff.SampleFormat.IEEEFP;
        case 'single'
            BpS = 32;
            TSF = Tiff.SampleFormat.IEEEFP;
        otherwise
            if islogical(A);
                A = uint32(A);
                cla = 'uint32';
            end
            BpS = round(log2(double(intmax(cla))));
            TSF = Tiff.SampleFormat.UInt;

    end

    t = Tiff(file,'w');
    tagstruct.ImageLength = siz(1);
    tagstruct.ImageWidth = siz(2);
    tagstruct.BitsPerSample = BpS;
    tagstruct.SampleFormat = TSF;
    tagstruct.SamplesPerPixel = 1;
    tagstruct.RowsPerStrip = 16;
    tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
    tagstruct.Software = 'MATLAB';
    tagstruct.Photometric = 0;

    t.setTag(tagstruct);
    t.write(A);
    t.close;
end

end

function k = refmat2worldfile(r)
% does not support rotation

k(1,1) = r(2,1);
k(4,1) = r(1,2);
k(5,1) = r(3,1)+k(1);
k(6,1) = r(3,2)+k(4);
end


function this = coregister(this)
% Affine coregistraton of given images to a stationary image (geometry only)
%
%   Y = MrSeries()
%   Y.coregister(inputs)
%
% This is a method of class MrSeries.
%
% IN
%       parameters.coregister ->
%           .nameStationaryImage            (e.g. 'mean')
%           .nameTransformedImage           (e.g. 'anatomy')
%           .nameEquallyTransformedImages   (e.g.'tissueProbabilityMap*')
% OUT
%
% EXAMPLE
%   coregister
%
%   See also MrSeries

% Author:   Saskia Klein & Lars Kasper
% Created:  2014-07-28
% Copyright (C) 2014 Institute for Biomedical Engineering
%                    University of Zurich and ETH Zurich
%
% This file is part of the TAPAS UniQC Toolbox, which is released
% under the terms of the GNU General Public Licence (GPL), version 3.
% You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version).
% For further details, see the file COPYING or
%  <http://www.gnu.org/licenses/>.

nameStationaryImage = this.parameters.coregister.nameStationaryImage;
nameTransformedImage = this.parameters.coregister.nameTransformedImage;
nameEquallyTransformedImages = ...
    this.parameters.coregister.nameEquallyTransformedImages;

stationaryImage = this.find('MrImage', 'name', ['^' nameStationaryImage '*']);
stationaryImage = stationaryImage{1};
transformedImage = this.find('MrImage', 'name', ['^' nameTransformedImage '*']);
transformedImage = transformedImage{1};
equallyTransformedImages = this.find('MrImage', 'name',...
    ['^' nameEquallyTransformedImages '*']);

% TODO: if transformed image has more than one volume, make sure to apply
% to all volumes!

% set paths of all images correctly
this.init_processing_step('coregister', transformedImage, ...
    equallyTransformedImages);

[~, affineCoregistrationGeometry] = transformedImage.coregister_to(...
    stationaryImage, 'applyTransformation', 'geometry');
this.parameters.coregister.affineCoregistrationGeometry = ...
    affineCoregistrationGeometry;

% now apply geometry Update to all other listed images that shall be
% transformed
% inverse transformation used, since coregister_to gives mapping from
% stationary to transformed image
nImages = numel(equallyTransformedImages);
for iImage = 1:nImages
    equallyTransformedImages{iImage}.affineTransformation.apply_inverse_transformation(...
        affineCoregistrationGeometry);
    equallyTransformedImages{iImage}.save;
end

this.finish_processing_step('coregister', transformedImage, ...
    equallyTransformedImages);


function x = parametric(x)
%PARAMETRIC Defines a variable as parametric
%
%   F = PARAMETRIC(x) is used to describe the set of parametric variables
%   in a multi-parametric program, as an alternative to using the 4th input
%   in SOLVEMP
%
%   It can also be used to define the parametric variables in a SOS program
%
%   INPUT
%    x : SDPVAR object
%
%   OUTPUT
%    F : Constraint
%
%   EXAMPLE
%    F = parametric(x);               % Short notation
%
%   See also SOLVEMP, SOLVESOS, SDPVAR

x.typeflag = 13;
x = lmi(x);


function view = cmapRedgreenblue(view, displayMode, hemi);
%
% view = cmapRedgreenblue(view, [displayMode='ph'], [hemi=1]);
%
% Set the color map for a view's display mode (default phase mode) to
% be a 'redgreenblue' cmap, a custom map Rory has found is useful in
% lookint at retinotopy data.
%
% The 'hemi' flag can be set to 0, 1 or 2: if 1, will make the second half of
% the colors be uniform gray, as if it was representing a non-mapped range
% of phases. If 0, will fill it with a blue->yellow->red submap, for
% looking at bilateral activations (e.g., in two hemispheres). If 2, will
% fill the entire cmap with the r->g->b cmap. (You can later reduce the range
% using cmapExtended. [Default is 1: only show 1 hemifield.]
%
% The redgreenblue cmap shows simple transititions between three colors
%
%
% ras, 10/2006.
% ras, 04/2009 -- got the 'both' option to work well.
if notDefined('view'),              view = getCurView;      	end
if notDefined('displayMode'),       displayMode = 'ph';         end
if notDefined('hemi'),              hemi = 1;                   end
modeInfo = view.ui.([displayMode 'Mode']);

nG = modeInfo.numGrays;
nC = modeInfo.numColors;

% build two colormaps: a red->green->blue map,
% and a blue->yellow->red map, each using half
% the available colors:
rgb = mrvColorMaps('redgreenblue', round(nC/2));
switch hemi
	case 0
		byr = repmat(.6, [nC/2 3]);
		subCmap = [rgb; byr];

	case 1
			byr = mrvColorMaps('redyellowblue', round(nC/2));
			byr = flipud(byr);

% 		% alternate mnemonic:
% 		% red is RIGHT, green is LEFT, blue is UP (like sky), yellow is DOWN
% 		% (like sand)
% 		gbr = mrvColorMaps('greenbluered', round(nC/2), 2);
% 		ryg = flipud(gbr);
% 		ryg(:,2) = ryg(:,2) + ryg(:,3);
% 		ryg(:,1) = ryg(:,1) + ryg(:,3);
% 		ryg(:,3) = 0;
% 		ryg(ryg > 1) = 1;  ryg(ryg < 0) = 0;
% 		subCmap = flipud([gbr; ryg]);
% 		subCmap = circshift(subCmap, round(nC/4));
		subCmap = [rgb; byr];

	case 2
		byr = flipud( mrvColorMaps('redgreenblue', nC-size(rgb,1)) );
		subCmap = [rgb; byr];

	otherwise
		error('Invalid hemifield flag.');
end

modeInfo.cmap = [gray(nG); subCmap];
modeInfo.name = 'redgreenblue cmap';

% override: let you set a the rgb cmap as the whole deal:
if hemi==2, modeInfo.cmap = [gray(nG); mrvColorMaps('redgreenblue', nC)]; end
% if hemi==2, modeInfo.cmap = [gray(nG); mrvColorMaps('gbr', nC, 4)]; end

view.ui.([displayMode 'Mode']) = modeInfo;

% view = refreshScreen(view);

return


function in=tril(in)

precision=in(1).precision;
for ii=1:size(in,1)
 if ii+1<=size(in,2)
  in(ii,ii+1:end)=mp(0,precision);
 end
end


function Y=domain(varargin)
%DOMAIN  Extract domain for PWA variable

% Fast version for plotting simple PWA objects
if nargin == 1
    X = varargin{1};
    if isa(varargin{1},'sdpvar')
        if length(X) == 1
            if length(getvariables(X))==1
                extstruct = yalmip('extstruct',getvariables(X));
                if ~isempty(extstruct)
                    if isequal(extstruct.fcn,'pwa_yalmip') | isequal(extstruct.fcn,'pwq_yalmip')
                        Y = [];
                        for i = 1:length(extstruct.arg{1})
                            Y = [Y extstruct.arg{1}{i}.Pn];
                        end
                        return
                    end
                end
            end
        end
    end
end
error('DOMAIN can only be applied to simple MPT related PWA objects')


function t = isdigit(c)
%ISDIGIT True for decimal digits.
%
%   For a string C, ISDIGIT(C) is 1 for decimal digits and 0 otherwise.
%
%   (In ASCII: characters [0-9].)
%
%   See also: ISALNUM, ISALPHA, ISASCII, ISLOWER, ISPRTCHR, ISUPPER,
%   ISXDIGIT.

%   Author:      Peter John Acklam
%   Time-stamp:  2002-03-03 13:51:04 +0100
%   E-mail:      pjacklam@online.no
%   URL:         http://home.online.no/~pjacklam

   if verLessThan('matlab','9.0')
       error(nargchk(1, 1, nargin));
   else
       narginchk(1, 1);
   end

   t = ischar(c) & ( '0' <= c ) & ( c <= '9' );


% The COBRAToolbox: testChangeIBMCplexParams.m
%
% Purpose:
%    This script tests whether input parameters for the IBM ILOG Cplex solver
%    are in effect when calling solveCobraLP.m, and also tests directly the function
%    setCplexParam used to change the IBM ILOG Cplex parameters in solveCobraLP.m

% save the current path
currentDir = pwd;

%get the warning settings and turn on all warnings
cwarn = warning;
warning('on');

% initialize the test
fileDir = fileparts(which('testChangeIBMCplexParams'));
cd(fileDir);

try
    ibm_cplex = changeCobraSolver('ibm_cplex', 'LP');
catch
    ibm_cplex = false;
end
if ibm_cplex
    LP = struct();
    LP.A = 1;
    LP.b = 1;
    LP.lb = -1000;
    LP.ub = 1000;
    LP.c = 1;
    LP.osense = -1;
    LP.csense = 'L';
    sol = solveCobraLP(LP);
    assert(sol.full == 1)

    if isunix
        % change the time limit for the solver
        % Note: On windows, the timelimit parameter has no effect
        CplexParam = struct('timelimit', 0);
        sol = solveCobraLP(LP, CplexParam);
        % no solution because of time limit
        assert(isempty(sol.full) & sol.origStat == 11)
    end

    % print parameters not recognized by Cplex
    CplexParam.notexist = 1;
    diary('testChangeIBMCplexParams.txt');
    sol = solveCobraLP(LP, CplexParam, 'printLevel', 1);
    diary off
    fid = fopen('testChangeIBMCplexParams.txt', 'r');
    text1 = '';
    line = fgetl(fid);
    while ~isequal(line, -1)
        text1 = [strtrim(text1), ' ', line];
        line = fgetl(fid);
    end
    fclose(fid);
    % check if the warning is printed
    assert(~isempty(strfind(text1, 'Warning: *.notexist cannot be identified as a valid cplex parameter. Ignore.')))
    delete('testChangeIBMCplexParams.txt');

    % print parameters that cannot be uniquely identified
    CplexParam = struct('timelimit', 0, 'feasibility', 1e-8);
    diary('testChangeIBMCplexParams.txt');
    sol = solveCobraLP(LP, CplexParam, 'printLevel', 1);
    diary off
    fid = fopen('testChangeIBMCplexParams.txt', 'r');
    text1 = '';
    line = fgetl(fid);
    while ~isequal(line, -1)
        text1 = [strtrim(text1), ' ', line];
        line = fgetl(fid);
    end
    fclose(fid);
    % check if the warning is printed
    assert(~isempty(strfind(text1, 'Warning: *.feasibility cannot be uniquely identified as a valid cplex parameter. Ignore.')))
    delete('testChangeIBMCplexParams.txt');

    % test changing other Cplex parameters
    LP = Cplex('test setCplexParam');
    CplexParam = struct();
    [CplexParam.simplex.display, CplexParam.tune.display] = deal(0);
    [CplexParam.simplex.tolerances.optimality, CplexParam.simplex.tolerances.feasibility] = deal(1e-9, 1e-8);
    % change parameters using setCplexParam
    LP = setCplexParam(LP, CplexParam);
    % Cplex internal method for getting all changed parameters
    ChangedParams = LP.getChgParam;

    % test also with .Cur at the end of the input struct
    LP = Cplex('test setCplexParam');
    CplexParam = struct();
    [CplexParam.simplex.display.Cur, CplexParam.tune.display.Cur] = deal(0);
    [CplexParam.simplex.tolerances.optimality.Cur, CplexParam.simplex.tolerances.feasibility.Cur] = deal(1e-9, 1e-8);
    % change parameters using setCplexParam
    LP = setCplexParam(LP, CplexParam);
    % Cplex internal method for getting all changed parameters
    ChangedParams2 = LP.getChgParam;

    % the changed parameters should be the same using either input structures
    assert(isequal(ChangedParams, ChangedParams2))
    % check if the parameters are really changed
    assert(isfield(ChangedParams, 'simplex') && isfield(ChangedParams.simplex, 'display') ...
        && ChangedParams.simplex.display.Cur == 0 && isfield(ChangedParams.simplex, 'tolerances') ...
        && isfield(ChangedParams.simplex.tolerances, 'optimality') && ChangedParams.simplex.tolerances.optimality.Cur == 1e-9 ...
        && isfield(ChangedParams.simplex.tolerances, 'feasibility') && ChangedParams.simplex.tolerances.feasibility.Cur == 1e-8 ...
        && isfield(ChangedParams, 'tune') && isfield(ChangedParams.tune, 'display') && ChangedParams.tune.display.Cur == 0)
end

%Reset the warning settings
warning(cwarn);

% change the directory
cd(currentDir)


function a = le( x, y )

evalin( 'caller', 'cvx_verify' );
b = cvx_pushcnstr( x, y, '<=' );
if nargout, a = b; end

% 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 [h] = m_legend(varargin)
% M_LEGEND Add a legend to a map. This function does not have the
%         full functionality of LEGEND but avoids some of the problems
%         encountered using that function in M_MAP. Feel free to
%         add code!
%
%    [legend_handle] = M_LEGEND(HANDLES,String1,String2,String3,...)
%
%    puts a legend on the plot containing the handles in the vector HANDLES
%    using the specified strings as labels for the corresponding handles.
%    By holding the mouse button down, the legend can be moved around the
%    plot.

% Original Author:: Deirdre Byrne, dbyrne@umeoce.maine.edu 00/06/23

% This software is provided "as is" without warranty of any kind.

global MAP_PROJECTION MAP_VAR_LIST

if isempty(MAP_PROJECTION)
  disp('No Map Projection initialized - call M_PROJ first!');
  return;
end

if nargin < 2
  help m_legend
  return
end

handles = varargin{1};
handles = handles(:);
varargin = varargin(:);
s = size(varargin,1);
if s-1 ~= size(handles,1)
  disp('must have same number of legends as handles')
  return
end

varargin = varargin(2:s);

% get axis location
ax=gca;
units = get(ax,'units');
p = get(ax,'pos');
c = get(ax,'color');
if strcmp(c,'none')
  c = get(gcf,'color');
end
if strcmp(c,'none')
  c = [0.702 0.702 0.702];
end

% calculate initial size for legend
xlen = (p(3))/5;
ylen = (p(4))/7;

% calculate position for legend
% default is to put it in bottom right corner
axpos(1) = p(1)+p(3) - xlen;
axpos(2) = p(2);
axpos(3:4) = [xlen ylen];

ButtonDownFcn = 'moveaxis';
Tag = 'legend';

h=axes('units',units,'position',axpos, ...
    'visible','on', ...
    'color',c, ...
    'xcolor','k', ...
    'ycolor','k', ...
    'tag',Tag, ...
    'Buttondownfcn',ButtonDownFcn, ...
    'xlim',[0 1], ...
    'xtick',[], ...
    'ylim',[0 1], ...
    'ytick',[], ...
    'nextplot','add', ...
    'box','on');

lh = length(handles);

% set width based on legend strings
axw = 4;
for i = 1:lh
  l = length(varargin{i});
  axw = max(axw,l);
end
axw = max(2*axw,axw+10);

sf = 1;
set(h,'units','characters');
axpos = get(h,'pos');
axh = (sf*lh+1);
set(h,'position',[(axpos(1)+axpos(3) - axw) axpos(2) axw axh])

for i = 1:lh
  xp = [0.05 0.2 0.35];
  iy = (i*sf-1)*0.8/lh + 0.25;
  yp = [iy iy iy];
  if strcmp(get(handles(i),'type'),'line')
    mark = get(handles(i),'marker');
    msize = get(handles(i),'markersize');
    linest = get(handles(i),'linestyle');
    linew = get(handles(i),'linewidth');
    clr = get(handles(i),'color');
    if ~strcmp(linest,'none')
      l1(i) = plot(xp,yp,'marker','none', ...
	  'color',clr,'linewidth',linew);
    end
    l2(i) = plot(xp(2),yp(2),'marker',mark, ...
	'linewidth',linew, 'markersize', msize, ...
	'color',clr);
    t(i) = text(0.5, iy, varargin{i});
  end
end

if nargout == 0
  clear h
end


function X = full(X)
%FULL Convert to a (dense) tensor.
%
%   FULL(X) returns X, i.e., does nothing.
%
%   See also TENSOR, SPTENSOR/FULL, KTENSOR/FULL, TTENSOR/FULL.
%
%MATLAB Tensor Toolbox.
%Copyright 2015, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2015) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

return;


function [outputEEG, commandHistory] = pop_erplabSelectChannelInterpolation( EEG, varargin )
%pop_erplabSelectChannelInterpolation In EEG data, replace specific channels through interpolation with the option to ignore specific channels
%
% FORMAT
%
%    EEG = pop_erplabSelectChannelInterpolation(inEEG, replaceChannels, ignoreChannels)
%
% INPUT:
%
%    EEG                EEGLAB EEG dataset
%    replaceChannels       list of event codes to shift
%    ignoreChannels        time in sec. If ignoreChannels is positive, the EEG event code time-values are shifted to the right (e.g. increasing delay).
%                       - If ignoreChannels is negative, the event code time-values are shifted to the left (e.g decreasing delay).
%                       - If ignoreChannels is 0, the EEG's time values are not shifted.
%    interpolationMethod         Type of interpolationMethod to use
%                       - 'nearest'    (default) Round to the nearest integer
%                       - 'floor'      Round to nearest ingtowards positive infinity
%                       - 'ceiling'    Round to nearest integer towards negative infinity
%
% OPTIONAL INPUT:
%
%    displayFeedback  Type of feedback to display at Command window
%                        - 'summary'   (default) Print summarized info to Command Window
%                        - 'detailed'  Print event table with latency differences
%                        - 'both'      Print both summarized & detailed info
%
% OUTPUT:
%
%    EEG               EEGLAB EEG dataset with the specified channels replaced through interpolation
%
%
% EXAMPLE:
%
%     replaceChannels       = {'22', '19'};
%     ignoreChannels        = 0.015;
%     interpolationMethod   = 'floor';
%     outputEEG             = pop_erplabSelectChannelInterpolation(EEG, replaceChannels, ignoreChannels, interpolationMethod);
%
%
% Requirements:
%   - EEG_CHECKSET (eeglab function)
%
% See also eegignoreChannels.m erpignoreChannels.m
%
%
% *** This function is part of ERPLAB Toolbox ***
% Author: Jason Arita
% Center for Mind and Brain
% University of California, Davis,
% Davis, CA
% 2009

%% Return help if given no input
if nargin < 1
    help pop_erplabSelectChannelInterpolation
    return
end

%% Error Checks

% Error check: Input EEG structure
if isobject(EEG) % eegobj
    whenEEGisanObject % calls a script for showing an error window
    return
end

%% Call GUI
% When only 1 input is given the GUI is then called
if nargin==1

     % Input EEG error check
    serror = erplab_eegscanner(EEG, 'pop_erplabSelectChannelInterpolation',...
        0, ... % 0 = do not accept md;
        0, ... % 0 = do not accept empty dataset;
        0, ... % 0 = do not accept epoched EEG;
        0, ... % 0 = do not accept if no event codes
        2);    % 2 = do not care if there exists an ERPLAB EVENTLIST struct

    % Quit if there is an error with the input EEG
    if serror; return; end

    % Get previous input parameters
    def  = erpworkingmemory('pop_erplabSelectChannelInterpolation');
    if isempty(def); def = {}; end

    % Call GUI function
    inputstrMat = gui_erplab_selectiveEegInterpolation(def);  % GUI

    % Exit when CANCEL button is pressed
    if isempty(inputstrMat) && ~strcmp(inputstrMat,'')
        commandHistory = 'User selected cancel';
        return;
    end

    replaceChannels          = inputstrMat{1};
    ignoreChannels           = inputstrMat{2};
    interpolationMethod      = inputstrMat{3};
%     displayFeedback          = inputstrMat{4};
    %

    % Save the GUI inputs to memory
    erpworkingmemory('pop_erplabSelectChannelInterpolation', ...
        {replaceChannels,    ...
        ignoreChannels,      ...
        interpolationMethod});
%         displayFeedback });

    % New output EEG set name
    if length(EEG)==1
        EEG.setname = [EEG.setname '_channelInterpolated'];
    end

    [outputEEG, commandHistory] = pop_erplabSelectChannelInterpolation(EEG, ...
        'replaceChannels'    , replaceChannels,     ...
        'ignoreChannels'     , ignoreChannels,      ...
        'interpolationMethod', interpolationMethod, ...
        'History'            , 'gui');

    return;

end

%% Parse named input parameters (vs positional input parameters)

inputParameters               = inputParser;
inputParameters.FunctionName  = mfilename;
inputParameters.CaseSensitive = false;

% Required parameters
inputParameters.addRequired('EEG');
% Optional named parameters (vs Positional Parameters)
inputParameters.addParameter('replaceChannels'     , []);
inputParameters.addParameter('ignoreChannels'      , []);
inputParameters.addParameter('interpolationMethod' , 'spherical');
inputParameters.addParameter('DisplayFeedback'     , 'summary'); % old parameter for BoundaryString
inputParameters.addParameter('History'             , 'script', @ischar); % history from scripting

inputParameters.parse(EEG, varargin{:});

%% Execute corresponding function
replaceChannels     = inputParameters.Results.replaceChannels;
ignoreChannels      = inputParameters.Results.ignoreChannels;
interpolationMethod = inputParameters.Results.interpolationMethod;

outputEEG = erplab_selectiveEegInterpolation(EEG ...
    , replaceChannels       ...
    , ignoreChannels        ...
    , interpolationMethod   );

%% Generate equivalent history command
%

commandHistory  = ''; %#ok<*NASGU>
skipfields      = {'EEG', 'DisplayFeedback', 'History'};
fn              = fieldnames(inputParameters.Results);
commandHistory         = sprintf( '%s  = pop_erplabSelectChannelInterpolation( %s ', inputname(1), inputname(1));
for q=1:length(fn)
    fn2com = fn{q}; % get fieldname
    if ~ismember(fn2com, skipfields)
        fn2res = inputParameters.Results.(fn2com); % get content of current field
        if ~isempty(fn2res)
            if iscell(fn2res)
                commandHistory = sprintf( '%s, ''%s'', {', commandHistory, fn2com);
                for c=1:length(fn2res)
                    getcont = fn2res{c};
                    if ischar(getcont)
                        fnformat = '''%s''';
                    else
                        fnformat = '%s';
                        getcont = num2str(getcont);
                    end
                    commandHistory = sprintf( [ '%s ' fnformat], commandHistory, getcont);
                end
                commandHistory = sprintf( '%s }', commandHistory);
            else
                if ischar(fn2res)
                    if ~strcmpi(fn2res,'off')
                        commandHistory = sprintf( '%s, ''%s'', ''%s''', commandHistory, fn2com, fn2res);
                    end
                else
                    %if iscell(fn2res)
                    %        fn2resstr = vect2colon(cell2mat(fn2res), 'Sort','on');
                    %        fnformat = '{%s}';
                    %else
                    fn2resstr = vect2colon(fn2res, 'Sort','on');
                    fnformat = '%s';
                    %end
                    commandHistory = sprintf( ['%s, ''%s'', ' fnformat], commandHistory, fn2com, fn2resstr);
                end
            end
        end
    end
end
commandHistory = sprintf( '%s );', commandHistory);

% get history from script. EEG
switch inputParameters.Results.History
    case 'gui' % from GUI
        commandHistory = sprintf('%s %% GUI: %s', commandHistory, datestr(now));
        %fprintf('%%Equivalent command:\n%s\n\n', commandHistory);
        displayEquiComERP(commandHistory);
    case 'script' % from script
        EEG = erphistory(EEG, [], commandHistory, 1);
    case 'implicit'
        % implicit
    otherwise %off or none
        commandHistory = '';
end

%
% Completion statement
%
prefunc = dbstack;
nf = length(unique_bc2({prefunc.name}));
if nf==1
    msg2end
end
return

end

% function runGUI(EEG)
%  % Input EEG error check
%     serror = erplab_eegscanner(EEG, 'pop_erplabSelectChannelInterpolation',...
%         0, ... % 0 = do not accept md;
%         0, ... % 0 = do not accept empty dataset;
%         0, ... % 0 = do not accept epoched EEG;
%         0, ... % 0 = do not accept if no event codes
%         2);    % 2 = do not care if there exists an ERPLAB EVENTLIST struct
%
%     % Quit if there is an error with the input EEG
%     if serror
%         return
%     end
%
%     % Get previous input parameters
%     def  = erpworkingmemory('pop_erplabSelectChannelInterpolation');
%     if isempty(def)
%         def = {};
%     end
%
%     % Call GUI
%     inputstrMat = gui_erplab_selectiveEegInterpolation(def);  % GUI
%
%     % Exit when CANCEL button is pressed
%     if isempty(inputstrMat) && ~strcmp(inputstrMat,'')
%         commandHistory = 'User selected cancel';
%         return;
%     end
%
%     replaceChannels          = inputstrMat{1};
%     ignoreChannels           = inputstrMat{2};
%     interpolationMethod      = inputstrMat{3};
%     %     displayFeedback     = inputstrMat{4};
%     %
%     %     erpworkingmemory('pop_erplabSelectChannelInterpolation', ...
%     %         {replaceChannels, ignoreChannels, interpolationMethod, displayFeedback});
%     %
%
%     % New output EEG name
%     if length(EEG)==1
%         EEG.setname = [EEG.setname '_interpolated'];
%     end
%
%
%
%     [EEG, commandHistory] = pop_erplabSelectChannelInterpolation(EEG, ...
%         'replaceChannels'    , replaceChannels,  ...
%         'ignoreChannels'     , ignoreChannels,   ...
%         'interpolationMethod', interpolationMethod,    ...
%         'History'            , 'gui');
%
%
%     return
% end


classdef TestDrawKeylines
    %TestDrawKeylines

    properties (Constant)
        img = fullfile(mexopencv.root(),'test','building.jpg');
    end

    methods (Static)
        function test_1
            im = cv.imread(TestDrawKeylines.img, 'Color',true, 'ReduceScale',2);
            detector = cv.LSDDetector();
            klines = detector.detect(im, 'Scale',2, 'NumOctaves',1);
            out = cv.drawKeylines(im, klines);
            validateattributes(out, {class(im)}, {'size',size(im)});
        end

        function test_2
            im = cv.imread(TestDrawKeylines.img, 'Color',true, 'ReduceScale',2);
            detector = cv.LSDDetector();
            klines = detector.detect(im, 'Scale',2, 'NumOctaves',1);
            out = cv.drawKeylines(im, klines, ...
                'OutImage',im, 'Color',[255 0 0]);
            validateattributes(out, {class(im)}, {'size',size(im)});
        end

        function test_error_argnum
            try
                cv.drawKeylines();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function display(N)
%DISPLAY   Print to command line for CHEBOP2.
% DISPLAY is called automatically when a statement that results in a
% CHEBOP2 output is not terminated with a semicolon.

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

loose = ~isequal(get(0, 'FormatSpacing'), 'compact');

if ( loose )
    fprintf('\n')
end

% Compact version.
if ( isempty(N) )
    fprintf('    empty chebop2\n\n')
    return
end

% Get information that we want to display.
dom = N.domain;
op = N.op;

% Display the information.
fprintf('chebop2 of rank %u: (linear bivariate operator)\n',rank(N))
fprintf('         domain               operator  \n');

fprintf(['[%3.2g,%3.2g] x [%3.2g,%3.2g]  ' func2str(op)  '\n'], dom(1),...
                                          dom(2), dom(3), dom(4));
printBoundaryConditions(N.lbc, 'left');
printBoundaryConditions(N.rbc, 'right');
printBoundaryConditions(N.ubc, 'top');
printBoundaryConditions(N.dbc, 'bottom');

if ( loose )
    fprintf('\n');
end

end

function printBoundaryConditions(BC, string)
% Display the boundary conditions.

    exists = ~isempty(BC);
    if ( exists )
        if ( isa(BC, 'double') )
            fprintf([string ' boundary = %u'], BC);
        elseif ( isa(BC, 'chebfun') )
            % Try to convert to a double:
            n = length(BC);
            if ( n == 1 )
                val = BC.values;
                printBoundaryConditions(val, string)
                return
            end
            fprintf([string ' boundary = function']);
        elseif ( isa(BC, 'function_handle') )
            fprintf([string ' boundary = ' func2str(BC)]);
        end
        fprintf('\n');
    end

end


function [ S, itype, stypes ] = cvx_create_structure( varargin )

%CVX_CREATE_STRUCTURE Construct a basis for a structured matrix.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parse the arguments, if needed %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

S = [];
itype = '';
stypes = {};
if isstruct( varargin{1} ),
    args = varargin{1};
    orig = { args.orig };
    name = { args.name };
    args = { args.args };
    nargs = numel( orig );
else
    nargs = nargin;
    orig = varargin;
    name = orig;
    args = cell( 1, nargs );
    if ischar( varargin{1} ),
        amin = 1;
    else
        args{1} = varargin{1};
        name{1} = '';
        varargin{1} = '';
        amin = 2;
    end
    toks = regexp( varargin, '^([a-zA-Z]\w*)(\(.*\))?$', 'tokens' );
    for k = amin : nargs,
        tok = toks{k};
        if isempty( tok ),
            if k == 1, type = 'variable'; else type = 'structure'; end
            cvx_throw( 'Invalid %s specification: %s', type, varargin{k} );
        end
        tok = tok{1};
        name{k} = tok{1};
        if length(tok) > 1 && ~isempty( tok{2} ),
            try
                args{k} = evalin( 'caller', [ '{', tok{2}(2:end-1), '};' ] );
            catch exc
                cvx_throw( 'Error evaluating structure type: %s\n    %s', orig{k}, exc.message );
            end
        else
            args{k} = {};
        end
    end
end
if nargs == 1 && nargout > 0,
    return
end
sz = args{1};
if iscell( sz ),
    sz = [ sz{:} ];
end
sz(end+1:2) = 1;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Scan the structure strings for symmetry and complex cases. We now handle %
% these cases specially for improved performance.                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

uplo = '';
do_semi = 0;
do_skew = false;
do_conj = false;
do_comp = false;
do_symm = false;
do_nneg = false;
do_dble = false;
is_toep = false;
do_strx = false;
hflags  = false(1,nargs); n_hflags = 0;
iflags  = false(1,nargs); n_iflags = 0;
sflags  = false(1,nargs); n_sflags = 0;
bflags  = false(1,nargs); n_bflags = 0;
pflags  = false(1,nargs); n_pflags = 0;
switch length(sz),
    case 0, bands = [1,1];
    case 1, bands = sz * [1,1];
    otherwise, bands = sz(1:2);
end
for k = 2 : nargs,
    amin = 0; amax = 0;
    nm = lower( name{k} );
    if ~isempty(uplo),
        nm = [ uplo, '_', nm ]; %#ok
        name{k} = nm;
        orig{k} = [ uplo, '_', orig{k} ];
        uplo = '';
    end
    if nm(end) == '_',
        stypes{end+1} = nm; %#ok
        continue;
    end
    switch nm,
        case { 'binary', 'integer' },
            itype = nm;
            iflags(k) = true;
        case { 'upper', 'lower', 'skew', 'doubly' },
            uplo = nm;
            continue;
        case 'nonnegative',
            stypes{end+1} = nm; %#ok
            do_nneg = true;
        case 'complex',
            do_comp = true;
            if do_semi, do_conj = true; end
            do_strx = true;
        case 'complex_if',
            amin = 1; amax = 1;
            if length(args{k}) == 1,
                arg = args{k}{1};
                if isa(arg,'logical') && arg || ~isreal(arg),
                    do_comp = true;
                    if do_semi, do_conj = true; end
                    do_strx = true;
                end
            end
        case 'symmetric',
            sflags(k) = true;                 do_symm = true;
            do_strx = true;
        case 'symmetric_ut',
            sflags(k) = true;
            pflags(k) = true;
            do_strx = true;
        case 'hermitian',
            sflags(k) = true; do_comp = true; do_symm = true; do_conj = true;
            do_strx = true;
        case 'hermitian_if',
            amin = 1; amax = 1;
            sflags(k) = true; do_symm = true;
            if length(args{k}) == 1,
                arg = args{k}{1};
                if isa(arg,'logical') && arg || ~isreal(arg),
                    do_comp = true; do_conj = true;
                    do_strx = true;
                end
            end
        case { 'skew_symmetric', 'skew-symmetric' },
            sflags(k) = true;                 do_symm = true;                 do_skew = true;
            do_strx = true;
        case { 'skew_hermitian', 'skew-hermitian' }
            sflags(k) = true; do_comp = true; do_symm = true; do_conj = true; do_skew = true;
            do_strx = true;
        case {'hankel','upper_hankel'},
            pflags(k) = true;
            sflags(k) = true;
            hflags(k) = true;
            do_strx = true;
        case 'toeplitz',
            hflags(k) = true;
            is_toep = true;
            do_strx = true;
        case { 'semidefinite', 'doubly_nonnegative' },
            do_semi = true; do_symm = true;
            if do_comp, do_conj = true; end
            stypes{end+1} = 'semidefinite'; %#ok
            if nm(1) == 'd',
                stypes{end+1} = 'nonnegative'; %#ok
                do_nneg = true; do_dble = true;
            end
            do_strx = true;
        case 'upper_bidiagonal',
            bflags(k) = true; sflags(k) = true;
            bands = min(bands,[0,1]);
            do_strx = true;
        case 'lower_bidiagonal',
            bflags(k) = true; sflags(k) = true;
            bands = min(bands,[1,0]);
            do_strx = true;
        case 'upper_hessenberg',
            bflags(k) = true; sflags(k) = true;
            bands = min(bands,[1,Inf]);
            do_strx = true;
        case 'lower_hessenberg',
            bflags(k) = true; sflags(k) = true;
            bands = min(bands,[Inf,1]);
            do_strx = true;
        case 'upper_triangular',
            bflags(k) = true; sflags(k) = true;
            bands = min(bands,[0,Inf]);
            do_strx = true;
        case 'lower_triangular',
            bflags(k) = true; sflags(k) = true;
            bands = min(bands,[Inf,0]);
            do_strx = true;
        case 'diagonal',
            bflags(k) = true;
            bands = min(bands,[0,0]);
            do_strx = true;
        case 'tridiagonal',
            bflags(k) = true;
            bands = min(bands,[1,1]);
            do_strx = true;
        case 'scaled_identity',
            bflags(k) = true; is_toep = true;
            bands = min(bands,[0,0]);
            do_strx = true;
        case 'banded',
            amin = 1; amax = 2;
            sflags(k) = length(args{k}) == 2 && ~isequal(args{k}{1},args{k}{2});
            bflags(k) = true;
            lb = args{k}{1};
            switch length(args{k}),
                case 0, cvx_throw( 'Not enough arguments for "banded()" structure.' );
                case 1, ub = args{k}{1};
                case 2, ub = args{k}{2};
                otherwise, cvx_throw( 'Too many arguments for "banded()" structure.' );
            end
            if ~isnumeric( lb ) || length( lb ) ~= 1 || lb < 0 || lb ~= floor( lb ),
                cvx_throw( 'Bandwidth arguments must be nonnegative integers.' );
            elseif ~isnumeric( ub ) || length( ub ) ~= 1 || ub < 0 || ub ~= floor( ub ),
                cvx_throw( 'Bandwidth arguments must be nonnegative integers.' );
            end
            bands = min(bands,[lb,ub]);
            do_strx = true;
        otherwise,
            pflags(k) = true;
            if ~exist( [ 'cvx_s_', nm ], 'file' ),
                cvx_throw( 'Undefined matrix structure type: %s\nTrying to declare multiple variables? Use the VARIABLES keyword instead.', orig{k} );
            end
    end
    n_bflags = n_bflags + bflags(k);
    n_iflags = n_iflags + iflags(k);
    n_sflags = n_sflags + sflags(k);
    n_hflags = n_hflags + hflags(k);
    n_pflags = n_pflags + pflags(k);
    if length( args{k} ) < amin,
        cvx_throw( 'Not enough arguments: %s', orig{k} );
    elseif length( args{k} ) > amax,
        cvx_throw( 'Too many arguments: %s', orig{k} );
    end
end
if ~isempty(uplo),
    cvx_throw( 'Invalid structure type: %s', orig{end} );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Verify integer consistency %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if n_iflags,
    if n_iflags > 1,
        cvx_throw( 'Multiple integer keywords used:\n   %s', sprintf(' %s', orig{iflags} ) );
    elseif do_comp,
        xflags = iflags | findstr( name, 'complex', 'hermitian', 'skew_hermitian' );
        cvx_throw( 'Integer variables must also be real:\n   %s', sprintf(' %s', orig{xflags}) );
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Quick exit for no structure %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if ~do_strx && nargout > 0
    return
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Verify structure consistency %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

xflags = 0;
if n_sflags > 1, xflags = xflags | sflags; end
if n_hflags > 1, xflags = xflags | hflags; end
if n_iflags > 1, xflags = xflags | iflags; end
if n_bflags > 1, xflags = xflags | bflags; end
if do_semi
    if do_skew
        xflags = xflags | sflags | findstr( name, 'semidefinite', 'doubly_nonnegative' );
    elseif do_nneg && ~do_dble,
        xflags = xflags | findstr( name, 'nonnegative', 'semidefinite' );
    end
end
if do_comp && ( n_iflags || do_nneg )
    xflags = xflags | iflags | findstr( name, 'complex', 'hermitian', 'nonnegative', 'doubly_nonnegative' );
end
if do_nneg && do_skew
    xflags = xflags | findstr( name, 'nonnegative', 'skew_symmetric' );
end
if any( xflags ),
    cvx_throw( 'These forms of structure may not be specified simultaneously:\n   %s', sprintf(' %s', orig{xflags} ) );
end
if do_symm && sz(1) ~= sz(2),
    xflags = sflags | findstr( name, 'semidefinite', 'doubly_nonnegative' );
    cvx_throw( 'This matrix structure requires square matrices:%s', sprintf(' %s', orig{xflags} ) );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Construct the basis matrices for the remaining structure elements        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

strs = {};
if is_toep || any( bands < sz(1:2) ),
    [ strs{end+1}, do_symm ] = cvx_s_banded( sz(1), sz(2), [ do_symm, is_toep ], bands(1), bands(2) );
    do_symm = do_symm(1);
end
if n_pflags,
    for k = find(pflags)',
        try
            [ strs{end+1}, do_symm ] = feval( [ 'cvx_s_', lower(name{k}) ], sz( 1 ), sz( 2 ), do_symm, args{k}{:} ); %#ok
        catch exc
            cvx_throw( 'Error constructing structure: %s\n   %s', orig{k}, exc.message );
        end
    end
end
if do_symm,
    [ strs{end+1}, do_symm ] = cvx_s_symmetric( sz(1), sz(2), do_symm ); %#ok
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% If multiple structures have been requested (e.g., toeplitz and banded),  %
% combine them together by finding bases for their orthogonal complements, %
% concatenating, and taking the orthogonal complement of that. This should %
% be used much less frequently than before---if ever---now that we handle  %
% symmetry as a special case for improved performance.                     %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

switch length( strs ),
    case 0,
        if ~do_comp && ~do_skew && nargout ~= 0, return; end
        sz(end+1:2) = 1;
        nel = sz( 1 ) * sz( 2 );
        S = sparse( 1 : nel, 1 : nel, 1, nel, nel );
    case 1,
        S = strs{ 1 };
    otherwise,
        for k = 1 : length(strs),
            strs{k} = cvx_orthog_structure( strs{k} ); %#ok
        end
        S = cvx_orthog_structure( vertcat(strs{:}), true );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Handle complex, skew-symmetric, and Hermitian structures.                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if do_comp,
    S = [ S ; +1j * S ];
    S = S([1:end/2;end/2+1:end],:);
end
if do_skew || do_conj,
    r = (0:sz(1)-1)'; r = r(:,ones(1,sz(2)));
    c = 0:sz(2)-1; c = c(ones(1,sz(1)),:);
    ut = r < c; dg = r == c;
    if do_skew,
        S(:,ut) = - S(:,ut);
        S(:,dg) = 0;
    end
    if do_conj,
        S(:,ut) = conj(S(:,ut));
        S(:,dg) = real(S(:,dg));
    end
    S = S(any(S,2),:);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Report an error of the structure is empty                                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if isempty( S ),
    cvx_throw( 'Incompatible structure modifiers:%s', sprintf( ' %s', args.orig ) );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Replicate structure for N-D arrays                                       %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if length( sz ) > 2,
    S = cvx_replicate_structure( S, sz( 3 : end ) );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Display the structure if called with no output arguments                 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if nargout == 0,
    [ii,jj,vv] = find( S );
    if isempty(sz), sz = [1,1]; end
    Z = reshape( full( sparse( jj, 1, ii .* vv, prod(sz), 1 ) ), sz );
    temp = sprintf( ',%d', sz );
    fprintf( 'Name: %s\nSize: %s\nStructure:', name{1}, temp(2:end) );
    if ~isempty( itype ),
        stypes = [ stypes, itype ];
    end
    for k = 2 : nargs,
        if ~any( strcmp(orig{k},stypes) )
            fprintf( ' %s', orig{k} );
        end
    end
    fprintf( '\n' );
    if ~isempty( stypes ),
        fprintf( 'Passthrough:' );
        for k = 1 : length(stypes),
            fprintf( ' %s', stypes{k} );
        end
    end
    fprintf( '\n\n' );
    fmt = get(0,'format');
    set(0,'format','rational');
    disp( Z );
    set(0,'format',fmt);
    clear S
end

function z = findstr( x, varargin )
q = varargin;
z = cellfun( @(z)any(strcmpi(z,q)), x );

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


function UFexport (list, check, tmp)
%UFEXPORT export to Matrix Market and Rutherford/Boeing formats
%
% Example:
%   UFexport ;          % export the entire collection
%   UFexport (list) ;   % just export matrices whose id's are given in the list
%   UFexport (list, 'check') ;      % also read them back in, to check
%
% If the list is empty, all matrices in the collection are exported.
% A 3rd argument tmp changes the tmp directory for UFread.
%
% See also UFget, UFwrite, RBio, mwrite.

% Copyright 2006-2007, Timothy A. Davis

%-------------------------------------------------------------------------------
% get the input arguments
%-------------------------------------------------------------------------------

index = UFget ;
nmat = length (index.nrows) ;

if (nargin < 1 || isempty (list))
    list = 1:nmat ;
end

check = ((nargin > 1) && strcmp (check, 'check')) ;

if (nargin < 3)
    tmp = '' ;
end

%-------------------------------------------------------------------------------
% determine the top-level directory to use
%-------------------------------------------------------------------------------

[url topdir] = UFlocation ;

%-------------------------------------------------------------------------------
% export the matrices
%-------------------------------------------------------------------------------

for id = list

    % get the MATLAB version
    Problem = UFget (id, index) ;
    disp (Problem) ;

    % create the MM and RB versions
    UFwrite (Problem, [topdir 'MM'], 'MM', 'tar') ;
    UFwrite (Problem, [topdir 'RB'], 'RB', 'tar') ;

    % check the new MM and RB versions
    if (check)
	for format = { 'MM' , 'RB' }
	    try
		if (isempty (tmp))
		    P2 = UFread ([topdir format{1} filesep Problem.name]) ;
		else
		    P2 = UFread ([topdir format{1} filesep Problem.name], tmp) ;
		end
	    catch
		% The Problem may be too large for two copies to be in the
		% MATLAB workspace at the same time.  This is not an error,
		% but it means that the Problem cannot be checked.
		P2 = [ ] ;
		fprintf ('Unable to read %s/%s\n', format {1}, Problem.name) ;
		fprintf ('%s\n', lasterr) ;
	    end
	    if (~isempty (P2) && ~isequal (Problem, P2))
                Problem
                P2
		error ('%s version mismatch: %s\n', format {1}, Problem.name) ;
	    end
	    clear P2
	end
    end
end


function [params, names] = expvarMeanExtractParam(model)

% EXPVARMEANEXTRACTPARAM Extract weights and biases from an EXPVARMEAN mapping.
% FORMAT
% DESC returns a vector of all the parameters from the mapping
% associated with the mean function of a exponential variational approximation.
% ARG model : the mappings from which we wish to extract the parameters.
% and biases.
% RETURN params : vector of all the parameters.
% RETURN names : optional additional returned cell array of the
% names of the parameters.
%
% SEEALSO : expvarMeanCreate, expvarMeanExpandParam, modelExtractParam
%
% COPYRIGHT : Neil D. Lawrence, 2006

% SHEFFIELDML

if nargout > 1
  [params, names] = kernExtractParam(model.kern);
else
  params = kernExtractParam(model.kern);
end


% fieldtripchan2eeglab() - convert Fieldtrip channel location structure
%                          to EEGLAB channel location structure
%
% Usage:
%   >> chanlocs = fieldtripchan2eeglab( fieldlocs );
%
% Inputs:
%   fieldlocs - Fieldtrip channel structure. See help readlocs()
%
% Outputs:
%   chanlocs  - EEGLAB channel location structure.
%
% Author: Arnaud Delorme, SCCN, INC, UCSD, 2006-
%
% See also: readlocs()

% Copyright (C) 2003 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% 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 2 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, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

function chanlocs = fieldtripchan2eeglab( loc );

    if nargin < 1
        help fieldtripchan2eeglab;
        return;
    end;

    chanlocs = struct('labels', loc.label(:)', 'X', mattocell(loc.pnt(:,1)'), ...
                                            'Y', mattocell(loc.pnt(:,2)'), ...
                                            'Z', mattocell(loc.pnt(:,3)'));
    chanlocs = convertlocs(chanlocs, 'cart2all');


function hole_num = p00_hole_num ( test )

%*****************************************************************************80
%
%% P00_HOLE_NUM counts the holes in a problem.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer TEST, the index of the test problem
%
%    Output, integer HOLE_NUM, the number of boundary segments.
%
  if ( test == 1 )
    hole_num = p01_hole_num ( );
  elseif ( test == 2 )
    hole_num = p02_hole_num ( );
  elseif ( test == 3 )
    hole_num = p03_hole_num ( );
  elseif ( test == 4 )
    hole_num = p04_hole_num ( );
  elseif ( test == 5 )
    hole_num = p05_hole_num ( );
  elseif ( test == 6 )
    hole_num = p06_hole_num ( );
  elseif ( test == 7 )
    hole_num = p07_hole_num ( );
  elseif ( test == 8 )
    hole_num = p08_hole_num ( );
  elseif ( test == 9 )
    hole_num = p09_hole_num ( );
  elseif ( test == 10 )
    hole_num = p10_hole_num ( );
  elseif ( test == 11 )
    hole_num = p11_hole_num ( );
  elseif ( test == 12 )
    hole_num = p12_hole_num ( );
  elseif ( test == 13 )
    hole_num = p13_hole_num ( );
  elseif ( test == 14 )
    hole_num = p14_hole_num ( );
  elseif ( test == 15 )
    hole_num = p15_hole_num ( );
  else
    fprintf ( 1, '\n' );
    fprintf ( 1, 'P00_HOLE_NUM - Fatal error!\n' );
    fprintf ( 1, '  Input value of TEST is out of range.\n' );
    fprintf ( 1, '  TEST = %d\n', test );
    error ( 'P00_HOLE_NUM - Fatal error!' )
  end

  return
end


%% Remove duplicate segments
function smaps2 = msPruneSegments(smaps)

smaps2 = smaps;
segment_list = {};

for m = 1:size(smaps, 2)
    for k = 1:max(smaps(:, m))
        ind = smaps(:, m)==k;
        [segment_list, isnew] = prune_add2list(segment_list, find(ind));
        if ~isnew
            smaps2(ind, m) = 0;
        end
    end
    uid = unique(smaps2(:, m));
    uid = setdiff(uid, 0);
    for k = 1:numel(uid)
        ind = smaps2(:, m)==uid(k);
        smaps2(ind, m) = k;
    end
end

function [seglist, isnew] = prune_add2list(seglist, ids)

isnew = true;
for k = 1:numel(seglist)
    seg = seglist{k};
    if numel(seg)==numel(ids) && all(seg==ids)
        isnew = false;
        return;
    end
end
seglist{end+1} = ids;