function [ r, g, b ] = ppma_read ( file_name )

%*****************************************************************************80
%
%% PPMA_READ opens an ASCII PPM file and reads the data.
%
%  The PPMA file is assumed to have the format:
%
%    P3
%    # feep.ppma
%    ncol nrow
%    maxrgb, the largest legal value for the data.
%    row 1, a list of ncol triples between 0 and maxrgb.
%    row 2, a list of ncol triples between 0 and maxrgb.
%    ...
%    row nrow, a list of ncol triples between 0 and maxrgb.
%
%    Lines beginning with '#' are comments.
%
%  Example:
%
%    P3
%    # feep.ppma
%    4 4
%    15
%     0  0  0  0  0  0    0  0  0   15  0 15
%     0  0  0  0 15  7    0  0  0    0  0  0
%     0  0  0  0  0  0    0 15  7    0  0  0
%    15  0 15  0  0  0    0  0  0    0  0  0
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 February 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string FILE_NAME, the name of the PPMA file to read.
%
%    Output, integer R{NROW,NCOL], G{NROW,NCOL], B{NROW,NCOL] is the RGB data read from the file.
%
  FALSE = 0;
  TRUE = 1;

  r = [];
  g = [];
  b = [];

  fid = fopen ( file_name, 'r' );

  if ( fid < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'PPMA_READ - Fatal error!\n' );
    fprintf ( 1, '  Could not open the input file.\n' );
    error ( 'PPMA_READ - Fatal error!' );
    return;
  end
%
%  Read the first line.
%
  line = fgets ( fid );
%
%  Verify that the first two characters are the "magic number".
%  Matlab strncmp returns 1 for equality, and 0 for inequality.
%
  if ( strncmp ( line, 'P3', 2 ) == 0 )
    return;
  end
%
%  Move to the next noncomment line.
%
  while ( 1 )
    line = fgets ( fid );
    if ( line(1) ~= '#' )
      break;
    end
  end
%
%  Extract NCOL and NROW.
%
  [ array, count ] = sscanf ( line, '%d' );
  ncol = array(1);
  nrow = array(2);
%
%  Move to the next noncomment line.
%
  while ( 1 )
    line = fgets ( fid );
    if ( line(1) ~= '#' )
      break;
    end
  end
%
%  Extract MAXRGB, and ignore it.
%
  [ array, count ] = sscanf ( line, '%d' );
  maxRGB = array(1);
%
%  Set aside space for R, G< B.
%
  r = zeros ( nrow, ncol );
  g = zeros ( nrow, ncol );
  b = zeros ( nrow, ncol );

  i = 1;
  j = 0;
  p = 0;
  done = FALSE;

  while ( done == FALSE )
%
%  Move to the next noncomment line.
%
    while ( 1 )
      line = fgets ( fid );
      if ( line(1) ~= '#' )
        break;
      end
    end
    [ array, count ] = sscanf ( line, '%d' );
%
%  Each value that you read goes into the "next" open entry.
%  When reading R, we update the row and column indices.
%
    for k = 1 : count

      if ( p == 0 )
        j = j + 1;
        if ( ncol < j )
          j = 1;
          i = i + 1;
        end
        r(i,j) = array(k);
      elseif ( p == 1 )
        g(i,j) = array(k);
      elseif ( p == 2 )
        b(i,j) = array(k);
        if ( i == nrow & j == ncol )
          done = TRUE;
        end
      end

      p = mod ( p+1, 3 );

    end

  end

  fclose ( fid );

  return
end


function metaImageWrite(img, fileName, varargin)
% Save image data using MetaImage file format (MHD).
%
%   metaImageWrite(IMG, FILENAME);
%   IMG is a matlab array, and FILENAME is the generic name (without
%   extension) of the metaimage file.
%   The functions tries to determine which parameters are appropriate for
%   the given image.
%
%   metaImageWrite(IMG, FILENAME, INFO);
%   Gives an additional structure as argument, containing additional
%   properties.
%
%   metaImageWrite(..., 'colorImage', true);
%   Forces writing as a RGB color array.
%
%   metaImageWrite(..., PARAM, VALUE);
%   Specifies additional properties as parameter key and value pairs. Case
%   is relevant. See http://www.itk.org/Wiki/MetaIO/Documentation for
%   details.
%
%   Example
%   [x y z] = meshgrid(1:80, 1:80, 1:80);
%   img = ((x-40).^2 + (y-40).^2 + (z-40).^2)<1000;
%   img = uint8(img*255);
%   metaImageWrite(img, 'ball');
%   metaImageWrite(img, 'ball.mhd');    % works also, same result
%   metaImageWrite(img, 'ball', 'ElementType', 'MET_USHORT', ...
%       'ElementByteOrderMSB', 'True')
%
%   See also
%     metaImageWrite, metaImageInfo
%

% ------
% Author: David Legland
% e-mail: david.legland@inrae.fr
% Created: 2010-02-03,    using Matlab 7.9.0.529 (R2009b)
% http://www.pfl-cepia.inra.fr/index.php?page=slicer
% Copyright 2010 INRA - Cepia Software Platform.

%% Initialisations

% extract meta-information
info = struct;
if ~isempty(varargin)
    var = varargin{1};
    if isstruct(var)
        info = var;
        varargin(1) = [];
    end
end

% permute image dimensions to use x as first index
img = permute(img, [2 1 3:ndims(img)]);

% extract image dimension
dims = size(img);
nd = length(dims);

% flag for color image (false by default)
isColor = false;

%% Process file names

% extract file name parts
[path, name, ext] = fileparts(fileName);

% if extension is different from '.mhd', keep it as part of the name
if ~strcmp(ext, '.mhd')
    name = [name ext];
end

% header and binary file names
headerFileName = [name '.mhd'];
binaryFileName = [name '.raw'];

%% Create file info structure

% check main information are present
if ~isfield(info, 'ObjectType')
    info.ObjectType = 'Image';
end
if ~isfield(info, 'NDims')
    info.NDims = nd;
end
if ~isfield(info, 'DimSize')
    info.DimSize = dims;
end
if ~isfield(info, 'ElementType')
    info.ElementType = metaTypeToString(class(img));
end
if ~isfield(info, 'ElementDataFile')
    info.ElementDataFile = binaryFileName;
end

% parse additional input arguments and populate the "info" structure
while length(varargin) > 1
    key = varargin{1};
    if ~ischar(key)
        error('following parameter must be a string: %s', key);
    end

    % check function-specific options.
    if strcmpi(key, 'colorImage')
        isColor = varargin{2};
    else
        info.(key) = varargin{2};
    end

    varargin(1:2) = [];
end

% in case of color image, update the info structure
if isColor
    info.NDims = info.NDims - 1;
    info.DimSize = info.DimSize([1 2 4:end]);
    info.ElementNumberOfChannels = 3;
end

% ensure MSB info is written for data other than 8-bits
elementByteOrderDefined = isfield(info, 'ElementByteOrderMSB');
binaryDataByteOrderDefined = isfield(info, 'BinaryDataByteOrderMSB');
if ~ischar(img) && ~(elementByteOrderDefined || binaryDataByteOrderDefined)
    info.BinaryData = true;
    if ispc
        info.ElementByteOrderMSB = false;
    else
        info.ElementByteOrderMSB = true;
    end
end

% open file
f = fopen(fullfile(path, headerFileName), 'wt');

%% write minimal information tags

fprintf(f, '%s = %s\n', 'ObjectType', 'Image');
fprintf(f, '%s = %d\n', 'NDims', info.NDims);
fprintf(f, '%s =%s\n', 'DimSize', ...
    sprintf(repmat(' %d', 1, info.NDims), info.DimSize));
fprintf(f, '%s = %s\n', 'ElementType', info.ElementType);

%% write each additional tag

names = fieldnames(info);
for i = 1:length(names)
    name = names{i};

    % some tags are either in the very beginning or at the end, so they are
    % not processed in the loop
    if ismember(name, {'ObjectType', 'NDims', 'DimSize', 'ElementType', ...
            'ElementDataFile'})
        continue;
    end

    fprintf(f, '%s = %s\n', name, convertToString(info.(name)));
end

%% write binary data info into header

fprintf(f, '%s = %s\n', 'ElementDataFile', binaryFileName);

fclose(f);

%% Write binary data

% Specify little- or big-endian ordering
byteOrder = determineByteOrder(info);

% extract data precision
precision = parseMetaType(info.ElementType);

% open file for binary writing
f = fopen(fullfile(path, binaryFileName), 'wb');

% write image data in correct order
if ~isColor
    % write grayscale data
    fwrite(f, img(:), precision, 0, byteOrder);
else
    % first permute data to write RGB of each element, then x, y, and z
    data = permute(img, [3 1 2 4:ndims(img)]);
    fwrite(f, data(:), precision, 0, byteOrder);
end

% close binary file
fclose(f);

function type = parseMetaType(string)
% Convert MetaImage type string into a Matlab data type name.

switch string
    case 'MET_UCHAR'
        type = 'uint8';
    case 'MET_CHAR'
        type = 'int8';
    case 'MET_USHORT'
        type = 'uint16';
    case 'MET_SHORT'
        type = 'int16';
    case 'MET_UINT'
        type = 'uint32';
    case 'MET_INT'
        type = 'int32';
    case 'MET_FLOAT'
        type = 'single';
    case 'MET_DOUBLE'
        type = 'double';
    otherwise
        error('unknown element type in metaimage header: %s', string);
end

function string = metaTypeToString(type)
% Convert a Matlab data type name into MetaImage Type string.

switch type
    case 'int8'
        string = 'MET_CHAR';
    case 'uint8'
        string = 'MET_UCHAR';
    case 'int16'
        string = 'MET_SHORT';
    case 'uint16'
        string = 'MET_USHORT';
    case 'int32'
        string = 'MET_INT';
    case 'uint32'
        string = 'MET_UINT';
    case 'single'
        string = 'MET_FLOAT';
    case 'double'
        string = 'MET_DOUBLE';
    otherwise
        error('unknown pixel type: %s', type);
end

function string = convertToString(data)
% Utility function that converts logical or numeric data to char array.

N = length(data(:));

if ischar(data)
    string = data;

elseif islogical(data)
    strings = {'false', 'true'};
    pattern = ['%s' repmat(' %s', 1, N-1)];
    string = sprintf(pattern, strings{data(:)+1});

elseif isinteger(data)
    pattern = ['%d' repmat(' %d', 1, N-1)];
    string = sprintf(pattern, data(:));

elseif isfloat(data)
    pattern = ['%g' repmat(' %g', 1, N-1)];
    string = sprintf(pattern, data(:));

else
    error('Unknwon type of data');
end

function byteOrder = determineByteOrder(info)
% Identify the byte-order character to use for low-level fwrite function.

% default byte order given by system (native)
byteOrder = 'n';

% first check the ElementByteOrderMSB field
if isfield(info, 'ElementByteOrderMSB')
    if info.ElementByteOrderMSB
        byteOrder = 'b';
    else
        byteOrder = 'l';
    end
end

% also check the BinaryDataByteOrderMSB field
if isfield(info, 'BinaryDataByteOrderMSB')
    if info.BinaryDataByteOrderMSB
        byteOrder = 'b';
    else
        byteOrder = 'l';
    end
end


function[]=flipx
% FLIPX    Flips the direction of the x-axis
%   _________________________________________________________________
%   This is part of JLAB --- type 'help jlab' for more information
%   (C) 2002, 2004 J.M. Lilly --- type 'help jlab_license' for details

if strcmpi(get(gca,'xdir'),'normal')
  set(gca,'xdir','reverse')
  breverse=1;
elseif strcmpi(get(gca,'xdir'),'reverse')
  set(gca,'xdir','normal')
  breverse=0;
end

%Update for compatibility with ZOOL
if isappdata(gcf,'xlimitslock')
   if getappdata(gcf,'xlimitslock')
      h=gca;
      hall=axeshandles;
      for i=1:length(hall)
         if breverse
             set(hall(i),'xdir','reverse')
         else
             set(hall(i),'xdir','normal')
         end
      end
   end
end


function pass = test_galleryball( )

names = {'deathstar','gaussian','helmholtz','moire','peaks',...
             'roundpeg','solharm','stripes','wave'};

N = length(names);
% Test construction of each gallery function.
for k = 1:N
    pass(k) = doesNotCrash(names{k});
end

if (nargout > 0)
    pass = all(pass(:));
end
end

function pass = doesNotCrash(name)
try
    fn = cheb.galleryball(name);  % Test returning the function
    pass = true;
catch ME %#ok<NASGU>
    pass = false;
end
end


function example;

I = load_images('house');

figure('Name','Input sequence');
subplot(2,2,1); imshow(I(:,:,:,1));
subplot(2,2,2); imshow(I(:,:,:,2));
subplot(2,2,3); imshow(I(:,:,:,3));
subplot(2,2,4); imshow(I(:,:,:,4));

R = exposure_fusion(I,[1 1 1]);
figure('Name','Result');
imshow(R);


function test_bug2303

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY ft_read_header read_eeglabheader

filename = dccnpath('/home/common/matlab/fieldtrip/data/test/bug2303/Dopa2_Quart2_Av.set');

hdr = ft_read_header(filename);

% hdr =
%
%              Fs: 500
%          nChans: 14
%        nSamples: 450
%     nSamplesPre: 100
%         nTrials: 1
%           label: {14x1 cell}
%            elec: [1x1 struct]
%            orig: [1x1 struct]
%        chantype: {14x1 cell}
%        chanunit: {14x1 cell}

assert(ft_filetype(filename, 'eeglab_set'))
assert(hdr.Fs==500);
assert(hdr.nChans==14);
assert(hdr.nSamplesPre==100);


function [dmeg, dspc] = block_delay(bmeg, bspc, d)

Nblock = length(bmeg);
dmeg = cell(Nblock,1);
dspc = cell(Nblock,1);
for bi=1:Nblock
    common = min(size(bmeg{bi},1),length(bspc{bi}));
    dmeg{bi} = bmeg{bi}((1+d):common,:);
    dspc{bi} = bspc{bi}(1:(common-d));
end
dmeg = cell2mat(dmeg);
dspc = cell2mat(dspc);


function [] = aps_era_ECMWF_Python(timing,wheatherregstr)
% script for the creation of download python script files for ERA-I model
% downloads monthly data in splitted times
% input str: timing in the format 'YYYYMMDDHH'
%
%     Copyright (C) 2015
%     With permission of Hannes Bathke
%     Email: eedpsb@leeds.ac.uk or davidbekaert.com
%
%     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.,
%     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%
% By Hannes Bathke -- January 2014
%
% modifications:
% DB    02/2014 Integrate in the APS toolbox
% DB    03/2014 Auto download included

year = timing(1:4);
month = timing(5:6);
day = timing(7:8);
htime = timing(9:10);

%mfield = calendar(str2double(year),str2double(month));
%nday = max(max(mfield));
datestr = [year,'-',month,'-',day];

pythonsc_path = [timing,'.py'];
fid = fopen(pythonsc_path,'w');
fprintf(fid,'#!/usr/bin/env python\n');
fprintf(fid,'\n');
fprintf(fid,'from ecmwfapi import ECMWFDataServer\n');
fprintf(fid,'\n');
fprintf(fid,'# To run this example, you need an API key\n');
fprintf(fid,'# available from https://api.ecmwf.int/v1/key/\n');
fprintf(fid,'\n');
fprintf(fid,'server = ECMWFDataServer()\n');
fprintf(fid,'\n');
fprintf(fid,'server.retrieve({\n');
fprintf(fid,'          ''dataset'' : "interim",\n');
fprintf(fid,'          ''class''   : "ei",\n');
fprintf(fid,'          ''type''    : "an",\n');
fprintf(fid,'          ''stream''  : "oper",\n');
fprintf(fid,'          ''levtype'' : "pl",\n');
fprintf(fid,'          ''levelist'': "1/2/3/5/7/10/20/30/50/70/100/125/150/175/200/225/250/300/350/400/450/500/550/600/650/700/750/775/800/825/850/875/900/925/950/975/1000",\n');
fprintf(fid,'          ''param''   : "129.128/130.128/157.128/246.128",\n');
fprintf(fid,'          ''date''    : "%s",\n',datestr);
fprintf(fid,'          ''time''    : "%s",\n',htime);
fprintf(fid,'          ''step''    : "0",\n');
fprintf(fid,'          ''format''  : "netcdf",\n');
fprintf(fid,'          ''resol''   : "auto",\n');
fprintf(fid,'          ''area''    : "%s",\n',wheatherregstr);
fprintf(fid,'          ''grid''    : "0.75/0.75",\n');
fprintf(fid,['          ''target''  : "ggap' num2str(timing(1:10)) '00.nc",\n']);
fprintf(fid,'                })\n');


function writeMSH(filename,V,T,F)
  % WRITEMSH  write a tet mesh to gmsh's .msh file format
  %
  % writeMSH(filename,V,T,F)
  %
  % Inputs:
  %   V  #V by dim=3 list of vertex positions
  %   T  #T by 4 list of tet indices
  %   F  #F by 3 list of triangle indices

  %disp(['writing: ',filename]);
  fp = fopen(filename,'w');
  % Write header
  fprintf(fp,'$MeshFormat\n');
  % http://www.manpagez.com/info/gmsh/gmsh-2.2.2/gmsh_63.php
  fprintf(fp,'%d %d %d\n',2,0,8);
  fprintf(fp,'$EndMeshFormat\n');
  % write nodes
  fprintf(fp,'$Nodes\n');
  fprintf(fp,'%d\n',size(V,1));
  fprintf(fp,'%d %0.17g %0.17g %0.17g\n',[1:size(V,1);V']);
  fprintf(fp,'$EndNodes\n');
  % write elements
  fprintf(fp,'$Elements\n');
  fprintf(fp,'%d\n',size(T,1)+size(F,1));
  % write tets
  if ~isempty(T)
    fprintf(fp,'%d 4 2 0 1 %d %d %d %d\n',[1:size(T,1);T']);
  end
  if ~isempty(F)
    fprintf(fp,'%d 2 2 0 1 %d %d %d\n',[size(T,1)+(1:size(F,1));F']);
  end
  fprintf(fp,'$EndElements\n');
  fclose(fp);
end


function [split,numpieces]=explode(string,delimiters)
% EXPLODE    Splits string into pieces.
%
% EXPLODE(STRING,DELIMITERS) returns a cell array with the pieces
% of STRING found between any of the characters in DELIMITERS.
%
% :Usage:
% ::
%
%     [SPLIT,NUMPIECES] = EXPLODE(STRING,DELIMITERS)
%
% also returns the number of pieces found in STRING.
%
% :Inputs:
%
%   **STRING:**
%        the string to split (string)
%
%   **DELIMITERS:**
%        the delimiter characters (string)
%
% :Outputs:
%
%   **SPLIT:**
%        the split string (cell array), each cell is a piece
%
%   **NUMPIECES:**
%        the number of pieces found (integer)
%
% :Examples:
% ::
%
%    STRING = 'ab_c,d,e fgh'
%    DELIMITERS = '_,'
%    [SPLIT,NUMPIECES] = EXPLODE(STRING,DELIMITERS)
%    SPLIT = 'ab'    'c'    'd'    'e fgh'
%    NUMPIECES = 4
%
% :See also:
% IMPLODE, STRTOK
%
% ..
%   Created: Sara Silva (sara@itqb.unl.pt) - 2002.04.30
%
%   Modified: Matthew Davidson (matthew@psych.columbia.edu) - 2005.10.11
% ..

if isempty(string) % empty string, return empty and 0 pieces
    split{1}='';
    numpieces=0;

elseif isempty(delimiters) % no delimiters, return whole string in 1 piece
    split{1}=string;
    numpieces=1;

else % non-empty string and delimiters, the correct case

    remainder=string;
    i=0;

    % If the first letter is in the delimiters, add a blank piece at the
    % beginning
    firstletteridx = strfind(delimiters,string(1));
    if ~isempty(firstletteridx)
        i=i+1;
        split{i}='';
        remainder = string(2:end);
    end

    while ~isempty(remainder)
        [piece,remainder]=strtok(remainder,delimiters);
        i=i+1;
        split{i}=piece;
    end
    numpieces=i;

end


function egrad = getEuclideanGradient(problem, x, storedb, key)
% Computes the Euclidean gradient of the cost function at x.
%
% function egrad = getEuclideanGradient(problem, x)
% function egrad = getEuclideanGradient(problem, x, storedb)
% function egrad = getEuclideanGradient(problem, x, storedb, key)
%
% Returns the Euclidean gradient at x of the cost function described in the
% problem structure.
%
% storedb is a StoreDB object, key is the StoreDB key to point x.
%
% Because computing the Hessian based on the Euclidean Hessian will require
% the Euclidean gradient every time, to avoid overly redundant
% computations, if the egrad function does not use the store caching
% capabilites, this implements an automatic caching functionality. Writing
% egrad to accept the optional store or storedb parameter will disable
% automatic caching, but allow user controlled caching.
%
% See also: getGradient canGetGradient canGetEuclideanGradient

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, July 9, 2013.
% Contributors:
% Change log:
%
%   April 3, 2015 (NB):
%       Works with the new StoreDB class system.

    % Allow omission of the key, and even of storedb.
    if ~exist('key', 'var')
        if ~exist('storedb', 'var')
            storedb = StoreDB();
        end
        key = storedb.getNewKey();
    end

    if isfield(problem, 'egrad')
    %% Compute the Euclidean gradient using egrad.

        % Check whether this function wants to deal with storedb or not.
        switch nargin(problem.egrad)
            case 1
                % If it does not want to deal with the store structure,
                % then we do some caching of our own. There is a small
                % performance hit for this is some cases, but we expect
                % that this is most often the preferred choice.
                store = storedb.get(key);
                if ~isfield(store, 'egrad__')
                    store.egrad__ = problem.egrad(x);
                    storedb.set(store, key);
                end
                egrad = store.egrad__;
            case 2
                % Obtain, pass along, and save the store for x.
                % If the user deals with the store structure, then we don't
                % do any automatic caching: the user is in control.
                store = storedb.getWithShared(key);
                [egrad, store] = problem.egrad(x, store);
                storedb.setWithShared(store, key);
            case 3
                % Pass along the whole storedb (by reference), with key.
                % Same here: no automatic caching.
                egrad = problem.egrad(x, storedb, key);
            otherwise
                up = MException('manopt:getEuclideanGradient:badegrad', ...
                    'egrad should accept 1, 2 or 3 inputs.');
                throw(up);
        end

    else
    %% Abandon computing the Euclidean gradient

        up = MException('manopt:getEuclideanGradient:fail', ...
            ['The problem description is not explicit enough to ' ...
             'compute the Euclidean gradient of the cost.']);
        throw(up);

    end

end


%SETSCALE Set scale field (output scaling) in mapping
%
%    W = SETSCALE(W,SCALE)
%
% This sets the SCALE field in W. If W is affine, scaling is is directly
% performed in the weights in W.DATA and W.SCALE = 1.


function [datfield, dimord] = getdatfield(data)

% GETDATFIELD
%
% Use as
%   [datfield, dimord] = getdatfield(data)
% where the output arguments are cell-arrays.
%
% See also GETDIMORD, GETDIMSIZ

datfield  = fieldnames(data);
datfield  = datfield(:)'; % it should be a row-vector throughout the subsequent code

% these descriptive fields are cell-arrays and not treated as data
% the descriptive fields such as time and freq can be treated as data
datfield  = setdiff(datfield, {'label' 'labelcmb'});
datfield  = setdiff(datfield, ignorefields('selectdata'));

% find substructure fields
structfield = {};
for i=1:numel(datfield)
  if isstruct(data.(datfield{i}))
    structfield(end+1) = datfield(i);
  end
end
datfield  = setdiff(datfield, structfield);

% find homogenous transformation matrices, i.e. a 4x4 matrix that is named xxx2yyy
transformfield = {};
for i=1:numel(datfield)
  if ~isempty(regexp(datfield, '^[a-zA-Z]*2[a-zA-Z]*$', 'once')) && isequal(size(data.(datfield{i})), [4 4])
    transformfield(end+1) = datfield(i);
  end
end
datfield  = setdiff(datfield, transformfield);

xxxlabel  = datfield(~cellfun(@isempty, regexp(datfield, 'label$'))); % xxxlabel
datfield  = setdiff(datfield, xxxlabel);

xxxdimord = datfield(~cellfun(@isempty, regexp(datfield, 'dimord$'))); % xxxdimord
datfield  = setdiff(datfield, xxxdimord);

dimord = cell(size(datfield));
for i=1:length(datfield)
  dimord{i} = getdimord(data, datfield{i});
end


function printOptions(fid, expInfo)
%PRINTOPTIONS   Print problem options when they are exported.
%
% Calling sequence:
%   PRINTOPTIONS(FID, EXPINFO)
% where
%   FID:        ID of a file-writing stream.
%   EXPINFO:    Struct containing information for printing the problem.

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

% Extract info from the expInfo struct:
tol = expInfo.tol;
pdeflag = expInfo.pdeflag;
doplot = expInfo.doplot;
dohold = expInfo.dohold;
ylim1 = expInfo.ylim1;
ylim2 = expInfo.ylim2;
fixN = expInfo.fixN;

% Start with an empty struct for opts
opts = [];

% Option for tolerance
opts = [opts, '''Eps'', ', tol];

% Is PDEFLAG set?
if ( ~all(pdeflag) )
    opts = [opts, ', ''PDEflag'', ', 'pdeflag'];
end

% Options for plotting
if ( strcmpi(doplot, 'off') )
    opts = [opts, ', ''Plot'', ', '''off'''];
else
    if ( dohold )
        opts = [opts, ', ''HoldPlot'', ', '''on'''];
    end
    if ( ~isempty(ylim1) && ~isempty(ylim2) )
        opts = [opts, ', ''Ylim'', [', ylim1, ',', ylim2,']'];
    end
end

% Options for fixed N
if ( ~isempty(fixN) )
    N = str2double(fixN);
    opts = [opts, ',''N'',', N];
end

% Set up preferences

fprintf(fid, '\n%%%% Setup preferences for solving the problem.\n');
fprintf(fid, 'opts = pdeset');
if ( isempty(opts) )
    fprintf(fid, ';\n', opts);
else
    fprintf(fid, '(%s);\n', opts);
end

end


function regQAPlanC(planC, scanNumV, structNumV, viewV, marginS)

% function imgFilesC = regQAPlanC(planC, scanNumV, structNumV, viewV)
% Usage: outputs image file (s) with review of segmented regions between
% coregistered scans
% Inputs
% planC: CERR object
% scanNumV: list of scan numbers of coregistered scans for comparison, 1xN array
% structNumV: list of structure numbers for comparison. A new image will be
%                output for each struct
% viewV: 1x3 array, indicating how many slices in each view you want to see
% marginS: padding zoom around ROI view

if ischar(planC)
    if exist(planC,'file')
        disp('String filename of planC passed.');
        planC = loadPlanC(planC);
    else
        error('planC filename is not valid path');
    end
end

indexS = planC{end};

if ~exist('marginS','var')
    marginS = 20;
end

if nargin < 2
    scanNumV = 1;
end

scanC = {};

structureListC = {planC{indexS.structures}.structureName};

% get structure mask(s), add error handling for no mask
for i = 1:numel(structNumV)
    structIndex = structNumV(i);
    maskC{i} = getStrMask(structIndex,planC);
    structNameC{i} = structureListC{structIndex};
    cmapC{i} = [rand rand rand];
end

viewNameC = {'sagittal','coronal','axial'};

maskNet3M = zeros(size(maskC{1}));

for i = 1:numel(structNumV)
    mask3M = maskC{i};
    maskNet3M = maskNet3M + mask3M;
end

% get scans
Nscan = numel(scanNumV);
for i = 1:Nscan
    scanIndex = scanNumV(i);
    scanC{i} = getScanArray(scanIndex, planC);
    cmean{i} = mean(scanC{i}(find(maskNet3M)));
    cstd{i} = std(scanC{i}(find(maskNet3M)));
end

for k = 1:3 %views x-,y-,z-plane
    if viewV(k)~=0
        N = viewV(k);

        if k == 1
            for j = 1:numel(scanC)
                rscanC{j} = permute(scanC{j},[2 3 1]);
                rmaskC{j} = permute(maskC{j},[2 3 1]);
            end
            rmaskNet3M = permute(maskNet3M,[2 3 1]);
        elseif k == 2
            for j = 1:numel(scanC)
                rscanC{j} = permute(scanC{j},[3 1 2]);
                rmaskC{j} = permute(maskC{j},[3 1 2]);
            end
            rmaskNet3M = permute(maskNet3M,[3 1 2]);
        else
            rscanC = scanC;
            rmaskC= maskC;
            rmaskNet3M = maskNet3M;
        end

        idx = find(rmaskNet3M);
        [x,y,z] = ind2sub(size(rmaskNet3M),idx);
        minV = [min(x) min(y) min(z)];
        maxV = [max(x) max(y) max(z)];

        incr = floor((maxV(3) - minV(3))/(N + 1));
        if incr < 1
            sliceV = minV(3):maxV(3);
            N = numel(sliceV);
        else
            sliceV = minV(3) + incr*(1:N);
        end
        %get extents
        r1 = [minV(1) - marginS,maxV(1) + marginS];
        if r1(1) < 0
            r1(1) = 0;
        end
        if r1(2) > size(rmaskNet3M,1)
            r1(2) = size(rmaskNet3M,1);
        end
        r2 = [minV(2) - marginS,maxV(2) + marginS];
        if r2(1) < 0
            r2(1) = 0;
        end
        if r2(2) > size(rmaskNet3M,2)
            r2(2) = size(rmaskNet3M,2);
        end

        if N > 5
            ha = [];
            for o = 1:floor(N/5)
                figure;
                ha0 = tight_subplot(5,Nscan,[.01 .03],[.1 .01],[.01 .01]);
                ha = [ha; ha0];
            end
            figure;
            ha0 = tight_subplot(mod(N,5),Nscan,[.01 .03],[.1 .01],[.01 .01]);
            ha = [ha; ha0];
        else
            figure;
            ha = tight_subplot(N,Nscan,[.01 .03],[.1 .01],[.01 .01]);
        end

        for n = 1:N

            for j = 1:Nscan
                rscan3M = rscanC{j};
                slice2M = rscan3M(r1(1):r1(2),r2(1):r2(2),sliceV(n));
                rmaskNet2M = rmaskNet3M(r1(1):r1(2),r2(1):r2(2),sliceV(n));

%                 cmean = mean(slice2M(find(rmaskNet2M)));
%                 cstd = std(slice2M(find(rmaskNet2M)));

                %                 subplot(N,Nscan,(n-1)*Nscan + j); image       sc(slice2M);
                axes(ha((n-1)*Nscan + j)); imagesc(slice2M);
                axis equal; axis off; colormap(gray); caxis([cmean{j} - cstd{j},cmean{j}+cstd{j}]); hold on;

                for z = 1:numel(rmaskC)
                    rmask3M = rmaskC{z};
                    mask2M = rmask3M(r1(1):r1(2),r2(1):r2(2),sliceV(n));
                    [B,~,Nb,~] = bwboundaries(mask2M);
                    for b = 1:Nb
                        bd = B{b};
                        plot(bd(:,2), bd(:,1),'Color',cmapC{z},'LineWidth',2);
                    end
                end
            end
        end

    end
end


2     % problem
4     % grid parameter
1     % uniform/stretched/shishkin grid
1     % outflow boundary
0.005 % viscosity parameter
inf   % SUPG parameter (inf==>optimal)

%% Data file for test problem CD2


function code = getfourcc(fourcc)

code = [char(bitshift(fourcc,0,8)) char(bitshift(fourcc,-8,8)) char(bitshift(fourcc,-16,8)) char(bitshift(fourcc,-24,8))];

%   $Revision: 1.1.6.2 $  $Date: 2004/03/30 13:06:56 $
%   Copyright 1984-2003 The MathWorks, Inc.


classdef CachedCalculationResults
    %CACHEDCALCULATIONRESULTS Summary of this class goes here
    %   Detailed explanation goes here
    % Usage:
    %     cached_params = [];
    %     cached_params.Y = Y;
    %     cached_params.k = k;
    %     cached_file = '../../../../CachedResults/cached_nmf_adjacency_graph.mat';
    %     ccr = CachedCalculationResults(cached_file);
    %     A = ccr.GetMatchedResult(cached_params);
    %     if isempty(A)
    %         [A,~,~] = create_adjacency_graph(Y,'nn',k,1);
    %         if N*B > 1e6
    %             ccr.AddResult(cached_params,A);
    %         end
    %     end

    properties
        FileName
        MaxSignatureSize
        MaxEntries
    end

    methods
        function obj = CachedCalculationResults(file_name,max_param_size)
            if nargin < 2
                max_param_size = 1e5;
            end
            obj.FileName = file_name;
            obj.MaxSignatureSize = max_param_size;
            obj.MaxEntries = 50;
        end

        function AddResult(obj, params, result)
            [list_params,list_results] = LoadCachedResults(obj);
            if length(list_params) >= obj.MaxEntries
                list_params(1) = [];
                list_results(1) = [];
            end
            list_params = [list_params,{obj.GetSignature(params)}];
            list_results = [list_results,{result}];
            save(obj.FileName,'list_params','list_results','-v7.3');
        end

        function matched = GetMatchedResult(obj,params)
            [list_params,list_results] = LoadCachedResults(obj);
            signature = obj.GetSignature(params);

            matched = [];
            for i = 1:length(list_params)
                if isequal(list_params{i},signature)
                    matched = list_results{i};
                    break;
                end
            end

        end

        function [list_params,list_results] = LoadCachedResults(obj)
            if ~exist(obj.FileName,'file')
                list_params = {};
                list_results = {};
                save(obj.FileName,'list_params','list_results');
            end
            S = load(obj.FileName);
            list_params = S.list_params;
            list_results = S.list_results;
        end

        function new_params = GetSignature(obj,params)
            new_params = params;
            names = fieldnames(new_params);
            for i = 1:length(names)
                X = new_params.(names{i});
                x = X(:);
                if length(x) > obj.MaxSignatureSize
                    step = ceil(length(x) / obj.MaxSignatureSize);
                    x = x(1:step:end);
                end
                new_params.(names{i}) = x;
            end
        end

    end

end


function varargout = plotcoeffs(A, varargin)
%PLOTCOEFFS   PLOTCOEFFS for CHEBMATRIX objects.
%   PLOTCOEFFS(A) plots the Chebyshev coefficients CHEBMATRIX object A. If A
%   contains only CHEBFUN and DOUBLE objects, A is converted to a QUASIMATRIX,
%   and CHEBFUN/PLOTCOEFFS() is called. In this case PLOTCOEFFS(A, S) allows
%   various line types, plot symbols, and colors to be used, where S is a
%   character string. See CHEBFUN/PLOTCOEFFS() for further details.
%
%   If A contains inf x inf blocks, an error is thrown.
%
% See also CHEBFUN/PLOTCOEFFS.

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

% Deal with an empty input:
if ( isempty(A) )
    [varargout{1:nargout}] = plot([]);
    return
end

s = cellfun(@(b) min(size(b)), A.blocks);
isQuasi = all(isfinite(s(:)));

if ( ~isQuasi )
    % If A contains inf x inf blocks throw an error:
    error('CHEBFUN:CHEBMATRIX:plotcoeffs:notQuasi', ...
        'PLOTCOEFFS does not support CHEBMATRIX objects of size INFxINF.');
end

% If A contains only CHEBFUN or DOUBLE, convert it to a quasimatrix and call
% CHEBFUN/PLOTCOEFFS():
A.blocks = reshape(A.blocks, 1, numel(A.blocks));
A = quasimatrix(A.blocks);
[varargout{1:nargout}] = plotcoeffs(A, varargin{:});

end


function [bndry_lon,bndry_lat] = m_plotbndry(name,varargin)
% M_PLOTBNDRY plots text files of Lat,Lon for political boundaries.
% Text files (derived from the DCW) are obtained from
%   http://www.maproom.psu.edu/cgi-bin/ian/points/index.cgi
%
%     M_PLOTBNDRY(NAME) plots the state or country specified in the
%     string NAME, which may include a path name. The routine will
%     then a) search the specified path for a mat-file of that name
%          b) search the specified path for an ascii *2pts.txt file
%             of that name, and, if found convert it to a mat-file.
%          c) failing that, it will open a file dialog box.
%
%     M_PLOTBNDRY(NAME, ...line properties) will use the specified
%     line properties in drawing the boundary.
%
%     [LON,LAT]=M_PLOTBNDRY(...) returns vectors of the boundary
%     points.
%
% Note: If errors occur when a file is first plotted, check that
% the entire file was downloaded.  It should end with two consecutive
% END lines.

% Original Author: Michael W. Mann
%
% Changes: R. Pawlowicz 21/12/98 - changed interface to read from
%          given directory, allow output, allow various line
%          properties to be specified.
% 6/Nov/00 - eliminate returned stuff if ';' neglected (thx to D Byrne)
% 19/Mar/04 - .mat files not being created because of a bug found by James Connor.

% Set current projection to geographic
Currentmap=m_coord('set');
m_coord('geographic');

targetfile = [name,'2pts.mat']; %try to find binary file
targetpath = dir(targetfile);

if ( length(targetpath)~=0 ) %then load file.
   load(targetfile);
   m_line(bndry_lon,bndry_lat,'tag','m_plotbndry',varargin{:});

else %Can't find binary file, load and process text file.
   %  Create .mat file from data read.

   targetfile = [name,'2pts.txt'];
   targetpath = dir(targetfile);
   if ( length(targetpath)==0 ) %then
      [filename,pathname]=uigetfile('*2pts.txt',['Select ',targetfile,' file']);
      if ( filename == 0 ), error(['Could not find ',targetfile]), end
      targetpath = [pathname,filename];
   end %if
   [fid,message] = fopen(targetfile,'r');
   if ( fid < 0 ) %then
      fclose(fid);
      error(message);
   end %if

   namein = fgetl(fid);
   if ( ~strfind(lower(name),lower(namein)) ) %then
      fclose(fid);
      error(['File contains wrong state! ','Desired: ',name,' Found: ',namein]);
   end %if

   done = 0;
   polynum = 0;
   numpts = [];
   while ( ~done )
      %read in polygon index
      line = fgetl(fid);
      field = sscanf(line,'%3c');
      if ( strcmp(upper(field),'END') ) %then found EOF
         done = 1;
      else %start reading in polygon
         polynum = polynum + 1;
         polynumin = sscanf(line,'%u');
         if ( polynum ~= polynumin ) %then
            fclose(fid);
            error(['Didn''t find polynum ',num2str(polynum),...
                  ', found ',num2str(polynumin),' .']);
         end %if
         line = fgetl(fid); %skip polygon centroid
         line = fgetl(fid); %first point
         ptcount = 0;
         while ( ~strcmp(upper(line(1:3)),'END') )
            ptcount = ptcount + 1;
            line = fgetl(fid);
         end %while
         numpts = [numpts,ptcount];
      end %if
   end %while

   Npolygon = length(numpts);
   fclose(fid); %Close file.

   % Vectors for composite outline
   bndry_lat = zeros(1,sum(numpts)+Npolygon);
   bndry_lon = zeros(1,sum(numpts)+Npolygon);
   i1 = 0; %index to last filled entry in vectors

   fid = fopen(targetfile,'r'); %reopen file
   line = fgetl(fid); %ignore namefield

   for i = 1:Npolygon
      line = fgetl(fid); %ignore polygon index
      line = fgetl(fid); %ignore centroid lat,lon
      [poly,count] = fscanf(fid,'%g',[2,inf]); %read data
      line = fgetl(fid); %ignore END

      % Save data for reuse as .mat file
      i0 = i1 + 1;  i1 = i0 + numpts(i);
      bndry_lon(i0:i1) = [poly(1,:),NaN]; %add NaN to lift pen
      bndry_lat(i0:i1) = [poly(2,:),NaN]; %add NaN to lift pen

   end %for

   fclose(fid);

   m_line(bndry_lon,bndry_lat,'tag','m_plotbndry',varargin{:});
   nchar = length(targetfile);   % Bug fix thanks to James Connor
   matfile = [targetfile(1:(nchar-4)),'.mat'];
   save(matfile,'bndry_lat','bndry_lon');

end %if

m_coord(Currentmap.name);

if nargout==0
 clear bndry_lon bndry_lat
end


%==============================================================================
% This code is part of the Matlab-based toolbox
% FAIR - Flexible Algorithms for Image Registration.
% For details see
% - https://github.com/C4IR and
% - http://www.siam.org/books/fa06/
%==============================================================================
%
% KERNEL/DATA
%
% This folder provides the basis data (examples) that come with the toolbox
% and some convenient tools for handling the data;
% see also references at the end of the mfiles
%
% To get the data "X" (e.g. 2DHandData), conveniently run setup"X";
% e.g. setup2DHandData.
% For faster access, the generated data is saved in an automatically
% generated file in the temp folder and later simply re-used.
%
%------------------------------------------------------------------------------
%
% The following examples are available:
%
% 2D data:
%   2Dhands     -  hand xrays,                  see ref. [1] and setup2DHandData
%   2DHNSP      -  brain serial sectioning,     see ref. [2] and setup2DHNSPData
%   2DMRIs      -  MR slices from human brain,  see ref. [3] and setup2DMRIData
%   2DPETCT     -  PET-CT study,                see ref. [4] and setup2DPETCTdata
%   2DUS        -  US image of Vibe Heldmann,
%                  courtesy by Dr. Stefan Heldmnn, Fraunhofer MEVIS, Lübeck
%   2Ddisc2C    -  binary images of a disc and a C a la Gary Christensen,
%                  test case for large deformations, academic testcase
%   2DGaussian  -  Gaussian blobs, test-case for mass-preserving schemes,
%                  academic testcase
%
% 3D data:
%   3Dbrains    -  MRI data of a human brain,
%                  data courtesy Ron Kikinis, Brigham & Women's Hospital, Boston, USA
%   3Dknees     -  MRI data from a human knee,
%                  data courtesy Thomas Netsch, Philips Medical Solutions, Hamburg
%   3Dmice      -  PET data of a mouse heart,
%                  data courtesy European Institute for Molecular Imaging (EIMI),
%                  University of Muenster, Germany
%   3Dboxes     -  academical example with deformed binary boxes
%
% Tools (M-files)
%
%   setup2DhandData     - requires hands-T.jpg,     hands-R.jpg
%   setup2DHNSPData     - requires HNSP-T.jpg,      HNSP-R.jpg
%   setup2DMRIData      - requires MRIhead-T.jpg,   MRIhead-R.jpg
%   setup2DPETCTData    - requires PET-CT-CT.jpg,   PET-CT-PET.jpg
%   setup2DUSData       - requires US.jpg
%   setup2Ddisc2CData   - requires disc.jpg and c.jpg
%   setup2DGaussianData - requires Gauss-T.jpg, Gauss-r.jpg
%   setup3DbrainData    - requires brain3D.mat
%   setup3DkneeData     - requires createPhilipsKnees.mat
%   setup3DmouseData    - requires mice3D.mat
%   setup3DboxData      - academic, a box
%
%------------------------------------------------------------------------------
% More tools:
%   contents            -  this file
%   checkDataFile       -  in the first run, the data is saved and later simply
%                          loaded for faster access,
%                          this file handles the administration
%   jpgs2data           -  convenient tool to convert two jpgs files into the
%                          FAIR data structure
%   testData            -  tests this part of the toolbox
%
%------------------------------------------------------------------------------
% JPG files:
%   Gauss-R.jpg,           Gauss-T.jpg
%   HNSP-R.jpg             HNSP-T.jpg
%   MRIhead-R.jpg          MRIhead-T.jpg
%   PET-CT-CT.jpg          PET-CT-PET.jpg
%   c.jpg                  disc.jpg
%   hands-R.jpg            hands-T.jpg
%   US.jpg
%   EPIslice-R.jpg         EPIslice-T.jpg [5]
%
% MAT files:
%   brain3D.mat
%   knees3D.mat
%   mice3D.mat
%
%
% [5] 2D slices of MR images, Institute of Clinical Radiology, Univesity
%     Hospital Muenster, Germany.
%   phantom3D.mat
%     MR data of a hardware phantom,
% Institute for Clinical Radiology, University Hospital Muenster, Germany
% for data sources see the corresponding setup file
%
%==============================================================================

function debit = contents
if nargout == 0,
  help(mfilename);
  return;
end;

debit = {
  'contents.m'
  'checkDataFile.m'
  'jpgs2data.m'

  'setup2DGaussianData.m'
  'setup2DHNSPData.m'
  'setup2DMRIData.m'
  'setup2DPETCTData.m'
  'setup2DUSData.m'
  'setup2Ddisc2CData.m'
  'setup2DhandData.m'
  'setup3DboxData.m'
  'setup3DbrainData.m'
  'setup3DkneeData.m'
  'setup3DmouseData.m'

  'testData.m'

  'Gauss-R.jpg'
  'Gauss-T.jpg'
  'HNSP-R.jpg'
  'HNSP-T.jpg'
  'MRIhead-R.jpg'
  'MRIhead-T.jpg'
  'PET-CT-CT.jpg'
  'PET-CT-PET.jpg'
  'US.jpg'
  'c.jpg'
  'disc.jpg'
  'hands-R.jpg'
  'hands-T.jpg'
  'brain3D.mat'
  'EPIslice-R.jpg'
  'EPIslice-T.jpg'
  'knee3D.mat'
  'mice3D.mat'
  'phantom3D.mat'
  };
%==============================================================================


function test08 ( input_file_name )

%*****************************************************************************80
%
%% TEST08 tests STLA_READ and STLA_READ_FAST.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2007
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST08\n' );
  fprintf ( 1, '  Compare two routines with the same functionality.\n' );
  fprintf ( 1, '  One is designed to run faster than the other,\n' );
  fprintf ( 1, '  especially on large problems with thousands of faces.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  STLA_READ reads various data from an ASCII STL file.\n' );
  fprintf ( 1, '  STLA_READ_FAST reads data from an ASCII STL file.\n' );
  fprintf ( 1, '\n' );

  [ solid_num, node_num, face_num, text_num ] = stla_size_fast ( ...
    input_file_name );

  t1 = clock;

  [ node_xyz, face_node, face_normal ] = stla_read_fast ( ...
    input_file_name, node_num, face_num );

  t2 = clock;

  diff1 = etime ( t2, t1 );

  fprintf ( 1, '  STLA_READ_FAST read the file in %f seconds.\n', diff1 );

  [ solid_num, node_num, face_num, text_num ] = stla_size ( ...
    input_file_name );

  t3 = clock;

  [ node_xyz, face_node, face_normal ] = stla_read ( ...
    input_file_name, node_num, face_num );

  t4 = clock;

  diff2 = etime ( t4, t3 );

  fprintf ( 1, '  STLA_READ      read the file in %f seconds.\n', diff2 );

  stla_size_print ( input_file_name, solid_num, node_num, face_num, ...
    text_num );

  return
end


%CODEGENERATOR.GENMFUNFRICTION Generate M-function for joint friction
%
% cGen.genmfunfriction() generates a robot-specific M-function to compute
% joint friction.
%
% Notes::
% - Is called only if cGen has active flag genmfun
% - Access to generated function is provided via subclass of SerialLink
%   whose class definition is stored in cGen.robjpath.
%
% Author::
%  Joern Malzahn, (joern.malzahn@tu-dortmund.de)
%
% See also CodeGenerator.CodeGenerator, CodeGenerator.gengravload.

% Copyright (C) 2012-2014, by Joern Malzahn
%
% This file is part of The Robotics Toolbox for Matlab (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com
%
% The code generation module emerged during the work on a project funded by
% the German Research Foundation (DFG, BE1569/7-1). The authors gratefully
% acknowledge the financial support.

function [ F ] = genmfunfriction( CGen )

%% Does robot class exist?
if ~exist(fullfile(CGen.robjpath,[CGen.getrobfname,'.m']),'file')
    CGen.logmsg([datestr(now),'\tCreating ',CGen.getrobfname,' m-constructor ']);
    CGen.createmconstructor;
    CGen.logmsg('\t%s\n',' done!');
end

%% Generate m-function
CGen.logmsg([datestr(now),'\tGenerating joint friction m-function']);
symname = 'friction';
fname = fullfile(CGen.sympath,[symname,'.mat']);

if exist(fname,'file')
    tmpStruct = load(fname);
else
    error ('genmfunfriction:SymbolicsNotFound','Save symbolic expressions to disk first!')
end

funfilename = fullfile(CGen.robjpath,[symname,'.m']);
[~,qd] = CGen.rob.gencoords;

matlabFunction(tmpStruct.(symname),'file',funfilename,...              % generate function m-file
    'outputs', {'F'},...
    'vars', {'rob',[qd]});
hStruct = createHeaderStruct(CGen.rob,symname);                 % replace autogenerated function header
replaceheader(CGen,hStruct,funfilename);
CGen.logmsg('\t%s\n',' done!');

end

%% Definition of the header contents for each generated file
function hStruct = createHeaderStruct(rob,fname)
[~,hStruct.funName] = fileparts(fname);
hStruct.shortDescription = ['Joint friction for the ',rob.name,' arm.'];
hStruct.calls = {['F = ',hStruct.funName,'(rob,qd)'],...
    ['F = rob.',hStruct.funName,'(qd)']};
hStruct.detailedDescription = {['Given a full set of generalized joint velocities the function'],...
    'computes the friction forces/torques.'};
hStruct.inputs = { ['rob: robot object of ', rob.name, ' specific class'],...
                   ['qd:  ',int2str(rob.n),'-element vector of generalized'],...
                   '     velocities', ...
                   'Angles have to be given in radians!'};
hStruct.outputs = {['F:  [',int2str(rob.n),'x1] vector of joint friction forces/torques']};
hStruct.references = {'1) Robot Modeling and Control - Spong, Hutchinson, Vidyasagar',...
    '2) Modelling and Control of Robot Manipulators - Sciavicco, Siciliano',...
    '3) Introduction to Robotics, Mechanics and Control - Craig',...
    '4) Modeling, Identification & Control of Robots - Khalil & Dombre'};
hStruct.authors = {'This is an autogenerated function!',...
    'Code generator written by:',...
    'Joern Malzahn',...
    '2012 RST, Technische Universitaet Dortmund, Germany',...
     'http://www.rst.e-technik.tu-dortmund.de'};
hStruct.seeAlso = {'gravload'};
end


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

figure, plot(tout, control_results)
title('Joint positions')

figure,
plot(tout, joint1_error), hold
plot(tout, joint2_error)
title('Joint errors')

figure,
plot(tout, motor1_current), hold
plot(tout, motor2_current)
title('Motor current')

figure,
plot(tout, motor1_speed_rpm), hold
plot(tout, motor2_speed_rpm)
title('Motor speed rpm')


for i = 1 : length(missed)
    if ~isempty(missed{i})
        I = imread(fullfile(param.dataset_root, val2db.list{i}));
        hold on
        r = missed{i};
        r=[r(:,[1,2]) r(:,3)-r(:,1) r(:,4)-r(:,2)];
        I = insertShape(I, 'rectangle', r);
        imshow(I)
        waitforbuttonpress;
    end
end


function title = p15_title ( )

%*****************************************************************************80
%
%% P15_TITLE returns a title for problem 15.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 April 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Per-Olof Persson and Gilbert Strang,
%    A Simple Mesh Generator in MATLAB,
%    SIAM Review,
%    Volume 46, Number 2, June 2004, pages 329-345.
%
%  Parameters:
%
%    Output, string TITLE, a title for the problem.
%
  title = '#15: Sangbum Kim''s forward step.';

  return
end


function out = get(f, prop, simpLevel)
%GET   GET method for the CHEBFUN class.
%   P = GET(F, PROP) returns the property P specified in the string PROP from
%   the CHEBFUN F. Valid entries for the string PROP are:
%       'domain'         - The domain of definition of F.
%       'ends'
%       'funs'           - The piecewise smooth components of F.
%       'vscale'         - Vertical scale of F.
%       'vscale-local'   - Local vertical scales of F.
%       'hscale'         - Horizontal scale of F.
%       'ishappy'        - Is F happy?
%       'lval'           - Value(s) of F at left-hand side of domain.
%       'rval'           - Value(s) of F at right-hand side of domain.
%       'lval-local'     - Value(s) of F's FUNs at left sides of their domains.
%       'rval-local'     - Value(s) of F's FUNs at right sides of their domains.
%       'exps'           - Exponents in a CHEBFUN, a two vector.
%       'exponents'
%       'deltas'         - Return the locations and magnitude of delta functions
%                          as a single matrix with the first row corresponding
%                          to the locations of the delta functions, and the
%                          magnitudes appended below the first row.
%       'deltas-local'   - Delta function information for each FUN of each
%                          column of F.
%   The following are also supported for backward compatibility, and really only
%   make sense when the CHEBFUN is represented by a CHEBTECH-type object. Note
%   that in these cases a cell is always returned, even if the CHEBFUN has only
%   a single FUN.
%       'points'         - The Chebyshev grid used to represent F.
%       'values'         - The values of the CHEBFUN on the grid above.
%       'coeffs'         - The corresponding Chebyshev coefficients.
%
%   When requesting properties like 'vscale-local' that vary with each FUN of
%   each column of F, P = GET(F, PROP, SIMPLEVEL) can be used to control the
%   extent to which the form of the returned data is "simplified."  Valid
%   values for SIMPLEVEL are:
%
%     0 - No simplification.  The output is always stored in a cell array of
%         cell arrays.  P is a cell array with length equal to the number of
%         columns of F.  P{J} is a cell array of length equal to the number of
%         FUNs in column J of F which stores the properties for the FUNs in
%         that column.  P{J}{K} is the value of the property for FUN K in column
%         J of F.
%
%     1 - Simplify output to 2D cell array, if possible.  If F has the same
%         number of FUNs in each column, then instead of returning a cell array
%         of cell arrays, return a 2D cell array instead.  P{K, J} is the
%         value of the property for FUN K in column J of F.  If F does not
%         have the same number of FUNs in each column, then a cell array of
%         cell arrays is returned, as described above.
%
%     2 - Maximum simplification.  If F has only one column and only one FUN, P
%         is the value of the requested property.  If F has multiple columns
%         and multiple FUNs, with the same number of FUNs in each column,
%         then this first simplifies to a 2D cell array as in SIMPLEVEL = 1
%         and then tries to convert the result to a numeric matrix if possible.
%         For this conversion to succeed, the following must be true:
%
%           1.  The property must have a numeric value.
%
%           2.  The property must be such that one of the following two
%               conditions holds:
%
%                 A.  If F has N columns, then the property also has N columns,
%                     and the values in column K of the property are associated
%                     with column K of F.
%
%                 B.  The property consists of a single column, the values of
%                     which are associated with _all_ columns of F.
%
%           3.  If each column has multiple FUNs, the property values for each
%               FUN must all have only one.  If each column has only one FUN,
%               the property values must all have the same number of rows.
%
%         If the result cannot be converted to a numeric matrix, the 2D cell
%         array is returned.  If F does not have the same number of funs in
%         each column, then the result is as in SIMPLEVEL = 0.
%
%   SIMPLEVEL = 0 and SIMPLEVEL = 1 are intended as a convenience to
%   programmers calling GET from their code, as the more uniform output of GET
%   makes it easier to handle without requiring additional program logic.
%   SIMPLEVEL = 2 is generally easier to use when working interactively, as the
%   output does not need to be unwrapped in many common cases.
%
%   The default value of SIMPLEVEL is 2.

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

% Try to simplify the output as much as possible by default.
if ( nargin < 3 )
    simpLevel = 2;
end

switch prop
    case {'domain', 'ends'}
        out = domain(f);
    case 'vscale'
        out = vscale(f);
    case 'hscale'
        out = hscale(f);
    case 'ishappy'
        out = ishappy(f);
    case fieldnames(f)
        out = cell(1, numel(f));
        for k = 1:1:numel(f)
            out{k} = f(k).(prop);
        end
        if ( numel(out) == 1 )
            out = out{1};
        end
    case 'lval'
        dom = domain(f);
        out = feval(f, dom(1));
    case 'rval'
        dom = domain(f);
        out = feval(f, dom(end));
    case 'lval-local'
        out = getSimpleNumericLocalProp(f, 'lval', simpLevel);
    case 'rval-local'
        out = getSimpleNumericLocalProp(f, 'rval', simpLevel);
    case 'vscale-local'
        out = getSimpleNumericLocalProp(f, 'vscale', simpLevel);
    case {'values', 'coeffs', 'points'}
        out = getSimpleNumericLocalProp(f, prop, simpLevel);
    case {'exps', 'exponents'}
        out = getArbitraryLocalProp(f, 'exponents', simpLevel);

        % If we want to simplify exponents to numeric matrix, we have to do it
        % manually:  the fact that exponents are stored as a row vector instead
        % of a column vector means that we have to use getArbitraryLocalProp
        % instead of getSimpleNumericLocalProp, and the former doesn't know how
        % to do this simplification.
        if ( (simpLevel > 1) && iscell(out) && (size(out, 2) == 1) )
            out = cell2mat(out);
        end
    case 'deltas'
        out = getArbitraryLocalProp(f, 'deltas', 0);
        for k = 1:numColumns(f)
            colDeltaData = out{k}.';

            % Before applying horzcat, make sure each cell has
            % the same number of row:
            maxRows = max(cellfun(@(A) size(A, 1), colDeltaData));
            for j = 1:length(colDeltaData)
                nRows = size(colDeltaData{j}, 1);
                nCols = size(colDeltaData{j}, 2);
                if ( nRows < maxRows )
                    colDeltaData{j} = [colDeltaData{j}; zeros(maxRows-nRows, nCols)];
                end
            end
            colDeltaData = horzcat(colDeltaData{:});

            if ( ~isempty(colDeltaData) )
                [mag, loc] = deltafun.mergeColumns(colDeltaData(2:end, :), ...
                    colDeltaData(1, :));
                out{k} = [loc ; mag];
            else
                out{k} = [];
            end
        end
        if ( numel(out) == 1 )
            out = out{1};
        end
    case 'deltas-local'
        out = getArbitraryLocalProp(f, 'deltas', simpLevel);
    case 'imps'
        warning('CHEBFUN:CHEBFUN:get:imps', ...
            '''imps'' property is deprecated.  Use ''deltas'' instead.');
        out = get(f, 'deltas');
    otherwise
        error('CHEBFUN:CHEBFUN:get:badProp', ...
            '''%s'' is not a recognized CHEBFUN property name.', prop);
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function out = getSimpleNumericLocalProp(f, prop, simpLevel)
%GETSIMPLENUMERICLOCALPROP   Get simple numeric FUN properties.
%   OUT = GETSIMPLENUMERICLOCALPROP(F, PROP, SIMPLEVEL) retrieves the values
%   of the "simple numeric local" property PROP from each of the FUNs of F and
%   assembles them in some sensible way.  A property is a "simple numeric
%   local" property if (1) it is numeric, (2) it is a FUN property, and (3)
%   either one of the following conditions holds:
%
%     A.  If F has N columns, then the property also has N columns, and the
%     values in column K of the property are associated with column K of F.
%
%     B.  The property consists of a single column, the values of which are
%     associated with _all_ columns of F.
%
%   SIMPLEVEL controls the extent to which the function will try to represent
%   the property in a simpler form:
%
%     SIMPLEVEL = 0.  Cell array of cell arrays.  out{j}{k} gives the value of
%     the property for FUN j of column k.
%
%     SIMPLEVEL = 1.  2D cell array.  The output can be simplified to this if
%     all columns of F have the same number of FUNs.  out{j, k} gives the value
%     of the property for FUN j of column k.
%
%     SIMPLEVEL = 2.  Numeric matrix.  If the output can be simplified to a 2D
%     cell array, we can sometimes convert it further into a numeric matrix if
%     the result can be unambiguously interpreted.  See
%     CANCONVERT2DCELLARRAYTONUMERIC.
%
%   The reason this funciton exists is that simple numeric local properties can
%   be extracted from array-valued CHEBFUNs without needing to convert them to
%   quasimatrices first, which can potentially save a lot in computational
%   overhead costs.

% Get properties for each FUN and assemble into cell arrays.
if ( numel(f) == 1 )  % Single column or array-valued CHEBFUN.
    out = getSimpleNumericLocalPropArrayValued(f, prop);
else                  % Quasimatrix / array of CHEBFUNs.
    out = getArbitraryLocalPropQuasimatrix(f, prop);
end

% Try to convert from a cell array of cell arrays to a 2D cell array.
if ( (simpLevel > 0) && canConvertCellOfCellsTo2DCellArray(out) )
    out = horzcat(out{:});
    % Try to go one step further and convert to a numeric matrix.
    if ( (simpLevel > 1) && canConvert2DCellArrayToNumeric(out) )
        out = cell2mat(out);
    end
end

if ( f(1).isTransposed )
    out = out.';
end

end

function out = getArbitraryLocalProp(f, prop, simpLevel)
%GETSIMPLENUMERICLOCALPROP   Get simple numeric FUN properties.
%   OUT = GETSIMPLENUMERICLOCALPROP(F, PROP, DOSIMPLIFY) retrieves the values
%   of the property PROP from each of the FUNs of F and %   assembles them in
%   some sensible way.
%
%   SIMPLEVEL controls the extent to which the function will try to represent
%   the property in a simpler form:
%
%     SIMPLEVEL = 0.  Cell array of cell arrays.  out{j}{k} gives the value of
%     the property for FUN j of column k.
%
%     SIMPLEVEL = 1.  2D cell array.  The output can be simplified to this if
%     all columns of F have the same number of FUNs.  out{j, k} gives the value
%     of the property for FUN j of column k.
%
%     SIMPLEVEL = 2.  Single cell contents.  If the output can be simplified to
%     a 2D cell array, with only one cell, we just return the contents of that
%     cell.

% The only way to correctly support access to general properties of
% array-valued CHEBFUNs is to convert them to quasimatrices first.  (Example:
% If f is an array-valued CHEBFUN with n columns and has a tech with a property
% that is a 1 x n row vector, we don't know if each element in that row vector
% corresponds to a different column or if the whole vector needs to be a
% property of each column.  Only the tech's MAT2CELL knows how to split the
% property appropriately amongst the columns.)
if ( (numel(f) == 1) && (numColumns(f) > 1) )
    out = getArbitraryLocalProp(cheb2quasi(f), prop);
    return
end

out = getArbitraryLocalPropQuasimatrix(f, prop);

% Try to convert from a cell array of cell arrays to a 2D cell array.
if ( (simpLevel > 0) && canConvertCellOfCellsTo2DCellArray(out) )
    out = horzcat(out{:});

    % If our 2D cell array has only one cell (i.e., if f has only one column,
    % and that column has only fun), return the contents of that cell.
    if ( (simpLevel > 1) && (numel(out) == 1) )
        out = out{1};
    end
end

if ( f(1).isTransposed )
    out = out.';
end

end

function out = getSimpleNumericLocalPropArrayValued(f, prop)
%GETSIMPLENUMERICLOCALPROPARRAYVALUED   Get simple numeric FUN properties from
%   an array-valued CHEBFUN.
%
%   OUT = GETSIMPLENUMERICLOCALPROPARRAYVALUED(F, PROP) returns a cell array of
%   cell arrays OUT such that OUT{J}{K} is the value of the simple numeric
%   local property PROP (see GETSIMPLENUMERICLOCALPROP) for FUN J of column K
%   of the array-valued CHEBFUN F.

nCols = numColumns(f);
nFuns = numel(f.funs);

tmp = cell(nFuns, nCols);
for j = 1:nFuns
    funPropVal = get(f.funs{j}, prop);
    [funPropValRows, funPropValCols] = size(funPropVal);

    if ( funPropValCols == 1 )
        funPropVal = repmat(funPropVal, 1, nCols);
    elseif ( funPropValCols ~= nCols )
        error('CHEBFUN:CHEBFUN:get:getSimpleNumericLocalPropArrayValued:notSimple', 'Property is not simple.');
    end

    tmp(j, :) = mat2cell(funPropVal, funPropValRows, ones(nCols, 1));
end

out = cell(1, nCols);
for k = 1:nCols
    out{k} = vertcat(tmp(:, k));
end

end

function out = getArbitraryLocalPropQuasimatrix(f, prop)
%GETARBITRARYLOCALPROPQUASIMATRIX   Get FUN properties from a quasimatrix.
%   OUT = GETARBITRARYLOCALPROPQUASIAMTRIX(F, PROP) returns a cell array of
%   cell arrays OUT such that OUT{J}{K} is the value of the local property PROP
%   for FUN J of column K of the quasimatrix F.

nCols = numColumns(f);
out = cell(1, nCols);
for k = 1:nCols
    nFuns = numel(f(k).funs);
    out{k} = cell(nFuns, 1);
    for j = 1:nFuns
        out{k}{j} = get(f(k).funs{j}, prop);
    end
end

end

function canConvert = canConvertCellOfCellsTo2DCellArray(out)
%CANCONVERTCELLOFCELLSTO2DCELLARRAY   Self-explanatory.
%   CANCONVERT = CANCONVERTCELLOFCELLTO2DCELLARRAY(OUT) function treturns TRUE
%   of the cell array of cell arrays OUT can be converted to a 2D cell array
%   (i.e., if OUT{J} has the same number of columns for each J) and FALSE
%   otherwise.
    canConvert = ~any(diff(cellfun(@(C) size(C, 1), out)));
end

function canConvert = canConvert2DCellArrayToNumeric(out)
%CANCONVERT2DCELLARRAYTONUMERIC   Self-explanatory.
%   CANCONVERT = CANCONVERT2DCELLARRAYTONUMERIC(OUT) function treturns TRUE of
%   the 2D cell array OUT can be converted to a numeric matrix.

[nFuns, nCols] = size(out);

% If each column has multiple FUNS, the property values for each FUN must
% all have only one row.  If each column has only one FUN, the property
% values must all have the same number of rows.
if ( nFuns > 1 )
    nRowsNeeded = 1;
else
    nRowsNeeded = size(out{1}, 1);
end

for ( j = 1:1:nFuns )
    for ( k = 1:1:nCols )
        if ( size(out{j, k}, 1) ~= nRowsNeeded )
            canConvert = false;
            return;
        end
    end
end

canConvert = true;

end


function [rotations,flipLR] = getFlatRotations(view)
%
%  [rotations,flipLR] = getFlatRotations(view)
%
% Gets rotation field from FLAT
% Returns a [2x1]  pair of rotations if sucessful.
% Returns [0 0] if no such field present.
% Also returns a pair of flags indicating whether a L/R flip happens.

if (~strcmp(view.viewType,'Flat'))
    error('getFlatRotation called for non-flat view');
end

if (~isfield(view,'rotateImageDegrees'))
    rotations=[0 0];
else
    rotations=view.rotateImageDegrees;
end

if (~isfield(view,'flipLR'))
    flipLR = [0 0]; % If this flag is set, coordinates are flipped L/R : The rotation matrix becomes -c s; s c
    return;
else
    flipLR = view.flipLR;
end

return


function submitWeb(partId)
%SUBMITWEB Generates a base64 encoded string for web-based submissions
%   SUBMITWEB() will generate a base64 encoded string so that you can submit your
%   solutions via a web form

  fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ...
          homework_id());
  if ~exist('partId', 'var') || isempty(partId)
    partId = promptPart();
  end

  % Check valid partId
  partNames = validParts();
  if ~isValidPartId(partId)
    fprintf('!! Invalid homework part selected.\n');
    fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames));
    fprintf('!! Submission Cancelled\n');
    return
  end

  [login] = loginPrompt();
  if isempty(login)
    fprintf('!! Submission Cancelled\n');
    return
  end

  [result] = submitSolution(login, partId, output(partId), ...
                            source(partId));
  result = base64encode(result);

  fprintf('\nSave as submission file [submit_ex%s_part%d.txt]: ', ...
          homework_id(), partId);
  saveAsFile = input('', 's');
  if (isempty(saveAsFile))
    saveAsFile = sprintf('submit_ex%s_part%d.txt', homework_id(), partId);
  end

  fid = fopen(saveAsFile, 'w');
  if (fid)
    fwrite(fid, result);
    fclose(fid);
    fprintf('\nSaved your solutions to %s.\n\n', saveAsFile);
    fprintf(['You can now submit your solutions through the web \n' ...
             'form in the programming exercises. Select the corresponding \n' ...
             'programming exercise to access the form.\n']);

  else
    fprintf('Unable to save to %s\n\n', saveAsFile);
    fprintf(['You can create a submission file by saving the \n' ...
             'following text in a file: (press enter to continue)\n\n']);
    pause;
    fprintf(result);
  end

end

% ================== CONFIGURABLES FOR EACH HOMEWORK ==================

function id = homework_id()
  id = '8';
end

function [partNames] = validParts()
  partNames = { 'Estimate Gaussian Parameters', ...
                'Select Threshold' ...
                'Collaborative Filtering Cost', ...
                'Collaborative Filtering Gradient', ...
                'Regularized Cost', ...
                'Regularized Gradient' ...
                };
end

function srcs = sources()
  % Separated by part
  srcs = { { 'estimateGaussian.m' }, ...
           { 'selectThreshold.m' }, ...
           { 'cofiCostFunc.m' }, ...
           { 'cofiCostFunc.m' }, ...
           { 'cofiCostFunc.m' }, ...
           { 'cofiCostFunc.m' }, ...
           };
end

function out = output(partId)
  % Random Test Cases
  n_u = 3; n_m = 4; n = 5;
  X = reshape(sin(1:n_m*n), n_m, n);
  Theta = reshape(cos(1:n_u*n), n_u, n);
  Y = reshape(sin(1:2:2*n_m*n_u), n_m, n_u);
  R = Y > 0.5;
  pval = [abs(Y(:)) ; 0.001; 1];
  yval = [R(:) ; 1; 0];
  params = [X(:); Theta(:)];
  if partId == 1
    [mu sigma2] = estimateGaussian(X);
    out = sprintf('%0.5f ', [mu(:); sigma2(:)]);
  elseif partId == 2
    [bestEpsilon bestF1] = selectThreshold(yval, pval);
    out = sprintf('%0.5f ', [bestEpsilon(:); bestF1(:)]);
  elseif partId == 3
    [J] = cofiCostFunc(params, Y, R, n_u, n_m, ...
                       n, 0);
    out = sprintf('%0.5f ', J(:));
  elseif partId == 4
    [J, grad] = cofiCostFunc(params, Y, R, n_u, n_m, ...
                             n, 0);
    out = sprintf('%0.5f ', grad(:));
  elseif partId == 5
    [J] = cofiCostFunc(params, Y, R, n_u, n_m, ...
                       n, 1.5);
    out = sprintf('%0.5f ', J(:));
  elseif partId == 6
    [J, grad] = cofiCostFunc(params, Y, R, n_u, n_m, ...
                             n, 1.5);
    out = sprintf('%0.5f ', grad(:));
  end
end

% ========================= SUBMIT HELPERS =========================

function src = source(partId)
  src = '';
  src_files = sources();
  if partId <= numel(src_files)
      flist = src_files{partId};
      for i = 1:numel(flist)
          fid = fopen(flist{i});
          while ~feof(fid)
            line = fgets(fid);
            src = [src line];
          end
          fclose(fid);
          src = [src '||||||||'];
      end
  end
end

function ret = isValidPartId(partId)
  partNames = validParts();
  ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames));
end

function partId = promptPart()
  fprintf('== Select which part(s) to submit:\n', ...
          homework_id());
  partNames = validParts();
  srcFiles = sources();
  for i = 1:numel(partNames)
    fprintf('==   %d) %s [', i, partNames{i});
    fprintf(' %s ', srcFiles{i}{:});
    fprintf(']\n');
  end
  fprintf('\nEnter your choice [1-%d]: ', ...
          numel(partNames));
  selPart = input('', 's');
  partId = str2num(selPart);
  if ~isValidPartId(partId)
    partId = -1;
  end
end

function [result, str] = submitSolution(email, part, output, source)

  result = ['a:5:{' ...
            p_s('homework') p_s64(homework_id()) ...
            p_s('part') p_s64(part) ...
            p_s('email') p_s64(email) ...
            p_s('output') p_s64(output) ...
            p_s('source') p_s64(source) ...
            '}'];

end

function s = p_s(str)
   s = ['s:' num2str(numel(str)) ':"' str '";'];
end

function s = p_s64(str)
   str = base64encode(str, '');
   s = ['s:' num2str(numel(str)) ':"' str '";'];
end

% =========================== LOGIN HELPERS ===========================

function [login] = loginPrompt()
  % Prompt for password
  [login] = basicPrompt();
end

function [login] = basicPrompt()
  login = input('Login (Email address): ', 's');
end

% =========================== Base64 Encoder ============================
% Thanks to Peter John Acklam
%

function y = base64encode(x, eol)
%BASE64ENCODE Perform base64 encoding on a string.
%
%   BASE64ENCODE(STR, EOL) encode the given string STR.  EOL is the line ending
%   sequence to use; it is optional and defaults to '\n' (ASCII decimal 10).
%   The returned encoded string is broken into lines of no more than 76
%   characters each, and each line will end with EOL unless it is empty.  Let
%   EOL be empty if you do not want the encoded string broken into lines.
%
%   STR and EOL don't have to be strings (i.e., char arrays).  The only
%   requirement is that they are vectors containing values in the range 0-255.
%
%   This function may be used to encode strings into the Base64 encoding
%   specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions).  The
%   Base64 encoding is designed to represent arbitrary sequences of octets in a
%   form that need not be humanly readable.  A 65-character subset
%   ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be represented per
%   printable character.
%
%   Examples
%   --------
%
%   If you want to encode a large file, you should encode it in chunks that are
%   a multiple of 57 bytes.  This ensures that the base64 lines line up and
%   that you do not end up with padding in the middle.  57 bytes of data fills
%   one complete base64 line (76 == 57*4/3):
%
%   If ifid and ofid are two file identifiers opened for reading and writing,
%   respectively, then you can base64 encode the data with
%
%      while ~feof(ifid)
%         fwrite(ofid, base64encode(fread(ifid, 60*57)));
%      end
%
%   or, if you have enough memory,
%
%      fwrite(ofid, base64encode(fread(ifid)));
%
%   See also BASE64DECODE.

%   Author:      Peter John Acklam
%   Time-stamp:  2004-02-03 21:36:56 +0100
%   E-mail:      pjacklam@online.no
%   URL:         http://home.online.no/~pjacklam

   if isnumeric(x)
      x = num2str(x);
   end

   % make sure we have the EOL value
   if nargin < 2
      eol = sprintf('\n');
   else
      if sum(size(eol) > 1) > 1
         error('EOL must be a vector.');
      end
      if any(eol(:) > 255)
         error('EOL can not contain values larger than 255.');
      end
   end

   if sum(size(x) > 1) > 1
      error('STR must be a vector.');
   end

   x   = uint8(x);
   eol = uint8(eol);

   ndbytes = length(x);                 % number of decoded bytes
   nchunks = ceil(ndbytes / 3);         % number of chunks/groups
   nebytes = 4 * nchunks;               % number of encoded bytes

   % add padding if necessary, to make the length of x a multiple of 3
   if rem(ndbytes, 3)
      x(end+1 : 3*nchunks) = 0;
   end

   x = reshape(x, [3, nchunks]);        % reshape the data
   y = repmat(uint8(0), 4, nchunks);    % for the encoded data

   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % Split up every 3 bytes into 4 pieces
   %
   %    aaaaaabb bbbbcccc ccdddddd
   %
   % to form
   %
   %    00aaaaaa 00bbbbbb 00cccccc 00dddddd
   %
   y(1,:) = bitshift(x(1,:), -2);                  % 6 highest bits of x(1,:)

   y(2,:) = bitshift(bitand(x(1,:), 3), 4);        % 2 lowest bits of x(1,:)
   y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4));   % 4 highest bits of x(2,:)

   y(3,:) = bitshift(bitand(x(2,:), 15), 2);       % 4 lowest bits of x(2,:)
   y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6));   % 2 highest bits of x(3,:)

   y(4,:) = bitand(x(3,:), 63);                    % 6 lowest bits of x(3,:)

   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % Now perform the following mapping
   %
   %   0  - 25  ->  A-Z
   %   26 - 51  ->  a-z
   %   52 - 61  ->  0-9
   %   62       ->  +
   %   63       ->  /
   %
   % We could use a mapping vector like
   %
   %   ['A':'Z', 'a':'z', '0':'9', '+/']
   %
   % but that would require an index vector of class double.
   %
   z = repmat(uint8(0), size(y));
   i =           y <= 25;  z(i) = 'A'      + double(y(i));
   i = 26 <= y & y <= 51;  z(i) = 'a' - 26 + double(y(i));
   i = 52 <= y & y <= 61;  z(i) = '0' - 52 + double(y(i));
   i =           y == 62;  z(i) = '+';
   i =           y == 63;  z(i) = '/';
   y = z;

   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % Add padding if necessary.
   %
   npbytes = 3 * nchunks - ndbytes;     % number of padding bytes
   if npbytes
      y(end-npbytes+1 : end) = '=';     % '=' is used for padding
   end

   if isempty(eol)

      % reshape to a row vector
      y = reshape(y, [1, nebytes]);

   else

      nlines = ceil(nebytes / 76);      % number of lines
      neolbytes = length(eol);          % number of bytes in eol string

      % pad data so it becomes a multiple of 76 elements
      y = [y(:) ; zeros(76 * nlines - numel(y), 1)];
      y(nebytes + 1 : 76 * nlines) = 0;
      y = reshape(y, 76, nlines);

      % insert eol strings
      eol = eol(:);
      y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines));

      % remove padding, but keep the last eol string
      m = nebytes + neolbytes * (nlines - 1);
      n = (76+neolbytes)*nlines - neolbytes;
      y(m+1 : n) = '';

      % extract and reshape to row vector
      y = reshape(y, 1, m+neolbytes);

   end

   % output is a character array
   y = char(y);

end


function path_unix = dos2unix(path_dos)

for i=1:length(path_dos)
    if strcmp( path_dos(i) , '\' );
        path_unix(i) = '/';
    else
        path_unix(i) = path_dos(i);
    end
end
path_unix = regexprep(path_unix, '//', '/');
path_unix = regexprep(path_unix, '//', '/');


function masks = char2img( strings, h, pad )
% Convert ascii text to a binary image using pre-computed templates.
%
% Input strings can only contain standard characters (ascii character
% 32-126). First time char2img() is ever called with a given height h,
% txt2img() is used to create a template for each ascii character. All
% subsequent calls to to char2img() with the given height are very fast as
% the pre-computed templates are used and no display/screen capture is
% needed.
%
% USAGE
%  masks = char2img( strings, h, [pad] )
%
% INPUTS
%  strings  - {1xn} text string or cell array of text strings to convert
%  h        - font height in pixels
%  pad      - [0] amount of extra padding between chars
%
% OUTPUTS
%  masks    - {1xn} binary image masks of height h for each string
%
% EXAMPLE
%  mask=char2img('hello world',50); im(mask{1})
%  mask=char2img(num2str(pi),35); im(mask{1})
%
% See also TXT2IMG
%
% Piotr's Computer Vision Matlab Toolbox      Version 2.65
% Copyright 2014 Piotr Dollar.  [pdollar-at-gmail.com]
% Licensed under the Simplified BSD License [see external/bsd.txt]

% load or create character templates (or simply store persistently)
persistent chars h0
if(isempty(h0) || h0~=h)
  pth=fileparts(mfilename('fullpath'));
  fName=sprintf('%s/private/char2img_h%03i.mat',pth,h); h0=h;
  if(exist(fName,'file')), load(fName); else
    chars=char(32:126); chars=num2cell(chars);
    chars=txt2img(chars,h,{'Interpreter','none'});
    save(fName,'chars');
  end
end
% add padding to chars
if(nargin<3 || isempty(pad)), pad=0; end
charsPad=chars; if(pad), pad=ones(h,pad,'uint8');
  for i=1:length(chars), charsPad{i}=[pad chars{i} pad]; end; end
% create actual string using templates
if(~iscell(strings)), strings={strings}; end
n=length(strings); masks=cell(1,n);
for s=1:n, str=strings{s};
  str(str<32 | str>126)=32; str=uint8(str-31);
  M=[charsPad{str}]; masks{s}=M;
end


function cmp = cstrcmp(a, b)
%CSTRCMP  Compare two character arrays according to ASCII dictionary order in C
%style.
%
%   INPUTS:
%
%   -|a|, |b|: character arrays, not necessarily of the same length
%
%   OUTPUT:
%
%   -|cmp|: integer holding the result of the comparison. Equal to 0 when the
%    two inputs are equal, positive when |a| is greater than |b|, and negative
%    when |a| is less than |b|.

% Force the arrays to equal length.
x = char({a;b});

% Subtract one from the other.
d = x(1,:) - x(2,:);

if any(d)
    cmp = d(find(d, 1));
else
    cmp = 0;
end

end


% USERDATA  User data for SLAMTB.
%   Edit this script to enter the information you need for SLAM. Variable
%   names and comments should make this file easy to understand. Follow
%   these guidelines:
%
%   * Specify site and estimation details for the current run in ExpOpt.
%   * Specify sampling time and start and end frames in Tim.
%   * Use as many robots and sensors as you wish with Robot{} and Sensor{}.
%   * Assign sensors to robots via Sensor{i}.robot.
%   * Use field Sensor{i}.distortion for radial distortion parameters if
%   desired.
%   * Use the field Opt.map.numLmk and .lmkSize to specify the maximum
%   number of landmarks that the SLAM map must support.
%   * Use Opt.init.initType to select the type of landmarks to use. Try
%   with one in this list:
%       'idpPnt', 'hmgPnt', 'ahmPnt', 'plkLin', 'ahmLin'.
%   * Use World.points and World.segments to create artificial worlds of
%   points or segments. Check functions THICKCLOISTER and HOUSE.
%
%   See further comments within the file for more detailed information.
%
%   NOTE: You can have multiple copies of this file with different names to
%   store different simulation conditions. Just modify the call in SLAMTB
%   to point to the particular 'USERDATA' file you want.
%
%   See also SLAMTB, EULERANGLES, THICKCLOISTER, HOUSE, USERDATAPNT,
%   USERDATALIN.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

% Time variables
%   - sampling time, first and last frames
Time = struct(...
  'dt',                   .1,...          % sampling time, seconds
  'firstFrame',           1,...           % first frame #
  'lastFrame',            800);           % last frame #

% Simulated world
%   - Simulation landmark sets, playground dimensions
World = struct(...
  'points',           thickCloister(-6,6,-6,6,1,7),... % 3d point landmarks - see THICKCLOISTER.
  'segments',         []);  % 3D segments - see HOUSE.

% Robot things with their controls
%   - each robot's type and initial configuration, and controls.
%   - motion models (add new model strings if you need more):
%       'constVel'    6D Constant velocity model
%       'odometry'    6D Odometry model
%       'inertial'    6D IMU-based model
%   - See EULERANGLES for orientations specifications.
Robot{1} = struct(...                  % ODOMETRY EXAMPLE
  'id',                 1,...           % robot identifier
  'name',               'Dala',...      % robot name
  'type',               'atrv',...      % type of robot
  'motion',             'odometry',...  % motion model
  'position',           [0;-5;0],...     % robot position in map
  'orientationDegrees', [0;0;0],...     % orientation, in degrees, [roll; pitch; yaw].
  'positionStd',        [0;0;0],...     % position error, std
  'orientationStd',     [0;0;0],...     % orient. error, std, in degrees
  'dx',                 [.08;0;0],...     % position increment
  'daDegrees',          [0;0;.9],...     % angle increment, degrees
  'dxStd',              0.005*[1;1;1],...  % odo linear error std
  'daStd',              0.05*[1;1;1]);      % odo ang error std, degrees

% Robot{2} = struct(...                  % ODOMETRY EXAMPLE
%   'id',                 2,...           % robot identifier
%   'name',               'Dala',...      % robot name
%   'type',               'atrv',...      % type of robot
%   'motion',             'odometry',...  % motion model
%   'position',           [0;5;0],...     % robot position in map
%   'orientationDegrees', [0;0;180],...     % orientation, in degrees, [roll; pitch; yaw].
%   'positionStd',        [0;0;0],...     % position error, std
%   'orientationStd',     [0;0;0],...     % orient. error, std, in degrees
%   'dx',                 [.08;0;0],...     % position increment
%   'daDegrees',          [0;0;.9],...     % angle increment, degrees
%   'dxStd',              0.005*[1;1;1],...  % odo linear error std
%   'daStd',              0.05*[1;1;1]);      % odo ang error std, degrees

% Robot{3} = struct(...                  % CONSTANT VELOCITY EXAMPLE
%   'id',                 3,...           % robot identifier
%   'name',               'Dala',...      % robot name
%   'type',               'atrv',...      % type of robot
%   'motion',             'constVel',...  % motion model
%   'position',           [1;0;0],...     % robot position in map
%   'orientationDegrees', [0;0;45],...    % orientation, in degrees, [roll; pitch; yaw].
%   'positionStd',        [0;0;0],...     % position error, std
%   'orientationStd',     [0;0;0],...     % orient. error, std, degrees
%   'velocity',           [1;0;0],...     % lin. velocity
%   'angularVelDegrees',  [0;0;10],...    % ang. velocity, in degrees
%   'velStd',             [0;0;0],...     % lin. vel. error, std
%   'angVelStd',          [0;0;0],...     % ang. vel. error, std, degrees
%   'dv',                 [0;0;0],...     % veolcity increment
%   'dwDegrees',          [0;0;0],...     % ang. vel. increment, degrees
%   'dvStd',              [0;0;0],...     % vel perturbation std
%   'dwStd',              [0;0;1]);       % ang vel pert. std, degrees

% Sensor things
%   - each sensor's type and parameters, noise, non-measurable prior.
%   - Sensor types (add new type strings if you need more):
%       'pinHole'   Pin-hole camera
%   - See EULERANGLES for orientations specifications.
Sensor{1} = struct(...
  'id',                 1,...           % sensor identifier
  'name',               'Micropix',...  % sensor name
  'type',               'pinHole',...   % type of sensor
  'robot',              1,...           % robot where it is mounted
  'position',           [0;0;.6],...    % position in robot
  'orientationDegrees', [-90;0;-90],... % orientation in robot, [roll; pitch; yaw]
  'positionStd',        [0;0;0],...     % position error std
  'orientationStd',     [0;0;0],...     % orient. error std
  'imageSize',          [640;480],...   % image size
  'pixErrorStd',        1.0,...         % pixel error std
  'intrinsic',          [320;240;320;320],... % intrinsic params [u0 v0 au av]
  'distortion',         [-0.3;0.1],...          % distortion params
  'frameInMap',         false,...       % add sensor frame in slam map?
  'imGrid',               struct(...      % grid for Active Search
    'numCells',         [8;6],...         % number of H and V grid cells
    'skipOuter',        true));           % skip outer cells for initialization?

% Sensor{2} = struct(...
%   'id',                 2,...           % sensor identifier
%   'name',               'Micropix',...      % sensor name
%   'type',               'pinHole',...   % type of sensor
%   'robot',              2,...           % robot where it is mounted
%   'position',           [0;-0.25;.6],...     % position in robot
%   'orientationDegrees', [-90;0;-90],...      % orientation in robot, [roll; pitch; yaw]
%   'positionStd',        [0;0;0],...     % position error std
%   'orientationStd',     [1.5;1.5;1.5],...     % orient. error std
%   'imageSize',          [640;480],...   % image size
%   'pixErrorStd',        1.0,...         % pixel error std
%   'intrinsic',          [320;240;320;320],... % intrinsic params
%   'distortion',         [],...          % distortion params
%   'frameInMap',         true,...         % add sensor frame in slam map?
%   'imGrid',               struct(...      % grid for Active Search
%     'numCells',         [8;6],...         % number of H and V grid cells
%     'skipOuter',        true));           % skip outer cells for initialization?

% Sensor{3} = struct(...
%   'id',                 1,...           % sensor identifier
%   'name',               'Micropix',...  % sensor name
%   'type',               'pinHole',...   % type of sensor
%   'robot',              2,...           % robot where it is mounted
%   'position',           [0;.25;.6],...    % position in robot
%   'orientationDegrees', [-90;0;-90],... % orientation in robot, [roll; pitch; yaw]
%   'positionStd',        [0;0;0],...     % position error std
%   'orientationStd',     [0;0;0],...     % orient. error std
%   'imageSize',          [640;480],...   % image size
%   'pixErrorStd',        1.0,...         % pixel error std
%   'intrinsic',          [320;240;320;320],... % intrinsic params [u0 v0 au av]
%   'distortion',         [-0.3;0.1],...          % distortion params
%   'frameInMap',         false,...       % add sensor frame in slam map?
%   'imGrid',               struct(...      % grid for Active Search
%     'numCells',         [8;6],...         % number of H and V grid cells
%     'skipOuter',        true));           % skip outer cells for initialization?

% Omnidirectional camera model -> MegaPixel Fish Eye lens as example (FoV is ~190 deg )
% k           = [668 438 1 0 0]';
% invProjDist = [4.473e+2 -0.000e+0 -1.068e-3 1.184e-6 -1.856e-9]';
% projDist    = [6.447e+2 -3.410e+2 -2.901e+1 -5.770e+1 1.849e+1 5.415e+0 5.065e+1 -5.614e+1 1.591e+1 0 0]';
% Sensor{1} = struct(...
%   'id',                 1,...           % sensor identifier
%   'name',               'FrontCam',...  % sensor name
%   'type',               'omniCam',...   % type of sensor
%   'robot',              1,...           % robot where it is mounted
%   'position',           [0.2;0;1.2],... % position in robot
%   'orientationDegrees', [-120;0;-90],...% orientation in robot, [roll; pitch; yaw].
%   'positionStd',        [0;0;0],...     % position error std
%   'orientationStd',     [0;0;0],...     % orient. error std
%   'imageSize',          [1280;800],...  % image size
%   'pixErrorStd',        1.0,...         % pixel error std
%   'intrinsic',          k,...           % intrinsic params: [xc yc c d e]';
%   'distortion',         projDist,...    % distortion params -> polynom for projection to cam sensor
%   'invDistortion',      invProjDist,... % distortion params -> polynom for inv proj from cam sensor
%   'frameInMap',         false,...       % add sensor frame in slam map?
%   'imGrid',             struct(...      % grid for Active Search
%     'numCells',         [8;6],...       % number of H and V grid cells
%     'skipOuter',        true));         % skip outer cells for initialization?

% Estimation options
Opt = struct(...
  'map',              struct(...    % options for the map
    'type',           'ekf',...      % type of map {'ekf','graph'}
    'numLmks',        73,...         % number of 3d landmarks
    'lmkSize',        6),...          % Size of landmark state
  'correct',          struct(...    % options for lmk correction
    'reprojectLmks',  true,...       % reproject lmks after active search?
    'reparametrize',  true,...       % reparametrize lmk?
    'nUpdates',       10,...         % max simultaneus updates
    'MD2th',          9,...          % Threshold on Mahalanobis distance squared
    'linTestIdp',     0.1,...        % threshold on IDP linearity test
    'lines',          struct(...     % options for line corrections
      'innType',      'ortDst',...    % innovation type for lines
      'extPolicy',    false,...       % line extending policy ?
      'extSwitch',    10)),...        % extension policy switch point in pixels
  'init',             struct(...    % Options for initialization
    'nbrInits',       [5 1],...      % number of inits [firstFrame, otherFrames]
    'initType',       'idpPnt',...   % Type of lmk to use for init
    'idpPnt',         struct(...     % options for lmk initialization
      'nonObsMean',   .01,...         % mean of non obs
      'nonObsStd',    .5),...         % std of non obs
    'plkLin',         struct(...     % opt. for Plucker and anchored Plucker lines init
      'nonObsMean',   [.1;0],...      % mean of non obs
      'nonObsStd',    [.25;1])),...   % std of non obs
  'obs',              struct(...    % Observation options
    'lines',          struct(...     % lines options
      'minLength',    20)));          % minimum segment length

% Simulation options
%   - random
SimOpt = struct(...
  'random',           struct(...      % random generator options
    'newSeed',        true,...         % select new random seed?
    'fixedSeed',      208948,...            % random seed for non-random runs
    'seed',           []),...          % current seed
  'obs',              Opt.obs);       % Observation options

% Figure options
%   - view, projection, video, ellipses.
%   - figure projections - mapProj:
%       'persp'     Perspective
%       'ortho'     Orthographic
%   - 3D figure views - mapView - see MAPOBSERVER.
%       [a,e,f]     Custom azimuth/elevation/FOV vector. Distance automatic
%       [a,e,f,d]   custom az/el/fov/distance vector.
%   - 3D figure predefined views (edit mapObserver.m to create/edit views):
%       'top'       Top view
%       'side'      Side view
%       'view'      Generic view
%       'normal'    Normal view
%   - objects colors - two options for color specification:
%       'rgbcmykw'  1-char predifined Matlab colors
%       [r g b]     RGB color vector. [0 0 0] is black, [1 1 1] is white.
FigOpt = struct(...
  'renderer',       'zbuffer',...    % renderer
  'rendPeriod',     1,...           % frames to skip for faster processing
  'createVideo',    false,...       % create video sequences?
  'map',            struct(...      % map figure options
    'size',         [320 240],...   % map figure size
    'lims',         struct(...      % playground limits
      'xMin',            -10,...
      'xMax',             10,...
      'yMin',            -10,...
      'yMax',             10,...
      'zMin',            -10,...
      'zMax',             10),...
    'proj',         'persp',...     % projection of the 3d figure
    'view',         'view',...      % viewpoint of the 3d figure [30 45 40 20]
    'orbit',        [0 0],...       % Azimuth and Elevation orbit angle increments - use to animate figure
    'showSimLmk',   true,...        % show simulated landmarks?
    'showEllip',    false,...        % show ellipsoids?
    'colors',       struct(...      % map figure colors
      'border',     [1 1 1],...      %   [r g b]
      'axes',       [0 0 0],...      % with:
      'bckgnd',     [1 1 1],...      %   [0 0 0] black
      'simLmk',     .3*[1 1 1],...   %   [1 1 1] white
      'defPnt',     struct(...       % euclidean point colors
        'mean',     'b',...           % mean dot
        'ellip',    [.7 .7 1]),...    % ellipsoid
      'othPnt',     struct(...       % other point colors
        'mean',     'r',...           % mean dot
        'ellip',    [1 .7 .7]),...    % ellipsoid
      'defLin',     struct(...       % Plucker line colors
        'mean',     [0 .8 0],...      % mean line
        'ellip',    [.6 1 .6]),...    % ellipsoid
      'othLin',     struct(...       % Plucker line colors
        'mean',     [.8 0 0],...      % mean line
        'ellip',    [1 .6 .6]),...    % ellipsoid
      'simu',       'b',...          %   or 'r', 'b', etc.
      'est',        'g',...          % estimated robots and sensors
      'ground',     [.8 .8 .8],...   % simulated robots and sensors
      'label',      [.0 .5 0])),...  % landmark ID labels
  'sensor',         struct(...      % sensor figures options
    'size',         [320 240],...    % sensor figure size
    'showEllip',    false,...        % show ellipses?
    'colors',       struct(...       % Sensor figure colors:
      'border',     .8*[1 1 1],...    %
      'axes',       [0 0 0],...       %
      'bckgnd',     [1 1 1],...       %
      'raw',        .3*[1 1 1],...    %
      'defPnt',     struct(...       % Default point colors
        'updated',  'c',...           % updated
        'predicted','b'),...          % predicted
      'othPnt',     struct(...       % other point colors
        'updated',  'r',...           % updated
        'predicted','m'),...          % predicted
      'defLin',     struct(...       % Default line colors
        'meas',     'b',...           % measurement
        'mean',     'g',...           % mean line
        'ellip',    'y'),...          % ellipsoid
      'othLin',     struct(...       % other line colors
        'meas',     'b',...           % measurement
        'mean',     'm',...           % mean line
        'ellip',    'r'),...          % ellipsoid
      'label',      [.5 .5 .5])));    %

% Experiment options
%   - site name, series gathered, estimation run number
ExpOpt = struct(...
  'root',         '~/SLAM/',...         % root directory
  'site',         'simu',...            % Name of the site
  'dataRun',      1,...                 % Run # on this site
  'estimateRun',  1,...                 % slam run for data and site
  'lmkTypes',     Opt.init.initType,... % types of landmarks used
  'sensingType',  'mono',...            % sensing mode
  'mappingType',  'single');            % mapping mode

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   SLAMTB 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 SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function varargout=gaussmix(varargin)
%
% For calling details please see v_gaussmix.m
%
% This dummy routine is included for backward compatibility only
% and will be removed in a future release of voicebox. Please use
% v_gaussmix.m in future and/or update with v_voicebox_update.m
%
%      Copyright (C) Mike Brookes 2018
%      Version: $Id: gaussmix.m 10863 2018-09-21 15:39:23Z dmb $
%
if nargout
    varargout=cell(1,nargout);
    [varargout{:}]=v_gaussmix(varargin{:});
else
    v_gaussmix(varargin{:});
end


classdef MimCoordinateSystem
    % MimCoordinateSystem. An enumeration used to specify the coordinate system used when
    %     importing or exporting coordinates
    %
    % Different imaging programs use different coordinate systems. Therefore,
    % if you import or export image coordinates from/to another imaging program,
    % you need to tell MIM what origin to use, otherwise the coordinates will
    % not match.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD MIM Toolkit. https://github.com/tomdoel
    %     Author: Tom Doel, 2013.  www.tomdoel.com
    %     Distributed under the MIT licence. Please see website for details.
    %

    enumeration
        PTK                % Coordinates in mm relatve to the top-left corner of the image volume
        Dicom              % Coordinates in mm relative to the scanner origin
        DicomUntranslated  % Origin in the centre of the first voxel of the image
    end
end