cosmo oddeven partitioner skl

function partitions = cosmo_oddeven_partitioner(ds, type)
    % generates an odd-even partition scheme
    %
    % partitions=cosmo_oddeven_partitioner(chunks,[type])
    %
    % Input
    %    ds              dataset struct with field .ds.chunks.
    %    type            One of:
    %                    - 'full': two partitions are returned, training on odd
    %                       unique chunks and testing on even unique chunks,
    %                       and vice versa (default). A typical use case is
    %                       classification analysis (using
    %                       cosmo_crossvalidation_measure)
    %                    - 'half': a single partition is returned, training on
    %                       odd unique chunks and testing on even unique chunks
    %                       only. A typical use case is split-half
    %                       correlation analysis (using
    %                       cosmo_correlation_measure) because correlations are
    %                       symmetric (i.e. corr(a,b)==corr(b,a) for column
    %                       vectors a and b)
    %
    % Output:
    %    partitions      A struct with fields .train_indices and .test_indices.
    %                    Each of these is an Nx1 cell (N=1 when type='half',
    %                    N=2 when type='full'.).
    %                    .train_indices{k} and .test_indices{k} contain the
    %                    sample indices for the sets of unique chunks
    %                    alternatingly
    %
    % Example:
    %     ds=struct();
    %     ds.samples=NaN(8,99); % will be ignored by this function
    %     ds.sa.targets=[8 9 8 9 8 9 8 9]';
    %     ds.sa.chunks=[1 1 2 2 6 7 7 6]';
    %     p=cosmo_oddeven_partitioner(ds);
    %     % note that chunks=6 ends up in the odd chunks and chunks=7 in the
    %     % even chunks, as 6 [7] is the third [fourth] unique value of chunks.
    %     cosmo_disp(p);
    %     %|| .train_indices
    %     %||   { [ 1    [ 3
    %     %||       2      4
    %     %||       5      6
    %     %||       8 ]    7 ] }
    %     %|| .test_indices
    %     %||   { [ 3    [ 1
    %     %||       4      2
    %     %||       6      5
    %     %||       7 ]    8 ] }
    %     %||
    %     %
    %     % only half-partition (for correlation-based analysis)
    %     p=cosmo_oddeven_partitioner(ds,'half');
    %     cosmo_disp(p);
    %     %|| .train_indices
    %     %||   { [ 1
    %     %||       2
    %     %||       5
    %     %||       8 ] }
    %     %|| .test_indices
    %     %||   { [ 3
    %     %||       4
    %     %||       6
    %     %||       7 ] }
    %
    % Notes:
    %   - typically, the 'half' option can be used with
    %     cosmo_correlation_measure, because correlations are symmetric; the
    %     'full' option can be used with cosmo_crossvalidation_measure.
    %   - this function returns partitions based on the sorted unique values
    %     in chunks, not the chunk values themselves. For example, if the
    %     sorted unique values of .sa.chunks are [2,4,5,8], then the values
    %     2 and 5 are at the 'odd' position (1 and 3), and 4 and 8 are at the
    %     'even' position.
    %
    % See also: cosmo_nchoosek_partitioner
    %
    % #   For CoSMoMVPA's copyright information and license terms,   #
    % #   see the COPYING file distributed with CoSMoMVPA.           #

    chunks = get_chunks(ds);

    if nargin < 2 || isempty(type)
        type = 'full';
    end

    switch type
        case 'full'
            do_half_partition = false;
        case 'half'
            do_half_partition = true;
        otherwise
            error('illegal type: must be ''full'' or ''half''');
    end

    indices = cosmo_index_unique(chunks);
    nparts = numel(indices);
    if nparts < 2
        error('Need >=2 chunks, found %d', numel(indices));
    end

    % there are two partitions, unless do_half_partition in which case
    % there is one

    if do_half_partition
        npartitions = 1;
    else
        npartitions = 2;
    end

    % allocate space for output
    train_indices = cell(1, npartitions);
    test_indices = cell(1, npartitions);

    % Make partitions using even and odd chunks
    %%%% >>> Your code here <<< %%%%

    partitions.train_indices = train_indices;
    partitions.test_indices = test_indices;

    % final check to make sure all is kosher (including balanced-ness)
    cosmo_check_partitions(partitions, ds);

function ds = get_chunks(ds)
    if isnumeric(ds) && isvector(ds)
        % direct numeric
        return
    elseif isstruct(ds)
        if cosmo_isfield(ds, 'sa.chunks')
            ds = ds.sa.chunks;
            return
        end
    end

    error(['illegal input: expected dataset struct with field '...
           '.sa.chunks, or numeric vector']);