function r = mtimes(a,b)
%MTIMES       Taylor multiplication  a * b   (same as  a .* b )
%

% written  05/21/09     S.M. Rump
%

  r = a.*b;


function varargout=ann2rr(varargin)
%
% [RR,tms]=ann2rr(recordName,annotator,N,N0,consecutiveOnly)
%
%    Wrapper to WFDB ANN2RR:
%         http://www.physionet.org/physiotools/wag/ann2rr-1.htm
%
%    Reads a WFDB record and Annotation file to return:
%
%
% RR
%       Nx1 vector of integers representing the duration of the RR
%       interval in samples.
%
% tms
%       Nx1 vector of integers representing the begining of the RR
%       interval in samples.
%
% Required Parameters:
%
% recorName
%       String specifying the name of the record in the WFDB path or
%       in the current directory.
%
% annotator  -
%       String specifying the name of the annotation file in the WFDB path or
%       in the current directory.
%
% Optional Parameters are:
%
% N
%       A 1x1 integer specifying the sample number at which to stop reading the
%       record file (default read all = N).
% N0
%       A 1x1 integer specifying the sample number at which to start reading the
%       annotion file (default 1 = begining of the record).
%
% consecutiveOnly
%       A 1x1 boolean. If true, prints intervals between consecutive valid
%       annotaions only (default =true).
%
%
% Written by Ikaro Silva, 2013
% Last Modified: January, 16, 2013
% Version 1.1
%
% Since 0.0.1
% %Example
%[rr,tm]=ann2rr('challenge/2013/set-a/a01','fqrs');

%endOfHelp

[javaWfdbExec,config]=getWfdbClass('ann2rr');

%Set default pararamter values
inputs={'recordName','annotator','N','N0','consecutiveOnly'};
outputs={'data(:,2)','data(:,1)'};
N=[];
N0=1;
consecutiveOnly=1;
for n=1:nargin
    if(~isempty(varargin{n}))
        eval([inputs{n} '=varargin{n};']);
    end
end

N0=num2str(N0-1); %-1 is necessary because WFDB is 0 based indexed.
wfdb_argument={'-r',recordName,'-a',annotator,'-f',['s' N0]};

if(~isempty(N))
    wfdb_argument{end+1}='-t';
    %-1 is necessary because WFDB is 0 based indexed.
    wfdb_argument{end+1}=['s' num2str(N-1)];
end

if(consecutiveOnly)
    wfdb_argument{end+1}='-c';
end
wfdb_argument{end+1}='-V';

data=javaWfdbExec.execToDoubleArray(wfdb_argument);
data=wfdbjava2mat(data);
for n=1:nargout
    eval(['varargout{n}=' outputs{n} ';']);
end


function edgeBoxesSweeps()
% Parameter sweeps for Edges Boxes object proposals.
%
% Running the parameter sweeps requires altering internal flags.
% The sweeps are not well documented, use at your own discretion.
%
% Structured Edge Detection Toolbox      Version 3.0
% Copyright 2014 P. Dollar and L. Zitnick.  [pdollar-at-microsoft.com]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the MSR-LA Full Rights License [see license.txt]

% define parameter sweeps
rt = 'D:\code\research\edges\';
expNms = {'alpha','beta','minScore','edgeMinMag','edgeMergeThr',...
  'clusterMinMag','maxAspectRatio','minBoxArea','gamma','kappa'};
expNms=expNms(1:end); opts=createExp(rt,expNms); maxn=inf;

% run training and testing jobs
jobs = createJobs(rt,opts,maxn);
tic, for i=1:length(jobs), edgeBoxes(jobs{i}{:}); end; toc

% plot all results
for e=1:length(expNms)
  eval={'data',boxesData('split','val'),'names',{opts{e}.name},...
    'resDir',[rt 'boxes/sweeps/'],'maxn',maxn,'fName',expNms{e}};
  boxesEval(eval{:},'thrs',.7);
  boxesEval(eval{:},'thrs',.5:.05:1,'cnts',1000);
end

end

function jobs = createJobs( rt, opts, maxn )
% create jobs
M='models/forest/modelBsds'; M=load(M); M=M.model; M.opts.nThreads=1;
data=boxesData('split','val'); fs=data.imgs(1:min(end,maxn));
opts=[opts{:}]; N=length(opts); jobs=cell(1,N); D=zeros(1,N);
for e=1:N, opts(e).name=[rt 'boxes/sweeps/' opts(e).name '-val.mat']; end
for e=1:N, D(e)=exist(opts(e).name,'file')==2; jobs{e}={fs,M,opts(e)}; end
[~,K]=unique({opts.name},'stable'); D=D(K); jobs=jobs(K); jobs=jobs(~D);
fprintf('nJobs = %i\n',length(jobs));
end

function opts = createExp( rt, expNm )

% if expNm is a cell, call recursively and return
if( iscell(expNm) )
  N=length(expNm); opts=cell(1,N);
  for e=1:N, opts{e}=createExp(rt,expNm{e}); end; return;
end

% setup opts
opts=edgeBoxes(); opts.minScore=0;
N=100; optsDefault=opts; opts=opts(ones(1,N));
switch expNm
  case 'alpha'
    vs=45:5:75; N=length(vs);
    for e=1:N, opts(e).alpha=vs(e)/100; end
  case 'beta'
    vs=60:5:90; N=length(vs);
    for e=1:N, opts(e).beta=vs(e)/100; end
  case 'minScore'
    vs=[0 5 10 25 50 100]; N=length(vs);
    for e=1:N, opts(e).minScore=vs(e)/1000; end
  case 'edgeMinMag'
    vs=[0 50 100 200 400]; N=length(vs);
    for e=1:N, opts(e).edgeMinMag=vs(e)/1000; end
  case 'edgeMergeThr'
    vs=[25 50 100 200 400]; N=length(vs);
    for e=1:N, opts(e).edgeMergeThr=vs(e)/100; end
  case 'clusterMinMag'
    vs=[0 50 100 200 400]; N=length(vs);
    for e=1:N, opts(e).clusterMinMag=vs(e)/100; end
  case 'maxAspectRatio'
    vs=1:5; N=length(vs);
    for e=1:N, opts(e).maxAspectRatio=vs(e); end
  case 'minBoxArea'
    vs=[100 250 500 1000 2500 5000]; N=length(vs);
    for e=1:N, opts(e).minBoxArea=vs(e); end
  case 'gamma'
    vs=[25 50 100 200 400 10000]; N=length(vs);
    for e=1:N, opts(e).gamma=vs(e)/100; end
  case 'kappa'
    vs=50:25:200; N=length(vs);
    for e=1:N, opts(e).kappa=vs(e)/100; end
  otherwise, error('invalid exp: %s',expNm);
end

% produce final set of opts and find default opts
O=1:N; opts=opts(O); d=0;
for e=1:N, if(isequal(optsDefault,opts(e))), d=e; break; end; end
if(d==0), disp(expNm); assert(false); end; opts(d).name='Default';
for e=1:N, if(e~=d), opts(e).name=[expNm int2str2(vs(e),5)]; end; end

end


function newval = i2e_data(mpc, val, oldval, ordering, dim)
%I2E_DATA   Converts data from internal to external indexing.
%
%   VAL = I2E_DATA(MPC, VAL, OLDVAL, ORDERING)
%   VAL = I2E_DATA(MPC, VAL, OLDVAL, ORDERING, DIM)
%
%   For a case struct using internal indexing, this function can be
%   used to convert other data structures as well by passing in 3 or 4
%   extra parameters in addition to the case struct. If the value passed
%   in the 2nd argument (VAL) is a column vector or cell array, it will
%   be converted according to the ordering specified by the 4th argument
%   (ORDERING, described below). If VAL is an n-dimensional matrix or
%   cell array, then the optional 5th argument (DIM, default = 1) can be
%   used to specify which dimension to reorder. The 3rd argument (OLDVAL)
%   is used to initialize the return value before converting VAL to
%   external indexing. In particular, any data corresponding to off-line
%   gens or branches or isolated buses or any connected gens or branches
%   will be taken from OLDVAL, with VAL supplying the rest of the
%   returned data.
%
%   The ORDERING argument is used to indicate whether the data
%   corresponds to bus-, gen- or branch-ordered data. It can be one
%   of the following three strings: 'bus', 'gen' or 'branch'. For
%   data structures with multiple blocks of data, ordered by bus,
%   gen or branch, they can be converted with a single call by
%   specifying ORDERING as a cell array of strings.
%
%   Any extra elements, rows, columns, etc. beyond those indicated
%   in ORDERING, are not disturbed.
%
%   Examples:
%       A_ext = i2e_data(mpc, A_int, A_orig, {'bus','bus','gen','gen'}, 2);
%
%       Converts an A matrix for user-supplied OPF constraints from
%       internal to external ordering, where the columns of the A
%       matrix correspond to bus voltage angles, then voltage
%       magnitudes, then generator real power injections and finally
%       generator reactive power injections.
%
%       gencost_ext = i2e_data(mpc, gencost_int, gencost_orig, {'gen','gen'}, 1);
%
%       Converts a GENCOST matrix that has both real and reactive power
%       costs (in rows 1--ng and ng+1--2*ng, respectively).
%
%   See also E2I_DATA, I2E_FIELD, INT2EXT.

%   MATPOWER
%   Copyright (c) 2009-2016, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

if ~isfield(mpc, 'order')
    error('i2e_data: mpc does not have the ''order'' field required for conversion back to external numbering.');
end
o = mpc.order;
if o.state ~= 'i'
    error('i2e_data: mpc does not appear to be in internal order');
end
if nargin < 5
    dim = 1;
end
if ischar(ordering)         %% single set
    if strcmp(ordering, 'gen')
        v = get_reorder(val, o.(ordering).e2i, dim);
    else
        v = val;
    end
    newval = set_reorder(oldval, v, o.(ordering).status.on, dim);
else                        %% multiple sets
    be = 0;  %% base, external indexing
    bi = 0;  %% base, internal indexing
    for k = 1:length(ordering)
        ne = size(o.ext.(ordering{k}), 1);
        ni = size(mpc.(ordering{k}), 1);
        v = get_reorder(val, bi+(1:ni), dim);
        oldv = get_reorder(oldval, be+(1:ne), dim);
        new_v{k} = i2e_data(mpc, v, oldv, ordering{k}, dim);
        be = be + ne;
        bi = bi + ni;
    end
    ni = size(val, dim);
    if ni > bi              %% the rest
        v = get_reorder(val, bi+1:ni, dim);
        new_v{length(new_v)+1} = v;
    end
    newval = cat(dim, new_v{:});
end


function value = p05_autonomous ( )

%*****************************************************************************80
%
%% P05_AUTONOMOUS reports whether problem P05 is autonomous.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 February 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer VALUE, is 1 if the equation is autonomous.
%
  value = 0;

  return
end


function [lb, ub] = bounds(var_struct, bounds)

lb_var = ocl.Variable.create(var_struct, -inf);
ub_var = ocl.Variable.create(var_struct, inf);

for k=1:length(bounds.data)

  d = bounds.data{k};
  id = d.id;
  lower = d.lower;
  upper = d.upper;

  lb_var.get(id).set(lower);
  ub_var.get(id).set(upper);

end

lb = lb_var.value;
ub = ub_var.value;


function xyz = readVelodyne(filename)

fid = fopen(filename,'rb');
if fid == -1
  error('%s does not exist', filename);
end
velo = uint8(fread(fid,[32 inf],'uint8'));  % 32 /18
xyz = velo(1:12,:);
xyz = xyz(:);
xyz = typecast(xyz, 'single');
xyz = reshape(xyz, 3, []);
xyz(4,:) = 1;

fclose(fid);


function out = dimCheck(f, g, ~)
%DIMCHECK   Check dimension compatability of two CHEBFUN objects.
%   In MATLAB 2016a and below DIMCHECK(F, G) returns:
%       1    if numColumns(F) == numColumns(G)
%     error  otherwise.
%
%   In MATLAB 2016b and above DIMCHECK(F, G) returns:
%       1    if numColumns(F) == numColumns(G)
%      -1    if numColumns(F) == 1 or numColumns(G) == 1
%     error  otherwise.
%
%   DIMCHECK(F, G, 1) will return 0 rather than throw a dimension error.
%
% See also NUMCOLUMNS, SIZE.

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

nf = numColumns(f);
ng = numColumns(g);

% Check dimensions:
if ( nf == ng )
    out = 1;
elseif ( nf == 1 || ( ng == 1 ) )
    out = -1;
else
    out = 0;
end

% Adjust for MATLAB version if out = -1:
if ( (out == -1 ) && verLessThan('matlab', '9.1') )
   out = 0;
end

if ( out == 0 && nargin == 2 )
    % Throw an error if requested (as the caller):
    ME = MException('CHEBFUN:CHEBFUN:dimCheck:dim', ...
        'Matrix dimensions must agree.');
    throwAsCaller(ME)
end

end


% display a matrix in a format of %0.mf
function outStrMat = mat2strf(inNumMat,dispFmt)
[nrow,ncol] = size(inNumMat);
outStrMat = '[';
for i=1:nrow
    for j=1:ncol
        if j~=ncol
            outStrMat = [outStrMat,sprintf(dispFmt,inNumMat(i,j)),','];
        else
            if nrow~=1
                outStrMat = [outStrMat,sprintf(dispFmt,inNumMat(i,j)),';'];
            else
                outStrMat = [outStrMat,sprintf(dispFmt,inNumMat(i,j))];
            end
        end
    end
end
outStrMat = [outStrMat,']'];
end


function printtp(S)
%PRINTTP Print LTI models of a TP model
%	PRINTTP(S)
%
%	S - core tensor of a TP model

n = size(S);
LTI = shiftdim(S, length(n)-2)


function pred = RunInference (factors)
% This function performs inference for a Markov network specified as a list
% of factors.
%
% Input:
%   factors: An array of struct factors, each containing 'var', 'card', and
%     'val' fields.
%
% Output:
%   pred: An array of predictions for every variable. In particular,
%     pred(i) is the predicted value for variable numbered i (as determined
%     by the 'var' fields in the input factors).
%
% Copyright (C) Daphne Koller, Stanford University, 2012

binaries = {'.\inference\doinference.exe', ...
            './inference/doinference-mac', ...
            './inference/doinference-linux'};

kFactorsFilename = 'factors.fg';
kStderrFilename = 'inf.log';
kInfBinary = binaries{[ispc ismac isunix]}; % NB: need ismac first so that if ismac and isunix are both 1, then mac is chosen
kInferenceType = 'map'; % choices are 'map' or 'pd'

factorsString = SerializeFactorsFg (factors);

fd = fopen(kFactorsFilename, 'wt');
fprintf (fd, '%s', factorsString);
fclose(fd);

if (isunix && ~ismac)
  command = [kInfBinary ' ' kFactorsFilename ' ' kInferenceType];
else
  command = [kInfBinary ' ' kFactorsFilename ' ' kInferenceType ' 2> ' kStderrFilename];
end

[retVal, output] = system(command);

if (retVal ~= 0)
    error('The doinference command failed. Look at the file %s to diagnose the cause', kStderrFilename);
end

pred = ParseOutput(output);

end

function pred = ParseOutput(output)

lines = strread(output, '%s', 'delimiter', sprintf('\n'));
lines(strcmp(lines, '')) = [];

numVars = str2double(lines{1});

if (numVars ~= length(lines) - 1)
    error('Error parsing output: %s', output);
end

pred = zeros(numVars, 1);
for i = 2:(numVars + 1)
    line = str2num(lines{i}); %#ok
    pred(i-1) = line(end);
end

end


% plotdata() - plot concatenated multichannel data epochs in two-column format
%
% Usage:   >> plotdata(data)
%          >> plotdata(data,frames)
%          >> plotdata(data,frames,limits,title,channames,colors,rtitle,ydir)
%
% Necessary input:
%   data       = data consisting of consecutive epochs of (chans,frames)
%
% Optional inputs:
%   frames     = time frames/points per epoch {default: 0 -> data length}
%  [limits]    = [xmin xmax ymin ymax]  (x's in ms)
%                {default|0 (or both y's 0) -> use data limits)
%  'title'     = plot title {default|0 -> none}
%  'channames' = channel location file or structure (see readlocs())
%                {default|0 -> channel numbers}
%  'colors'    = file of color codes, 3 chars per line
%                ( '.' = space) {default|0 -> default color order}
%  'rtitle'    = right-side plot title {default|0 -> none}
%   ydir       = y-axis polarity (1 -> pos-up; -1 -> neg-up)
%                {default|0 -> set from default YDIR in 'icadefs.m'}
%
% Authors: Scott Makeig, Arnaud Delorme, Tzyy-Ping Jung,
%          SCCN/INC/UCSD, La Jolla, 05-01-96
%
% See also: plottopo(), timtopo(), envtopo(), headplot(), compmap(), eegmovie()

% Copyright (C) 05-01-96 Scott Makeig, Arnaud Delorme & Tzyy-Ping Jung,
% SCCN/INC/UCSD, scott@sccn.ucsd.edu
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

% 5-1-96 from showerps.m  -sm from showerp.m -tpj
% 5-3-96 added default channel numbering, frames & title -sm
% 5-17-96 added nargin tests below -sm
% 5-21-96 added right titles -sm
% 6-29-96 removed Postscript file query -sm
% 7-22-96 restored lines to fill printed page with figure -sm
% 7-29-96 added [channumbers] option for channames argument. -sm
%         changed "channels" argument to "channames" in help statement above -sm
% 1-6-97  debugged min/max time and +/- printing -tpj & sm
% 3-3-97  restored previous Default axis parameters at end -sm
% 4-2-97  debugged 32-epoch plotting -sm
% 5-10-97 added no-args check -sm
% 5-20-97 read icadefs.m for MAXPLOTDATACHANS and MAXPLOTDATAEPOCHS -sm
% 6-23-97 use returns instead of errorcodes -sm
% 10-31-97 use normalized PaperUnits for US/A4 compatibility,
%          fixed [xy]{min,max} printing, added clf, adding Clipping off,
%          fixed scaling, added limits tests -sm & ch
% 11-19-97 removed an 'orient' command that caused problems printing -sm
% 07-15-98 added 'ydir' arg, made pos-up the default -sm
% 07-24-98 fixed 'ydir' arg, and pos-up default -sm
% 01-02-99 added warning about frames not dividing data length -sm
% 02-19-99 debugged axis limits -sm
% 11-21-01 add compatibility to load .loc files for channames -ad
% 01-25-02 reformated help & license, added links -ad
% 02-16-02 added axcopy -ad & sm
% 03-15-02 added readlocs and the use of eloc input structure -ad
% 03-15-02 added smart axcopy -ad

function plotdata(data,frames,limits,plottitle,channels,colors,righttitle,ydr)

if nargin < 1,
    help plotdata
    return
end

%
% Set defaults
%
FONTSIZE = 12;     % font size to use for labels
TICKFONTSIZE=12;   % font size to use for axis labels
icadefs;           % read MAXPLOTDATACHANS constant from icadefs.m
                   % read YDIR
if ~exist('YDIR')
    fprintf('YDIR not read from ''icadefs.m'' - plotting positive-up.\n');
    YDIR = 1;
end
DEFAULT_SIGN = YDIR;  % default to plotting positive-up (1) or negative-up (-1)
                      % Now, read sign from YDIR in icadefs.m
ISSPEC = 0;           % default - 0 = not spectral data, 1 = pos-only spectra

axcolor= get(0,'DefaultAxesXcolor'); % find what the default x-axis color is
plotfile = 'plotdata.ps';
ls_plotfile = 'ls -l plotdata.ps';

%
%%%%%%%%%%%%%%%%%%%%%%%%%% Substitute defaults for missing parameters %%%%%
%
SIGN = DEFAULT_SIGN; % set default ydir from YDIR in icadefs.m
if nargin < 8
   ydr = [];
end
if ~isempty(ydr)& ydr ~=0  % override default from commandline
 if ydr == 1
   SIGN = 1;
 else
   SIGN = -1;
 end
end

if nargin < 7,
    righttitle = 0;
end;
if nargin < 6
    colors = 0;
end
if nargin < 5
    channels = [1:size(data,1)]; % default channames = 1:chans
end
if nargin < 4
    plottitle = 0; %CJH
end
limitset = 0;
if nargin < 3,
    limits = 0;
elseif length(limits)>1
    limitset = 1;
end
if nargin < 2,
    frames = 0;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%% Test parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  [chans,framestotal]=size(data);             % data size
  if frames <=0,
    frames = framestotal;    % default
    datasets=1;
  elseif frames==1,
    fprintf('plotdata: cannot plot less than 2 frames per trace.\n');
    return
    datasets=1;
  else
    datasets = fix(framestotal/frames);        % number of traces to overplot
    if datasets*frames < framestotal
         fprintf('\nWARNING: %d points at end of data will not be plotted.\n',...
                    framestotal-datasets*frames);
    end
  end;

  if chans>MAXPLOTDATACHANS,
    fprintf('plotdata: not set up to plot more than %d channels.\n',...
                       MAXPLOTDATACHANS);
    return
  end;
  if datasets>MAXPLOTDATAEPOCHS
      fprintf('plotdata: not set up to plot more than %d epochs.\n',...
                       MAXPLOTDATAEPOCHS);
    return
  end;
  if datasets<1
      fprintf('plotdata: cannot plot less than 1 epoch!\n');
      return
  end;
%
%%%%%%%%%%%%% Extend the size of the plotting area in the window %%%%%%%%%%%%
%
  curfig = gcf;
  h=figure(curfig);
  set(h,'Color',BACKCOLOR); % set the background color
  set(h,'PaperUnits','normalized'); % use percentages to avoid US/A4 difference
  set(h,'PaperPosition',[0.0235308 0.0272775 0.894169 0.909249]); % equivalent
  % orient portrait
  axis('normal');
%
%%%%%%%%%%%%%%%%%%%% Read the channel names %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  if isnumeric(channels) & channels(1)==0,
    channels = [1:size(data,1)];
  end;
  if isnumeric(channels),
      channames = num2str(channels(:));                   %%CJH
  else
      [tmp channames] = readlocs(channels);
      channames = strvcat(channames{:});
  end;
%    chid = fopen(channels,'r');
%    if chid <3,
%        fprintf('plotdata(): cannot open file %s.\n',channels);
%        return
%     end;
%     if isempty( findstr( lower(channels), '.loc') )
%    		channames = fscanf(chid,'%s',[4 Inf]);
%    		channames = channames';
%     else
%        	channames = fscanf(chid,'%d %f %f  %s',[7 128]);
%    		channames = char(channames(4:7,:)');
%     end;
%     ii = find(channames == '.');
%     channames(ii) = ' ';

    %channames = channames';
    %   [r c] = size(channames);
    %for i=1:r
    %    for j=1:c
    %        if channames(i,j)=='.',
    %            channames(i,j)=' ';
    %        end;
    %    end;
    %end;
%    end; % setting channames

%
%%%%%%%%%%%%%%%%%%%%%%%%% Read the color names %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  if colors ~=0,
    if ~isstr(colors)
       fprintf('plotdata(): color file name must be a string.\n');
       return
    end
    cid = fopen(colors,'r');
    % fprintf('cid = %d\n',cid);
    if cid <3,
        fprintf('plotdata: cannot open file %s.\n',colors);
        return
    end;
    colors = fscanf(cid,'%s',[3 Inf]);
    colors = colors';
       [r c] = size(colors);
    for i=1:r
        for j=1:c
            if colors(i,j)=='.',
                colors(i,j)=' ';
            end;
        end;
    end;
  else % use default color order (no yellow!)
     colors =['r  ';'b  ';'g  ';'c  ';'m  ';'r  ';'b  ';'g  ';'c  ';'m  ';'r  ';'b  ';'g  ';'c  ';'m  ';'r  ';'b  ';'g  ';'c  ';'m  ';'r  ';'b  ';'g  ';'c  ';'m  ';'r  ';'b  ';'g  ';'c  ';'m  ';'r  ';'b  ';'g  ';'c  ';'m  '];
     colors = [colors; colors];  % make > 64 available
  end;
  for c=1:size(colors,1)   % make white traces black unless axis color is white
    if colors(c,1)=='w' & axcolor~=[1 1 1]
         colors(c,1)='k';
    end
  end

%
%%%%%%%%%%%%%%%%%%%%%%% Read and adjust limits %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  if limits==0,      % == 0 or [0 0 0 0]
    xmin=0;
    xmax=frames-1;
    ymin=min(min(data));
    ymax=max(max(data));
    yrange = ymax-ymin;
    ymin = ymin - 0.00*yrange;
    ymax = ymax + 0.00*yrange;
  else
    if length(limits)~=4,
      fprintf( ...
       'plotdata: limits should be 0 or an array [xmin xmax ymin ymax].\n');
      return
    end;
    xmin = limits(1);
    xmax = limits(2);
    ymin = limits(3);
    ymax = limits(4);
  end;

  if xmax == 0 & xmin == 0,
    x = (0:1:frames-1);
    xmin = 0;
    xmax = frames-1;
  else
    dx = (xmax-xmin)/(frames-1);
    x=xmin*ones(1,frames)+dx*(0:frames-1); % compute x-values
  end;
  if xmax<=xmin,
      fprintf('plotdata() - xmax must be > xmin.\n')
      return
  end

  if ymax == 0 & ymin == 0,
      ymax=double(max(max(data)));
      ymin=double(min(min(data)));
      yrange = ymax-ymin;
      % ymin = ymin - 0.00*yrange;
      % ymax = ymax + 0.00*yrange;
  end
  if ymax<=ymin,
      fprintf('plotdata() - ymax must be > ymin.\n')
      return
  end

  xlabel = 'Time (ms)';
  if ymin >= 0 & xmin >= 0,          % For all-positive (spectral) data
    ISSPEC = 1;
    SIGN = 1;
    fprintf('\nPlotting positive up. Assuming data are spectra.\n');
    xlabel = 'Freq (Hz)';
    ymin = 0;                        % plot positive-up
  end;

%
%%%%%%%%%%%%%%%%%%%%%%%% Set up plotting environment %%%%%%%%%%%%%%%%%%%%%%%%%
%
  h = gcf;
  % set(h,'YLim',[ymin ymax]);       % set default plotting parameters
  % set(h,'XLim',[xmin xmax]);
  % set(h,'FontSize',18);
  % set(h,'DefaultLineLineWidth',1); % for thinner postscript lines
%
%%%%%%%%%%%%%%%%%%%%%%%%%% Print plot info %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  clf;   % clear the current figure

  % print plottitle over (left) sbplot 1
  if plottitle==0,
      plottitle = '';
  end
  if righttitle==0,
      righttitle = '';
  end

  if ~isempty(righttitle)
      sbplot(ceil(chans/2),2,2), h=gca;%title([righttitle], 'FontSize',FONTSIZE); % title plot and
      set(h,'FontSize',FONTSIZE);            % choose font size
      set(h,'YLim',[ymin ymax]);            % set default plotting parameters
      set(h,'XLim',[xmin xmax]);
  end;

  msg = ['\nPlotting %d traces of %d frames with colors: '];
  for c=1:datasets
    msg = [msg  colors(mod(c-1,length(colors))+1,:)];
  end
  msg = [msg ' -> \n'];    % print starting info on screen . . .
  fprintf(...
    '\n  limits: [xmin,xmax,ymin,ymax] = [%4.1f %4.1f %4.2f %4.2f]\n',...
                xmin,xmax,ymin,ymax);
  fprintf(msg,datasets,frames);
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Plot traces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

  xdiff=xmax-xmin;
  ydiff=ymax-ymin;

  for P=0:datasets-1, %  for each data epoch
      fprintf('\ntrace %d: ',P+1);

    for I=1:chans,        % for each data channel

        index=(2*((rem(I-1,ceil(chans/2))+1)))-1+floor(2*(I-1)/chans);
                                      % = 1 3 5 .. 2 4 6 ..
                                      % plot down left side of page first
        h=sbplot(ceil(chans/2),2,index); h=gca;
        pos = get(h,'position');
        set(h,'position',[pos(1)-pos(4)*0.5 pos(2), pos(3),pos(4)*2]); % increase sbplot-height

        hold on;
        set(h,'YLim',[ymin ymax]);    % set default plotting parameters
        set(h,'XLim',[xmin xmax]);

        axislcolor = get(gca,'Xcolor');   %%CJH

        %
        %%%%%%%%%%%%%%%%%%%%% Plot two-sided time-series data %%%%%%%%%%%%%%%%%%%
        %
        if ~ISSPEC % not spectral data

            ymin = double(ymin);
            ymax = double(ymax);

            if ymin == ymax, ymin = ymin-1; ymax = ymax+1; end;
            plot(x,SIGN*data(I,1+P*frames:1+P*frames+frames-1),colors(mod(P,length(colors))+1));

            if SIGN > 0
                axis([xmin xmax ymin ymax]);          % set axis bounds (pos up)
            else
                axis([xmin xmax -1*ymax -1*ymin]);     % set axis bounds (neg up)
            end

            if P==datasets-1,            % on last traces
                if I==floor((chans+1)/2),   % draw +/0 on lowest left plot
                    signx = double(xmin-0.04*xdiff);

                    if SIGN > 0  % pos up
                        axis('off');hl=text(signx,ymin,num2str(ymin,3));        % text ymin
                        axis('off');hi=text(signx,ymax,['+' num2str(ymax,3)]);  % text +ymax
                    else         % neg up
                        axis('off');hl=text(signx,-1*ymin,num2str(ymin,3));        % text ymin
                        axis('off');hi=text(signx,-1*ymax,['+' num2str(ymax,3)]);  % text +ymax
                    end
                    set(hl,'FontSize',TICKFONTSIZE);         % choose font size
                    set(hl,'HorizontalAlignment','right','Clipping','off');
                    set(hi,'FontSize',TICKFONTSIZE);         % choose font size
                    set(hi,'HorizontalAlignment','right','Clipping','off');
                end

                if I==chans & limitset,    % draw timescale on lowest right plot
                    ytick = double(-ymax-0.25*ydiff);

                    tick = [int2str(xmin)]; h=text(xmin,ytick,tick); % min time
                    set(h,'FontSize',TICKFONTSIZE);         % choose font size
                    set(h,'HorizontalAlignment','center',...
                          'Clipping','off');  % center text

                    tick = [xlabel]; h=text(xmin+xdiff/2,ytick,tick); % xlabel
                    set(h,'FontSize',TICKFONTSIZE);         % choose font size
                    set(h,'HorizontalAlignment','center',...
                          'Clipping','off');  % center text

                    tick = [int2str(xmax)]; h=text(xmax,ytick,tick); % max time
                    set(h,'FontSize',TICKFONTSIZE);         % choose font size
                    set(h,'HorizontalAlignment','center',...
                      'Clipping','off');  % center text
                end;
        end;
      %
      %%%%%%%%%%%%%%%%%%%%% Plot spectral data positive-up [0,ymax] %%%%%%%%%%%%%%%%%%%%%%%%
      %
      else % ISSPEC
        ymin=0;
        plot(x,SIGN*data(I,1+P*frames:1+P*frames+frames-1),colors(mod(P,length(colors))+1));
        ymaxm = ymax;

        % ymin = 0.01;
        % ymaxm = 10.^ceil(log(ymax)/log(10.));
        % if ymaxm/2. > ymax,
        %    ymaxm = ymaxm/2.;
        % end;

        axis([xmin xmax ymin ymaxm]);      % set axis values

        if P==datasets-1,                  % on last trace
         if I==floor((chans+1)/2),         % draw +/0 on lowest left plot
          signx = xmin-0.04*xdiff;

          axis('off');h=text(signx,ymax,['+' num2str(ymax,3)]);
            set(h,'FontSize',TICKFONTSIZE);
            set(h,'HorizontalAlignment','right','Clipping','off');

          axis('off');h=text(signx,0,'0');
            set(h,'FontSize',TICKFONTSIZE);
            set(h,'HorizontalAlignment','right','Clipping','off');
         end;

         if I==chans,                    % draw freq scale on lowest right plot
            ytick = -0.25*ymax;

          tick = [num2str(round(10*xmin)/10) ]; h=text(xmin,ytick,tick);
            set(h,'FontSize',TICKFONTSIZE);
            set(h,'HorizontalAlignment','center','Clipping','off');

          tick = [xlabel]; h=text(xmin+xdiff/2,ytick,tick);
            set(h,'FontSize',TICKFONTSIZE);
            set(h,'HorizontalAlignment','center','Clipping','off');

          tick = [num2str(round(10*xmax)/10) ]; h=text(xmax,ytick,tick);
            set(h,'FontSize',TICKFONTSIZE);
            set(h,'HorizontalAlignment','center','Clipping','off');

        end; % if last chan
      end % if last data
     end; % if ~ISSPEC

      %%%%%%%%%%%%%%%%%%%%%%% Print channel names and lines %%%%%%%%%%%%%%%%%%%%%%%%%%

      if P==datasets-1
          if ~ISSPEC
              axis('off');
              plot([0 0],[ymin ymax],'color',axislcolor); % draw vert %%CJH
                                                          % axis at time 0
          else  % ISSPEC
              axis('off');plot([xmin xmin],[0 ymax],'color',axislcolor);
          end

          % secondx = 200;                                % draw second vert axis
          % axis('off');plot([secondx secondx],[ymin ymax],'color',axislcolor);

          axis('off');
          plot([xmin xmax],[0 0],'color',axislcolor);     % draw horizontal axis

          if ~isempty(channels),                          % print channames
              if ~ISSPEC
                  if ymin <= 0 & ymax >= 0,
                  yht = 0;
                  else
                      yht = nan_mean(SIGN*data(I,1+P*frames:1+P*frames+frames-1));
                  end
                  axis('off'),h=text(xmin-0.04*xdiff,double(yht),[channames(I,:)]);
                  set(h,'HorizontalAlignment','right');      % print before traces
                  set(h,'FontSize',FONTSIZE);                % choose font size

                  % axis('off'),h=text(xmax+0.10*xdiff,yht,[channames(I,:)]);
                  %    set(h,'HorizontalAlignment','left');      % print after traces

              else % ISSPEC
                  axis('off'),h=text(xmin-0.04*xdiff,ymax/2,[channames(I,:)]);
                  set(h,'HorizontalAlignment','right');      % print before traces
                  set(h,'FontSize',FONTSIZE);                % choose font size

                  % axis('off'),h=text(xmax+0.10*xdiff,ymax/2,[channames(I,:)]);
                  %    set(h,'HorizontalAlignment','left');      % print after traces

              end;
          end;
      end;

     fprintf(' %d',I);
    end; % subplot
  end; % dataset
  fprintf('\n');
%
%%%%%%%%%%%%%%%%%% Make printed figure fill page %%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  curfig = gcf;
  h=figure(curfig);
  % set(h,'PaperPosition',[0.2 0.3 7.6 10]); % stretch out the plot on the page
%
%%%%%%%%%%%%%%%%%% Restore plot environment %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
  % set(h,'DefaultAxesYLim',aylim);      % restore previous plotting parameters
  % set(h,'DefaultAxesXLim',axlim);
  % set(h,'DefaultAxesFontSize',axfont);

%%%%%%%%%%%%%%%%%% Add axcopy %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if plottitle
	h = textsc(plottitle, 'title');
	set(h, 'fontsize', FONTSIZE);
end;
axcopy(gcf, 'axis on');

if 0,    % START DETOUR XXXXXXXXXXXXX
%
%%%%%%%%%%%%%%%%%% Save plot to disk if asked %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
   if  plotfile ~= '', %
     n=0; y=1;
     answer = input('plotdata: Save plot as Postscript file? (y/n) ');
     if answer==1,
         fprintf('\nSaving figure as %s ... ',plotfile);
         curfig = gcf;
         h=figure(curfig);
         % set(h,'PaperPosition',[0.2 0.3 7.6 10]);
                                     % stretch out the plot on the page
         eval (['print -dpsc ' plotfile]);
         fprintf('saved. Move or remove file!\n');
         unix(ls_plotfile);
     end
   end
end       % END DETOUR XXXXXXXXXXXXX

function out = nan_mean(in)

    nans = find(isnan(in));
    in(nans) = 0;
    sums = sum(in);
    nonnans = ones(size(in));
    nonnans(nans) = 0;
    nonnans = sum(nonnans);
    nononnans = find(nonnans==0);
    nonnans(nononnans) = 1;
    out = sum(in)./nonnans;
    out(nononnans) = NaN;


function varargout = hopfieldNetwork(varargin)
% HOPFIELDNETWORK M-file for hopfieldNetwork.fig
%      HOPFIELDNETWORK, by itself, creates a new HOPFIELDNETWORK or raises the existing
%      singleton*.
%
%      H = HOPFIELDNETWORK returns the handle to a new HOPFIELDNETWORK or the handle to
%      the existing singleton*.
%
%      HOPFIELDNETWORK('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in HOPFIELDNETWORK.M with the given input arguments.
%
%      HOPFIELDNETWORK('Property','Value',...) creates a new HOPFIELDNETWORK or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before hopfieldNetwork_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to hopfieldNetwork_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Copyright 2002-2003 The MathWorks, Inc.

% Edit the above text to modify the response to help hopfieldNetwork

% Last Modified by GUIDE v2.5 21-Jan-2007 15:45:38

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @hopfieldNetwork_OpeningFcn, ...
                   'gui_OutputFcn',  @hopfieldNetwork_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before hopfieldNetwork is made visible.
function hopfieldNetwork_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to hopfieldNetwork (see VARARGIN)

% Choose default command line output for hopfieldNetwork
handles.output = hObject;
N = str2num(get(handles.imageSize,'string'));
handles.W = [];
handles.hPatternsDisplay = [];

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes hopfieldNetwork wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = hopfieldNetwork_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in reset.
function reset_Callback(hObject, eventdata, handles)
% cleans all data and enables the change of the number of neurons used
    for n=1 : length(handles.hPatternsDisplay)
        delete(handles.hPatternsDisplay(n));
    end
    handles.hPatternsDisplay = [];
    set(handles.imageSize,'enable','on');
    handles.W = [];
    guidata(hObject, handles);

function imageSize_Callback(hObject, eventdata, handles)
% hObject    handle to imageSize (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    num = get(hObject,'string');
    n = str2num(num);
    if isempty(n)
        num = '32';
        set(hObject,'string',num);
    end
    if n > 32
        warndlg('It is strongly recomended NOT to work with networks with more then 32^2 neurons!','!! Warning !!')
    end

% --- Executes during object creation, after setting all properties.
function imageSize_CreateFcn(hObject, eventdata, handles)
% hObject    handle to imageSize (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end

% --- Executes on button press in loadIm.
function loadIm_Callback(hObject, eventdata, handles)
    [fName dirName] = uigetfile('*.bmp;*.tif;*.jpg;*.tiff');
    if fName
        set(handles.imageSize,'enable','off');
        cd(dirName);
        im = imread(fName);
        N = str2num(get(handles.imageSize,'string'));
        im = fixImage(im,N);
        imagesc(im,'Parent',handles.neurons);
        colormap('gray');
    end

% --- Executes on button press in train.
function train_Callback(hObject, eventdata, handles)

    Npattern = length(handles.hPatternsDisplay);
    if Npattern > 9
        msgbox('more then 10 paterns isn''t supported!','error');
        return
    end

    im = getimage(handles.neurons);
    N = get(handles.imageSize,'string');
    N = str2num(N);
    W = handles.W;  %weights vector
    avg = mean(im(:));   %removing the cross talk part
    if ~isempty(W)
        %W = W +( kron(im,im))/(N^2);
        W = W + ( kron(im-avg,im-avg))/(N^2)/avg/(1-avg);
    else
        % W = kron(im,im)/(N^2);
        W = ( kron(im-avg,im-avg))/(N^2)/avg/(1-avg);
    end
    % Erasing self weight
    ind = 1:N^2;
    f = find(mod(ind,N+1)==1);
    W(ind(f),ind(f)) = 0;

    handles.W = W;

    % Placing the new pattern in the figure...
    xStart = 0.01;
    xEnd = 0.99;
    height = 0.65;
    width = 0.09;
    xLength = xEnd-xStart;
    xStep = xLength/10;
    offset = 4-ceil(Npattern/2);
    offset = max(offset,0);
    y = 0.1;

    if Npattern > 0
        for n=1 : Npattern
            x = xStart+(n+offset-1)*xStep;
            h = handles.hPatternsDisplay(n);
            set(h,'units','normalized');
            set(h,'position',[x y width height]);
        end
        x = xStart+(n+offset)*xStep;
        h = axes('units','normalized','position',[x y width height]);
        handles.hPatternsDisplay(n+1) = h;
        imagesc(im,'Parent',h);
    else
        x = xStart+(offset)*xStep;
        h = axes('units','normalized','position',[x y width height]);
        handles.hPatternsDisplay = h;
    end

    imagesc(im,'Parent',h);
    set(h, 'YTick',[],'XTick',[],'XTickMode','manual','Parent',handles.learnedPaterns);

    guidata(hObject, handles);

% --- Executes on button press in addNoise.
function addNoise_Callback(hObject, eventdata, handles)
    im = getimage(handles.neurons);
    % N = get(handles.imageSize,'string');
    % N = floor(str2num(N)/2)+1;
    noisePercent = get( handles.noiseAmount, 'value' );
    N = round( length(im(:))* noisePercent );
    N = max(N,1);   %minimum change one neuron
    ind = ceil(rand(N,1)*length(im(:)));
%    im(ind) = -1*im(ind); %!!!!
    im(ind) = ~im(ind);
    imagesc(im,'Parent',handles.neurons);
    colormap('gray');

% --- Executes on button press in run.
function run_Callback(hObject, eventdata, handles)
    im = getimage(handles.neurons);
    [rows cols] = size(im);
    if rows ~= cols
        msgbox('I don''t support non square images','error');
        return;
    end
    N = rows;
    W = handles.W;
    if isempty(W)
        msgbox('No train data - doing nothing!','error');
        return;
    end
    %figure; imagesc(W)
    mat = repmat(im,N,N);
    mat = mat.*W;
    mat = im2col(mat,[N,N],'distinct');
    networkResult = sum(mat);
    networkResult = reshape(networkResult,N,N);
    im = fixImage(networkResult,N);
    imagesc(im,'Parent',handles.neurons);

% hObject    handle to run (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

function im = fixImage(im,N)
%    if isrgb(im)
	if length( size(im) ) == 3
        im = rgb2gray(im);
    end
    im = double(im);
    m = min(im(:));
    M = max(im(:));
    im = (im-m)/(M-m);  %normelizing the image
    im = imresize(im,[N N],'bilinear');
    %im = (im > 0.5)*2-1;    %changing image values to -1 & 1
    im = (im > 0.5);    %changing image values to 0 & 1

% --- Executes on slider movement.
function noiseAmount_Callback(hObject, eventdata, handles)
% hObject    handle to noiseAmount (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    percent = get(hObject,'value');
    percent = round(percent*100);
    set(handles.noisePercent,'string',num2str(percent));

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

% --- Executes during object creation, after setting all properties.
function noiseAmount_CreateFcn(hObject, eventdata, handles)
% hObject    handle to noiseAmount (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background, change
%       'usewhitebg' to 0 to use default.  See ISPC and COMPUTER.
usewhitebg = 1;
if usewhitebg
    set(hObject,'BackgroundColor',[.9 .9 .9]);
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end


function colors = colorSamples(lst)
%
% lst:  A vector of integers between 1 and 20 to draw some samples
%
% RF/BW

% Check parameters

% This is static.
% This is a good list of colors that Renzo made from D3.  We use these for
% various tasks like selecting the fiber colors
colorList = [ ...
    31   119   180
    174   199   232
    255   127    14
    255   187   120
    44   160    44
    152   223   138
    214    39    40
    255   152   150
    148   103   189
    197   176   213
    140    86    75
    196   156   148
    227   119   194
    247   182   210
    127   127   127
    199   199   199
    188   189    34
    219   219   141
    23   190   207
    158   218   229];

% Here they are
colors = colorList(lst,:);
end


function test3 (nmat)
%TEST3 test for BTF
% Requires UFget
% Example:
%   test3
% See also btf, maxtrans, strongcomp, dmperm, UFget,
%   test1, test2, test3, test4, test5.

% Copyright 2007, Timothy A. Davis, Univ. of Florida

doplot = 1 ;
dopause = 0 ;
dostrong = 1 ;

index = UFget ;
f = find (index.nrows == index.ncols) ;
[ignore i] = sort (index.nnz (f)) ;
f = f (i) ;
clear i

figure (1)

% short test set: seg faults, lots of blocks, lots of work, and so on:
nasty = [
        % --- various test matrices (no seg fault, quick run time)
    -(1:8)'  % generated matrices
    904 % vanHeukelum/cage3 (5-by-5)
    819 % Simon/raefsky6 (permuted triangular matrix)
        %
        % --- older seg faults:
    264 % HB/west0156, causes older strongcomp_recursive to fail
    824 % TOKAMAK/utm300 (300-by-300), causes older code to fail
    868 % Pothen/bodyy4
        %
        % --- seg faults in old MATLAB dmperm
    290 % Averous/epb3
    983 % Sanghavi/ecl32
    885 % Pothen/tandem_dual
    879 % Pothen/onera_dual
    955 % Schenk_IBMSDS/2D_54019_highK
    957 % Schenk_IBMSDS/3D_51448_3D
    958 % Schenk_IBMSDS/ibm_matrix_2
    912 % vanHeukelum/cage11
    924 % Andrews/Andrews
    960 % Schenk_IBMSDS/matrix-new_3
    862 % Kim/kim1
    544 % Hamm/scircuit
    897 % Norris/torso2
    801 % Ronis/xenon1
     53 % HB/bcsstk31
    958 % Schenk_IBMSDS/matrix_9
    844 % Cunningham/qa8fk
    845 % Cunningham/qa8fk
    821 % Simon/venkat25
    822 % Simon/venkat50
    820 % Simon/venkat01
    812 % Simon/bbmat
    804 % Rothberg/cfd1
     54 % HB/bcsstk32
    913 % vanHeukelum/cage12
    846 % Boeing/bcsstk39
    972 % Schenk_IBMSDS/para-10
    974 % Schenk_IBMSDS/para-5
    975 % Schenk_IBMSDS/para-6
    976 % Schenk_IBMSDS/para-7
    977 % Schenk_IBMSDS/para-8
    978 % Schenk_IBMSDS/para-9
    961 % Schenk_ISEI/barrier2-10
    962 % Schenk_ISEI/barrier2-11
    963 % Schenk_ISEI/barrier2-12
    964 % Schenk_ISEI/barrier2-1
    965 % Schenk_ISEI/barrier2-2
    966 % Schenk_ISEI/barrier2-3
    967 % Schenk_ISEI/barrier2-4
    968 % Schenk_ISEI/barrier2-9
    851 % Chen/pkustk05
    979 % Kamvar/Stanford
    374 % Bova/rma10
        %
        % --- lots of time:
    395 % DRIVCAV/cavity16
    396 % DRIVCAV/cavity17
    397 % DRIVCAV/cavity18
    398 % DRIVCAV/cavity19
    399 % DRIVCAV/cavity20
    400 % DRIVCAV/cavity21
    401 % DRIVCAV/cavity22
    402 % DRIVCAV/cavity23
    403 % DRIVCAV/cavity24
    404 % DRIVCAV/cavity25
    405 % DRIVCAV/cavity26
    1109 % Sandia/mult_dcop_01
    1110 % Sandia/mult_dcop_02
    1111 % Sandia/mult_dcop_03
    376 % Brethour/coater2
    284 % ATandT/onetone2
    588 % Hollinger/mark3jac100
    589 % Hollinger/mark3jac100sc
    452 % Grund/bayer01
    920 % Hohn/sinc12
    590 % Hollinger/mark3jac120
    591 % Hollinger/mark3jac120sc
    809 % Shyy/shyy161
    448 % Graham/graham1
    283 % ATandT/onetone1
    445 % Garon/garon2
    541 % Hamm/bcircuit
    592 % Hollinger/mark3jac140
    593 % Hollinger/mark3jac140sc
    435 % FIDAP/ex40
    912 % Hohn/sinc15
    894 % Norris/lung2
    542 % Hamm/hcircuit
    752 % Mulvey/finan512
    753 % Mulvey/pfinan512
    564 % Hollinger/g7jac180
    565 % Hollinger/g7jac180sc
    566 % Hollinger/g7jac200
    567 % Hollinger/g7jac200sc
    748 % Mallya/lhr34
    749 % Mallya/lhr34c
    922 % Hohn/sinc18
    447 % Goodwin/rim
    807 % Rothberg/struct3
    286 % ATandT/twotone
    982 % Tromble/language
    953 % Schenk_IBMNA/c-73
    890 % Norris/heart1
    750 % Mallya/lhr71
    751 % Mallya/lhr71c
    925 % FEMLAB/ns3Da
    827 % Vavasis/av41092
    931 % FEMLAB/sme3Db
   1297 % GHS_index/boyd2
   1301 % GHS_indef/cont-300
        %
        % --- lots of time, and seg faults:
    285 % ATandT/pre2
        % --- huge matrix, turn off plotting
    940 % Shenk/af_shell1, memory leak in plot, after call to btf, once.
        % ----
]' ;

% maxtrans_recursive causes a seg fault on these matrices, because of
% stack overflow (this is expected)
skip_list_maxtrans_recursive = 285 ;

% p = dmperm (A) in MATLAB 7.4 causes a seg fault on these matrices:
skip_list_dmperm = [285 1301 1231 1251 1232 1241] ;

% [p,q,r] = dmperm (A) in MATLAB 7.4 causes a seg fault on these matrices:
skip_list_dmperm_btf = ...
[    285 879 885 290 955 957 958     924 960         897        959 844 845 ...
 821 822 820     804    913 846 972 974:978 961:968  979 940 ...
 1422 1513 1412 1510 1301 1231 1251 1434 1213 1232 1241 1357 1579 1431 1281] ;
% length(skip_list_dmperm_btf)

% time intensive
skip_costly = [1514 1297 1876 1301] ;

% strongcomp (recursive) causes a seg fault on these matrices because of
% stack overflow (this is expected).
skip_list_strongcomp_recursive     = ...
[983 285 879 885 290 955 957 958 912 924 960 862 544 897 801 53 959 844 845 ...
 821 822 820 812 804 54 913 846 972 974:978 961:968 851     374 940] ;
skip_list_strongcomp_recursive     = ...
[ skip_list_strongcomp_recursive 592 593 752 753 807 286 982 855 566 567 ] ;

% matrices with the largest # of nonzeros in the set (untested)
toobig = [
928   853   852   356   761   368   973   895   805   849   932 ...
803   854   936   802   850   537   856   898   857   859   971   937 ...
914   858   980   896   806   538   863   369   938   860   941   942 ...
943   944   945   946   947   948   915   939   916 ] ;

f = [ -(1:8) f ] ;
% f = nasty ;

h = waitbar (0, 'BTF test 3 of 6') ;

if (nargin < 1)
    nmat = 1000 ;
end
nmat = min (nmat, length (f)) ;
f = f (1:nmat) ;

try

    for matnum = 1:nmat

        waitbar (matnum/nmat, h) ;

        j = f (matnum) ;

        if (any (j == toobig) | any (j == skip_costly))                     %#ok
            fprintf ('\n%4d: %3d %s/%s too big\n', ...
                matnum, j, index.Group{j}, index.Name{j}) ;
            continue ;
        end

        rand ('state', 0) ;

        % clear all unused variables.
        % nothing here is left that is proportional to the matrix size
        clear A p1 p2 p3 q3 r3 match1 match2 match4 pa ra sa qa B C pb rb pc rc
        clear jumble B11 B12 B13 B21 B22 B23 B31 B32 B33 pjumble qjumble ans
        clear c kbad kgood
        % whos
        % pause

        if (j > 0)
            Problem = UFget (j, index) ;
            name = Problem.name ;
            A = Problem.A ;
            clear Problem
        else
            % construct the jth test matrix
            j = -j ;
            if (j == 1 | j == 2)                                            %#ok
                B11 = UFget ('Grund/b1_ss') ;       % 7-by-7 diagonal block
                B11 = B11.A ;
                B12 = sparse (zeros (7,2)) ;
                B12 (3,2) = 1 ;
                B13 = sparse (ones  (7,5)) ;
                B21 = sparse (zeros (2,7)) ;
                B22 = sparse (ones  (2,2)) ;        % 2-by-2 diagonal block
                B23 = sparse (ones  (2,5)) ;
                B31 = sparse (zeros (5,7)) ;
                B32 = sparse (zeros (5,2)) ;
                B33 = UFget ('vanHeukelum/cage3') ;    % 5-by-5 diagonal block
                B33 = B33.A ;
                A = [ B11 B12 B13 ; B21 B22 B23 ; B31 B32 B33 ] ;
                name = '(j=1 test matrix)' ;
            end
            if (j == 2)
                pjumble = [ 10 7 11 1 13 12 8 2 5 14 9 6 4 3 ] ;
                qjumble = [ 3 14 2 11 1 8 5 7 10 12 4 13 9 6 ] ;
                A = A (pjumble, qjumble) ;
                name = '(j=2 test matrix)' ;
            elseif (j == 3)
                A = sparse (1) ;
            elseif (j == 4)
                A = sparse (0) ;
            elseif (j == 5)
                A = sparse (ones (2)) ;
            elseif (j == 6)
                A = sparse (2,2) ;
            elseif (j == 7)
                A = speye (2) ;
            elseif (j == 8)
                A = sparse (2,2) ;
                A (2,1) = 1 ;
            end
            if (j > 2)
                full (A)
            end
        end

        [m n] = size (A) ;
        if (m ~= n)
            continue ;
        end
        fprintf ('\n%4d: ', matnum) ;
        fprintf (' =========================== Matrix: %3d %s\n', j, name) ;
        fprintf ('n: %d nz: %d\n', n, nnz (A)) ;

        if (nnz (A) > 6e6)
            doplot = 0 ;
        end

        %-----------------------------------------------------------------------
        % now try maxtrans
        tic
        match1 = maxtrans (A) ;
        t = toc ;
        s1 = sum (match1 > 0) ;
        fprintf ('n-sprank: %d\n', n-s1) ;
        fprintf ('maxtrans:                %8.2f seconds\n', t) ;
        singular = s1 < n ;

        if (doplot)
            % figure (1)
            clf
            subplot (2,4,1)
            spy (A)
            title (name) ;
        end

        p1 = match1 ;
        if (any (p1 <= 0))
            % complete the permutation
            badrow = find (p1 <= 0) ;

            badcol = ones (1,n) ;
            badcol (p1 (p1 > 0)) = 0 ;
            badcol = find (badcol) ;

            p1 (badrow) = badcol ;

            % construct the older form of match1
            match1 (badrow) = -p1 (badrow) ;
        end
        if (any (sort (p1) ~= 1:n))
            error ('!!') ;
        end

        B = A (:,p1) ;

        if (doplot)
            subplot (2,4,2)
            hold off
            spy (B)
            hold on
            badcol = find (match1 < 0) ;
            Junk = sparse (badcol, badcol, ones (length (badcol), 1), n, n) ;
            % if (~isempty (A))
                % spy (Junk, 'ro') ;
            % end
            title ('maxtrans') ;
        end

        d = nnz (diag (B)) ;
        if (d ~= s1)
            error ('bad sprank') ;
        end
        clear B

        %-----------------------------------------------------------------------
        % try p = dmperm(A)
        skip_dmperm = any (j == skip_list_dmperm) ;

        if (~skip_dmperm)
            tic
            match4 = dmperm (A) ;
            t = toc ;
            fprintf ('p=dmperm(A):             %8.2f seconds\n', t) ;
            s4 = sum (match4 > 0) ;
            singular4 = (s4 < n) ;

            if (doplot)
                if (~singular4)
                    subplot (2,4,3)
                    spy (A (match4,:))
                    title ('dmperm') ;
                end
            end
            if (singular ~= singular4)
                error ('s4?') ;
            end
            if (s1 ~= s4)
                error ('bad sprank') ;
            end
        else
            fprintf ('p=dmperm(A): skip\n') ;
        end

        %-----------------------------------------------------------------------
        nblocks = -1 ;
        skip_dmperm_btf = any (j == skip_list_dmperm_btf) ;
        if (~skip_dmperm_btf)
            % get btf form
            tic
            [pa,qa,ra,sa] = dmperm (A) ;
            t = toc ;
            fprintf ('[p,q,r,s]=dmperm(A):     %8.2f seconds\n', t) ;
            nblocks = length (ra) - 1 ;
            fprintf ('nblocks: %d\n', nblocks) ;
            if (~singular4)
                checkbtf (A, pa, qa, ra) ;
                if (doplot)
                    subplot (2,4,4)
                    drawbtf (A, pa, qa, ra)
                    title ('dmperm blocks')
                end
            end
        else
            fprintf ('[p,q,r,s]=dmperm(A): skip\n') ;
        end

        jumble = randperm (n) ;

        %-----------------------------------------------------------------------
        % try strongcomp, non-recursive version

            %-------------------------------------------------------------------
            % try strongcomp on original matrix
            B = A (:,p1) ;
            tic ;
            [pb,rb] = strongcomp (B) ;
            t = toc ;
            fprintf ('strongcomp               %8.2f seconds\n', t) ;
            if (~singular & ~skip_dmperm_btf & (length (rb) ~= nblocks+1))  %#ok
                error ('BTF:invalid (rb)') ;
            end
            checkbtf (B, pb, pb, rb) ;
            if (doplot)
                subplot (2,4,5)
                drawbtf (B, pb, pb, rb) ;
                title ('strongcomp') ;
            end

            %-------------------------------------------------------------------
            % try btf on original matrix
            tic ;
            [pw,qw,rw] = btf (A) ;
            t = toc ;
            fprintf ('btf                      %8.2f seconds nblocks %d\n', ...
                t, length (rw)-1) ;

            if (any (pw ~= pb))
                error ('pw') ;
            end
            if (any (rw ~= rb))
                error ('rw') ;
            end
            if (any (abs (qw) ~= p1 (pw)))
                error ('qw') ;
            end
            c = diag (A (pw,abs (qw))) ;
            if (~singular & ~skip_dmperm_btf & (length (rw) ~= nblocks+1))  %#ok
                error ('BTF:invalid (rw)') ;
            end
            checkbtf (A, pw, abs (qw), rw) ;

            kbad  = find (qw < 0) ;
            kgood = find (qw > 0) ;
            if (any (c (kbad) ~= 0))
                error ('kbad') ;
            end
            if (any (c (kgood) == 0))       %#ok
                error ('kgood') ;
            end

            if (doplot)
                subplot (2,4,6)
                drawbtf (A, pw, abs (qw), rw) ;
                if (n < 500)
                    for k = kbad
                        plot ([k (k+1) (k+1) k k]-.5, ...
                            [k k (k+1) (k+1) k]-.5, 'r') ;
                    end
                end
                title ('btf') ;
            end

            %-------------------------------------------------------------------
            % try [p,q,r] = strongcomp (A, qin) form
            tic
            [pz,qz,rz] = strongcomp (A, match1) ;
            t = toc ;
            fprintf ('[p,q,r]=strongcomp(A,qin)%8.2f seconds\n', t) ;
            if (any (pz ~= pb))
                error ('pz') ;
            end
            if (any (rz ~= rb))
                error ('rz') ;
            end
            if (any (abs (qz) ~= p1 (pz)))
                error ('qz') ;
            end
            c = diag (A (pz,abs (qz))) ;
            if (~singular & ~skip_dmperm_btf & (length (rz) ~= nblocks+1))  %#ok
                error ('BTF:invalid (rz)') ;
            end
            checkbtf (A, pz, abs (qz), rz) ;

            kbad  = find (qz < 0) ;
            kgood = find (qz > 0) ;
            if (any (c (kbad) ~= 0))
                error ('kbad') ;
            end
            if (any (c (kgood) == 0))                                       %#ok
                error ('kgood') ;
            end

            if (doplot)
                subplot (2,4,7)
                drawbtf (A, pz, abs (qz), rz) ;
                if (n < 500)
                    for k = kbad
                        plot ([k (k+1) (k+1) k k]-.5, ...
                            [k k (k+1) (k+1) k]-.5, 'r') ;
                    end
                end
                title ('strongcomp(A,qin)') ;
            end

            %-------------------------------------------------------------------
            % try strongcomp again, on a randomly jumbled matrix
            C = sparse (B (jumble, jumble)) ;
            tic ;
            [pc,rc] = strongcomp (C) ;
            t = toc ;
            fprintf ('strongcomp       (rand)  %8.2f seconds\n', t) ;
            if (~singular & ~skip_dmperm_btf & (length (rc) ~= nblocks+1))  %#ok
                error ('BTF:invalid (rc)') ;
            end
            checkbtf (C, pc, pc, rc) ;
            if (doplot)
                subplot (2,4,8)
                drawbtf (C, pc, pc, rc) ;
                title ('strongcomp(rand)') ;
            end

            if (length (rc) ~= length (rb))
                error ('strongcomp random mismatch') ;
            end

        %-----------------------------------------------------------------------
        if (doplot)
            drawnow
        end

        if (matnum ~= nmat & dopause)                                       %#ok
            input ('Hit enter: ') ;
        end

    end

catch
    % out-of-memory is OK, other errors are not
    disp (lasterr) ;
    if (isempty (strfind (lasterr, 'Out of memory')))
        error (lasterr) ;                                                   %#ok
    else
        fprintf ('test terminated early, but otherwise OK\n') ;
    end
end

close (h) ;


function out = isempty( f )
%ISEMPTY   True for empty SEPARABLEAPPROX.
%   ISEMPTY(F) returns 1 if F is an empty SEPARABLEAPPROX object and 0 otherwise.

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

out = isempty( f.cols ) && isempty( f.rows );

end


function [stop reason] = stoppingcriterion(problem, x, options, info, last)
% Checks for standard stopping criteria, as a helper to solvers.
%
% function [stop reason] = stoppingcriterion(problem, x, options, info, last)
%
% Executes standard stopping criterion checks, based on what is defined in
% the info(last) stats structure and in the options structure.
%
% The returned number 'stop' is 0 if none of the stopping criteria
% triggered, and a (strictly) positive integer otherwise. The integer
% identifies which criterion triggered:
%  0 : Nothing triggered;
%  1 : Cost tolerance reached;
%  2 : Gradient norm tolerance reached;
%  3 : Max time exceeded;
%  4 : Max iteration count reached;
%  5 : Maximum number of cost evaluations reached;
%  6 : User defined stopfun criterion triggered.
%
% The output 'reason' is a string describing the triggered event.

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Dec. 30, 2012.
% Contributors:
% Change log:

    stop = 0;
    reason = '';

    stats = info(last);

    % Target cost attained
    if isfield(stats, 'cost') && isfield(options, 'tolcost') && ...
       stats.cost <= options.tolcost
        reason = 'Cost tolerance reached. See options.tolcost.';
        stop = 1;
        return;
    end

    % Target gradient norm attained
    if isfield(stats, 'gradnorm') && isfield(options, 'tolgradnorm') && ...
       stats.gradnorm < options.tolgradnorm
        reason = 'Gradient norm tolerance reached. See options.tolgradnorm.';
        stop = 2;
        return;
    end

    % Alloted time exceeded
    if isfield(stats, 'time') && isfield(options, 'maxtime') && ...
       stats.time >= options.maxtime
        reason = 'Max time exceeded. See options.maxtime.';
        stop = 3;
        return;
    end

    % Alloted iteration count exceeded
    if isfield(stats, 'iter') && isfield(options, 'maxiter') && ...
       stats.iter >= options.maxiter
        reason = 'Max iteration count reached. See options.maxiter.';
        stop = 4;
        return;
    end

    % Alloted function evaluation count exceeded
    if isfield(stats, 'costevals') && isfield(options, 'maxcostevals') && ...
       stats.costevals >= options.maxcostevals
        reason = 'Maximum number of cost evaluations reached. See options.maxcostevals.';
        stop = 5;
    end

    % Check whether the possibly user defined stopping criterion
    % triggers or not.
    if isfield(options, 'stopfun')
        userstop = options.stopfun(problem, x, info, last);
        if userstop
            reason = 'User defined stopfun criterion triggered. See options.stopfun.';
            stop = 6;
            return;
        end
    end

end


% Copyright 2011 Zdenek Kalal
%
% This file is part of TLD.
%
% TLD 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.
%
% TLD 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 TLD.  If not, see <http://www.gnu.org/licenses/>.

function bb = bb_correct(img,bb)
% Change

K  = 2;
K2 = 1;
while 1

    clf; imshow(img); bb_rectangle(bb,'EdgeColor','y');
    %maximize();
    [x,y,ch] = ginput(1);
    if isempty(ch), break; end
    switch ch
        case 29
            bb = [bb(1)+K; bb(2); bb(3)+K; bb(4)];
        case 28
            bb = [bb(1)-K; bb(2); bb(3)-K; bb(4)];
        case 30
            bb = [bb(1); bb(2)-K; bb(3); bb(4)-K];
        case 31
            bb = [bb(1); bb(2)+K; bb(3); bb(4)+K];
        case 46 % bigger
            bb = [bb(1)-K2; bb(2)-K2; bb(3)+K2; bb(4)+K2];
        case 44 % smaller
            bb = [bb(1)+K2; bb(2)+K2; bb(3)-K2; bb(4)-K2];

    end

end


function [strength, time, x, y, storedMacs] = parseWirelessData(fileName)

% PARSEWIRELESSDATA Load wireless strength data.
% FORMAT
% DESC loads wireless strength data as written by the University of
% Washington by Brian Ferris.
% ARG fileName : the file name to load the data from.
% RETURN strength : the strengths of the wireless access points
% read.
% RETURN time : the time at which the wireless access points were
% read.
% RETURN x : the 'ground truth' x location of the device at the
% time.
% RETURN y : the 'ground truth' y location of the device at the
% time.
% RETURN macs : the mac addresses of the devices that were read.
%
% SEEALSO : lvmLoadData
%
% COPYRIGHT : Neil D. Lawrence, 2005, 2006
%
% MODIFICATIONS : Neil D. Lawrence, 2009

% DATASETS

fid = fopen(fileName);
if fid == -1
  error(['No such file name ' fileName])
end
readLine = fgets(fid);
storedMacs = {};
counter = 0;
data = [];
curTime = -1;
timeIndex = 1;
while readLine ~= -1
  counter = counter + 1;
  parts = stringSplit(readLine, ' ');
  index = -1;
  for i = 1:length(storedMacs)
    if strcmp(parts{2}, storedMacs{i})
      index = i;
    end
  end
  if index == -1
    index = length(storedMacs) + 1;
    storedMacs{index} = parts{2};
  end
  pointTime = str2num(parts{1});
  if curTime == -1
    curTime = pointTime;
  end
  if pointTime > curTime
    timeIndex = timeIndex + 1;
    curTime = pointTime;
  end
  data(counter, :) = [timeIndex index str2num(parts{1})  str2num(parts{3}) str2num(parts{4}) str2num(parts{5})];
  readLine = fgets(fid);
end
start = min(data(:, 3));
data(:, 3) = data(:, 3) - start + 1;
indMax = max(data(:, 2));
points = max(data(:, 1));

x = zeros(points, 1);
y = zeros(points, 1);
time = zeros(points, 1);
strength = repmat(-92, points, indMax);

for i = 1:size(data, 1);
  x(data(i, 1), 1) = data(i, 4);
  y(data(i, 1), 1) = data(i, 5);
  time(data(i, 1), 1) = data(i, 3);
  strength(data(i, 1), data(i, 2)) = data(i, 6);
end
[storedMacs, ind] = sort(storedMacs);
strength = strength(:, ind);


function searchlight_saveresults(modeldir)
% This function combines and saves searchlight analysis results.
%
% :Usage:
% ::
%
%     searchlight_saveresults(modeldir)
%
% ..
%     Author and copyright information:
%
%     Copyright (C) 2014  Wani Woo
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
% ..
%
% :Input:
%
%   **modeldir:**
%        the directory where the searchlight result mat files (e.g.,
%        searchlight_results_*_01Aug2014.mat)
%
% :Outputs:
%
%   This function saves the brain maps where each voxel contains a summary
%   stat value (e.g., accuracy or outcome correlation) in the modeldir. The
%   naming convention of the result maps are as follow:
%
%   results_searchlight_(a)_(b)_dat(c).nii
%      1. will be a number - the number of test results
%      2. acc: accuracy, r: outcome correlation, p: p-values, se: standard error,
%         and thr: threshold for the single-interval test
%      3. If the test was on one dataset, (c) will be empty, but if the
%         test was cross-prediction, (c) will be 11, 12, 21, or 22.
%           - 11: trained on the first dataset, and tested on the first dataset
%           - 12: trained on the first dataset, and tested on the second dataset
%           - 21: trained on the second dataset, and tested on the first dataset
%           - 22: trained on the second dataset, and tested on the second dataset
%
% :Output Examples:
% ::
%
%    results_searchlight_1_r_dat11.nii (outcome correlation)
%    results_searchlight_1_p_dat11.nii (p value for the correlation values)
%
%    results_searchlight_2_acc_dat11.nii (accuracy)
%    results_searchlight_2_p_dat11.nii (p value for the accuracy)
%    results_searchlight_2_se_dat11.nii (standard error for the accuracy)
%    results_searchlight_2_thr_dat11.nii (threshold for the accuracy test)

load(fullfile(modeldir, 'searchlight_dream_variables.mat'));
data = load(fullfile(modeldir, 'searchlight_dream_variables.mat'), 'varargin');

do_cross = false;

% parsing varargin to know it's cross_classify or not
for i = 1:numel(data.varargin)
    if ischar(data.varargin{i})
        switch data.varargin{i}
            case 'dat2'
                do_cross = true;
        end
    end
end

res_files = filenames(fullfile(modeldir, 'searchlight_results_*mat'));

% load one test_results to set up results variables
load(res_files{1}, 'test_results');

% image frame
if do_cross
    dat.dat = zeros(size(dat.dat,1),4);
else
    dat.dat = zeros(size(dat.dat,1),1);
end

% results fields
for m = 1:numel(test_results)
    res_fields{m} = fields(test_results{m});
    for j = 1:numel(res_fields{m}), eval(['dat_' num2str(m) '_'  res_fields{m}{j} ' = dat;']); end
end

% combining results
for ii = 1:numel(res_files)
    load(res_files{ii}, 'test_results');

    for m = 1:numel(test_results)
        for j = 1:numel(res_fields{m})
            eval(['test_results{' num2str(m) '}.' res_fields{m}{j} '(isnan(test_results{' num2str(m) '}.' res_fields{m}{j} ')) = 0;']);
            eval(['dat_' num2str(m) '_' res_fields{m}{j} '.dat = dat_' num2str(m) '_' res_fields{m}{j} '.dat + test_results{' num2str(m) '}.' res_fields{m}{j} ';']);
        end
    end
end

% image names for each column
if do_cross
    col_names = {'dat11', 'dat12', 'dat21', 'dat22'};
else
    col_names = {'dat'};
end

% write images
for m = 1:numel(test_results)
    for jj = 1:numel(res_fields{m})
        eval(['for ii = 1:size(dat_' num2str(m) '_' res_fields{m}{jj} '.dat,2), dat.dat = dat_' ...
            num2str(m) '_' res_fields{m}{jj} '.dat(:,ii); dat.fullpath = fullfile(modeldir, [''results_searchlight_' ...
            num2str(m) '_' res_fields{m}{jj} '_'' col_names{ii} ''.nii'']); write(dat); end']);
    end
end

end


function r = isinf(a)
%ISINF        Array of 1's for inf components
%
%   r = isinf(a)
%

% written  08/07/02     S.M. Rump
% modified 04/04/04     S.M. Rump  set round to nearest for safety
%                                    Matlab flaw for empty sparse corrected
% modified 04/06/05     S.M. Rump  rounding unchanged
%

  r = reshape( isinf(a.x(:)) | any(isinf(a.dx),2) , size(a.x) );


function [obj] = update(obj)
    % Updates the NLP problems before load it to NLP solver

    % update variable indices
    index_offset = 0;

    num_vars = numel(obj.VariableArray);

    for i = 1:num_vars
        dim = obj.VariableArray(i).Dimension;

        % set the index
        setIndices(obj.VariableArray(i),index_offset + cumsum(ones(dim,1)));

        % increments (updates) offset
        index_offset = index_offset + dim;
    end

end


classdef TestDrawMarker
    %TestDrawMarker

    methods (Static)
        function test_1
            img = 255*ones(64,64,3,'uint8');
            out = cv.drawMarker(img, [32,32]);
            validateattributes(out, {class(img)}, {'size',size(img)});
        end

        function test_options
            img = zeros([100 400 3],'uint8');
            markers = '+x*ds^v';
            for i=1:numel(markers)
                img = cv.drawMarker(img, [50*i 50], ...
                    'Color',[255 0 0], 'MarkerType',markers(i), ...
                    'MarkerSize',30, 'Thickness',2, 'LineType','AA');
            end
            validateattributes(img, {'uint8'}, {'size',[100 400 3]});
        end

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

end


function A = double(T)
%DOUBLE Convert a sptenmat to a sparse matrix.
%
%   A = double(T) converts T stored as a SPTENMAT to a sparse matrix.
%
%   See also SPTENMAT.
%
%MATLAB Tensor Toolbox.
%Copyright 2015, Sandia Corporation.

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

m = prod(T.tsize(T.rdims));
n = prod(T.tsize(T.cdims));
if isempty(T.subs)
    A = sparse(m,n);
else
    A = sparse(T.subs(:,1), T.subs(:,2), T.vals, m, n);
end


% ----------------------------------------------------------------------------
% function hfssAssignSlave(fid, Name, ObjName, iUStart, iUEnd, Units,
%                              Master, [Phi], [Theta], [ReverseV])
%
% Description :
% -------------
% Creates the necessary VB Script to assign a Slave Boundary to a given Object.
%
% Parameters :
% ------------
% fid        - file identifier of the HFSS script file.
% Name       - name of the slave boundary (appears under 'Boundaries' in
%              HFSS).
% ObjName    - name of the (sheet-like) object to which the slave boundary
%              is to be assigned.
% iUStart    - (vector) starting point of the U vector. Specify as
%              [x, y, z].
% iUEnd      - (vector) ending point of the U vector. Specify as
%              [x, y, z].
% Units      - specify as 'meter', 'in', 'cm' (defined in HFSS).
% Master     - name of the master boundary to which it is assigned.
% [Phi]      - (degrees, optional) scan angle phi (defauls to 0deg).
% [Theta]    - (degrees, optional) scan angle theta (defaults to 0deg).
% [ReverseV] - (boolean, optional) reverses vector V (defaults to
%              true if the U vector points +y, and to false elsewise)
% Example :
% ---------
% fid = fopen('myantenna.vbs', 'wt');
% ...
% hfssAssignSlave(fid, 'Slave', 'Sheet', [-width/2, 0, 0], ...
%	                 [width/2, 0, 0], 'meter', 'Master', 0, 0, false);
%
% ----------------------------------------------------------------------------

% ----------------------------------------------------------------------------
% CHANGELOG
%
% 21-May-2013: *Initial release (PAG).
% 01-Sep-2020: *Fixed example (DRP).
% 08-Sep-2020: *Added phi and theta as input variables (DRP).
% ----------------------------------------------------------------------------

% ----------------------------------------------------------------------------
% Written by Pablo Alcon Garcia
% pabloalcongarcia@gmail.com / palcon@tsc.uniovi.es
% 21 May 2013
% ----------------------------------------------------------------------------
function hfssAssignSlave(fid, Name, ObjName, iUStart, iUEnd, Units, ...
    Master, Phi, Theta, ReverseV)

% arguments processor.
if (nargin < 10)
    if iUEnd(2)~=iUStart(2)
        ReverseV = true;
    else
        ReverseV = false;
    end
end
if (nargin < 9)
    Theta = 0;
end
if (nargin < 8)
    Phi = 0;
end
if (nargin < 7)
	error('Insufficient # of arguments !');
end

if ReverseV
    ReverseV = 'true';
else
    ReverseV = 'false';
end

% Preamble.
fprintf(fid, '\n');
fprintf(fid, 'Set oModule = oDesign.GetModule("BoundarySetup")\n');

% Parameters
fprintf(fid, 'oModule.AssignSlave _\n');
fprintf(fid, 'Array("NAME:%s", _\n', Name);
fprintf(fid, '\t"Objects:=", Array("%s"), _\n', ObjName);
fprintf(fid, '\tArray("NAME:CoordSysVector", "Origin:=", _\n');
fprintf(fid, '\t\tArray("%f%s", "%f%s", "%f%s"), _\n', ...
        iUStart(1), Units, iUStart(2), Units, iUStart(3), Units);
fprintf(fid, '\t\t"UPos:=", Array("%f%s", "%f%s", "%f%s") _\n', ...
        iUEnd(1), Units, iUEnd(2), Units, iUEnd(3), Units);
fprintf(fid, '\t\t), _\n');
fprintf(fid, '\t"ReverseV:=", %s, _\n', ReverseV);
fprintf(fid, '\t"Master:=", "%s", _\n', Master);
fprintf(fid, '\t"UseScanAngles:=", true, _\n');
fprintf(fid, '\t\t"Phi:=", "%fdeg", "Theta:=", "%fdeg" _\n', Phi, Theta);
fprintf(fid, '\t)\n');


function nii=nii2jnii(filename, format, varargin)
%
%    nii=nii2jnii(niifile, format, options)
%       or
%    nii2jnii(niifile, jniifile, options)
%    nii=nii2jnii(niifile)
%
%    A fast and portable NIFTI-1/2 and Analyze7.5 file parser and converter
%    to the text and binary JNIfTI formats defined in JNIfTI specification:
%    https://github.com/fangq/jnifti
%
%    This function is compatible with both MATLAB and GNU Octave.
%    It accepts .nii, .nii.gz, .hdr/.img and .hdr.gz/.img.gz input files
%
%    author: Qianqian Fang (q.fang <at> neu.edu)
%
%    input:
%        fname: the file name to the .nii, .nii.gz, .hdr/.img or .hdr.gz/.img.gz file
%        format:'nii' for reading the NIfTI-1/2/Analyze files;
%               'jnii' to convert the nii data into an in-memory JNIfTI structure.
%               'niiheader' return only the nii header without the image data
%
%               if format is not listed above and nii2jnii is called without
%               an output, format must be a string specifying the output JNIfTI
%               file name - *.jnii for text-based JNIfTI, or *.bnii for the
%               binary version
%        options: (optional) if saving to a .bnii file, please see the options for
%               savebj.m (part of JSONLab); if saving to .jnii, please see the
%               supported options for savejson.m (part of JSONLab).
%
%    output:
%        if the output is a JNIfTI data structure, it has the following subfield:
%          nii.NIFTIHeader -  a structure containing the 1-to-1 mapped NIFTI-1/2 header
%          nii.NIFTIData - the main image data array
%          nii.NIFTIExtension - a cell array contaiing the extension data buffers
%
%        when calling as nii=nii2jnii(file,'nii'), the output is a NIFTI object containing
%          nii.img: the data volume read from the nii file
%          nii.datatype: the data type of the voxel, in matlab data type string
%          nii.datalen: data count per voxel - for example RGB data has 3x
%                    uint8 per voxel, so datatype='uint8', datalen=3
%          nii.voxelbyte: total number of bytes per voxel: for RGB data,
%                    voxelbyte=3; also voxelbyte=header.bitpix/8
%          nii.hdr: file header info, a structure has the full nii header
%                    key subfileds include
%
%              sizeof_hdr: must be 348 (for NIFTI-1) or 540 (for NIFTI-2)
%              dim: short array, dim(2: dim(1)+1) defines the array size
%              datatype: the type of data stored in each voxel
%              bitpix: total bits per voxel
%              magic: must be 'ni1\0' or 'n+1\0'
%
%              For the detailed nii header, please see
%              https://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h
%
%    dependency:
%          No external dependency if reading .nii/.hdr/.img files;
%
%          To load gzipped input files (.nii.gz/.hdr.gz/.img.gz), one must
%          install the ZMat Toolbox (http://github.com/fangq/zmat) and
%          JSONLab Toolbox (http://github.com/fangq/jsonlab);
%
%          To save files into the text/binary JNIfTI formatted files, one
%          need to install JSONLab (http://github.com/fangq/jsonlab).
%
%    this file was initially developed for the MCX project: https://github.com/fangq/mcx/blob/master/utils/mcxloadnii.m
%
%    this file is part of JNIfTI specification: https://github.com/fangq/jnifti
%
%    License: Apache 2.0, see https://github.com/fangq/jnifti for details
%

hdrfile=filename;
isnii=-1;
if(regexp(filename,'(\.[Hh][Dd][Rr](\.[Gg][Zz])*$|\.[Ii][Mm][Gg](\.[Gg][Zz])*$)'))
    isnii=0;
elseif(regexp(filename,'\.[Nn][Ii][Ii](\.[Gg][Zz])*$'))
    isnii=1;
end

if(isnii<0)
    error('file must be a NIfTI (.nii/.nii.gz) or Analyze 7.5 (.hdr/.img,.hdr.gz/.img.gz) data file');
end

if(regexp(filename,'\.[Ii][Mm][Gg](\.[Gg][Zz])*$'))
    hdrfile=regexprep(filename,'\.[Ii][Mm][Gg](\.[Gg][Zz])*$','.hdr$1');
end

niftiheader=niiformat('nifti1');

if(~isempty(regexp(hdrfile,'\.[Gg][Zz]$', 'once')) || (exist('OCTAVE_VERSION','builtin')~=0))
    finput=fopen(hdrfile,'rb');
    input=fread(finput,inf,'uint8=>uint8');
    fclose(finput);

    if(regexp(hdrfile,'\.[Gg][Zz]$'))
        if(~exist('gzipdecode','file'))
            error('To process zipped files, you must install gzipdecode.m from the JSONLab toolbox: http://github.com/fangq/jsonlab');
        end
        gzdata=gzipdecode(input);
    else
        gzdata=input;
    end
    clear input;
    nii.hdr=memmapstream(gzdata,niftiheader);
else
    fileinfo=dir(hdrfile);
    if(isempty(fileinfo))
        error('specified file does not exist');
    end
    header = memmapfile(hdrfile,             ...
       'Offset', 0,                          ...
       'Writable', false,                    ...
       'Format', niftiheader(1:end-(fileinfo.bytes<352),:));

    nii.hdr=header.Data(1);
end

[os,maxelem,dataendian]=computer;

if(nii.hdr.sizeof_hdr~=348 && nii.hdr.sizeof_hdr~=540)
    nii.hdr.sizeof_hdr=swapbytes(nii.hdr.sizeof_hdr);
end

if(nii.hdr.sizeof_hdr==540) % NIFTI-2 format
    niftiheader=niiformat('nifti2');
    if(exist('gzdata','var'))
        nii.hdr=memmapstream(gzdata,niftiheader);
    else
        header = memmapfile(hdrfile,                ...
         'Offset', 0,                           ...
         'Writable', false,                     ...
         'Format', niftiheader(1:end-(fileinfo.bytes<352),:));

         nii.hdr=header.Data(1);
    end
end

if(nii.hdr.dim(1)>7)
    names=fieldnames(nii.hdr);
    for i=1:length(names)
        nii.hdr.(names{i})=swapbytes(nii.hdr.(names{i}));
    end
    if(nii.hdr.sizeof_hdr>540)
        nii.hdr.sizeof_hdr=swapbytes(nii.hdr.sizeof_hdr);
    end
    if(dataendian=='B')
        dataendian='little';
    else
        dataendian='big';
    end
end

type2byte=[
        0  0  % unknown                      %
        1  0  % binary (1 bit/voxel)         %
        2  1  % unsigned char (8 bits/voxel) %
        4  2  % signed short (16 bits/voxel) %
        8  4  % signed int (32 bits/voxel)   %
       16  4  % float (32 bits/voxel)        %
       32  8  % complex (64 bits/voxel)      %
       64  8  % double (64 bits/voxel)       %
      128  3  % RGB triple (24 bits/voxel)   %
      255  0  % not very useful (?)          %
      256  1  % signed char (8 bits)         %
      512  2  % unsigned short (16 bits)     %
      768  4  % unsigned int (32 bits)       %
     1024  8  % long long (64 bits)          %
     1280  8  % unsigned long long (64 bits) %
     1536 16  % long double (128 bits)       %
     1792 16  % double pair (128 bits)       %
     2048 32  % long double pair (256 bits)  %
     2304  4  % 4 byte RGBA (32 bits/voxel)  %
];

type2str={
    'uint8'    0   % unknown                       %
    'uint8'    0   % binary (1 bit/voxel)          %
    'uint8'    1   % unsigned char (8 bits/voxel)  %
    'uint16'   1   % signed short (16 bits/voxel)  %
    'int32'    1   % signed int (32 bits/voxel)    %
    'single'   1   % float (32 bits/voxel)         %
    'single'   2   % complex (64 bits/voxel)       %
    'double'   1   % double (64 bits/voxel)        %
    'uint8'    3   % RGB triple (24 bits/voxel)    %
    'uint8'    0   % not very useful (?)           %
    'int8'     1   % signed char (8 bits)          %
    'uint16'   1   % unsigned short (16 bits)      %
    'uint32'   1   % unsigned int (32 bits)        %
    'int64'    1   % long long (64 bits)           %
    'uint64'   1   % unsigned long long (64 bits)  %
    'uint8'    16  % long double (128 bits)        %
    'uint8'    16  % double pair (128 bits)        %
    'uint8'    32  % long double pair (256 bits)   %
    'uint8'    4   % 4 byte RGBA (32 bits/voxel)   %
};

typeidx=find(type2byte(:,1)==nii.hdr.datatype);

nii.datatype=type2str{typeidx,1};
nii.datalen=type2str{typeidx,2};
nii.voxelbyte=type2byte(typeidx,2);

if(type2byte(typeidx,2)==0)
    nii.img=[];
    return;
end

if(type2str{typeidx,2}>1)
    nii.hdr.dim=[nii.hdr.dim(1)+1 uint16(nii.datalen) nii.hdr.dim(2:end)];
end

if(nargin>1 && strcmp(format,'niiheader'))
    return;
end

if(regexp(filename,'\.[Hh][Dd][Rr](\.[Gg][Zz])*$'))
    filename=regexprep(filename,'\.[Hh][Dd][Rr](\.[Gg][Zz])*$','.img$1');
end

imgbytenum=prod(nii.hdr.dim(2:nii.hdr.dim(1)+1))*nii.voxelbyte;

if(isnii==0 && ~isempty(regexp(filename,'\.[Gg][Zz]$', 'once')))
    finput=fopen(filename,'rb');
    input=fread(finput,inf,'uint8=>uint8');
    fclose(finput);
    gzdata=gzipdecode(input);
    nii.img=typecast(gzdata(1:imgbytenum),nii.datatype);
else
    if(~exist('gzdata','var'))
        fid=fopen(filename,'rb');
        if(isnii)
            fseek(fid,nii.hdr.vox_offset,'bof');
        end
        nii.img=fread(fid,imgbytenum,[nii.datatype '=>' nii.datatype]);
        fclose(fid);
    else
        nii.img=typecast(gzdata(nii.hdr.vox_offset+1:nii.hdr.vox_offset+imgbytenum),nii.datatype);
    end
end

nii.img=reshape(nii.img,nii.hdr.dim(2:nii.hdr.dim(1)+1));

if(nargin>1 && strcmp(format,'nii'))
    return;
end

nii0=nii;
nii=struct();
nii.NIFTIHeader.NIIHeaderSize=  nii0.hdr.sizeof_hdr;
if(isfield(nii0.hdr,'data_type'))
    nii.NIFTIHeader.A75DataTypeName=deblank(char(nii0.hdr.data_type));
    nii.NIFTIHeader.A75DBName=      deblank(char(nii0.hdr.db_name));
    nii.NIFTIHeader.A75Extends=     nii0.hdr.extents;
    nii.NIFTIHeader.A75SessionError=nii0.hdr.session_error;
    nii.NIFTIHeader.A75Regular=     nii0.hdr.regular;
end
nii.NIFTIHeader.DimInfo.Freq=   bitand(nii0.hdr.dim_info,7);
nii.NIFTIHeader.DimInfo.Phase=  bitand(bitshift(nii0.hdr.dim_info,-3),7);
nii.NIFTIHeader.DimInfo.Slice=  bitand(bitshift(nii0.hdr.dim_info,-6),7);
nii.NIFTIHeader.Dim=            nii0.hdr.dim(2:2+nii0.hdr.dim(1)-1);
nii.NIFTIHeader.Param1=         nii0.hdr.intent_p1;
nii.NIFTIHeader.Param2=         nii0.hdr.intent_p2;
nii.NIFTIHeader.Param3=         nii0.hdr.intent_p3;
nii.NIFTIHeader.Intent=         niicodemap('intent',nii0.hdr.intent_code);
nii.NIFTIHeader.DataType=       niicodemap('datatype',nii0.hdr.datatype);
nii.NIFTIHeader.BitDepth=       nii0.hdr.bitpix;
nii.NIFTIHeader.FirstSliceID=   nii0.hdr.slice_start;
nii.NIFTIHeader.VoxelSize=      nii0.hdr.pixdim(2:2+nii0.hdr.dim(1)-1);
nii.NIFTIHeader.Orientation=    struct('x','r','y','a','z','s');
if(nii0.hdr.pixdim(1)<0)
    nii.NIFTIHeader.Orientation=    struct('x','l','y','a','z','s');
end
nii.NIFTIHeader.NIIByteOffset=  nii0.hdr.vox_offset;
nii.NIFTIHeader.ScaleSlope=     nii0.hdr.scl_slope;
nii.NIFTIHeader.ScaleOffset=    nii0.hdr.scl_inter;
nii.NIFTIHeader.LastSliceID=    nii0.hdr.slice_end;
nii.NIFTIHeader.SliceType=      niicodemap('slicetype',nii0.hdr.slice_code);
nii.NIFTIHeader.Unit.L=         niicodemap('unit',bitand(nii0.hdr.xyzt_units, 7));
nii.NIFTIHeader.Unit.T=         niicodemap('unit',bitand(nii0.hdr.xyzt_units, 56));
nii.NIFTIHeader.MaxIntensity=   nii0.hdr.cal_max;
nii.NIFTIHeader.MinIntensity=   nii0.hdr.cal_min;
nii.NIFTIHeader.SliceTime=      nii0.hdr.slice_duration;
nii.NIFTIHeader.TimeOffset=     nii0.hdr.toffset;
if(isfield(nii0.hdr,'glmax'))
    nii.NIFTIHeader.A75GlobalMax=   nii0.hdr.glmax;
    nii.NIFTIHeader.A75GlobalMin=   nii0.hdr.glmin;
end
nii.NIFTIHeader.Description=    deblank(char(nii0.hdr.descrip));
nii.NIFTIHeader.AuxFile=        deblank(char(nii0.hdr.aux_file));
nii.NIFTIHeader.QForm=          nii0.hdr.qform_code;
nii.NIFTIHeader.SForm=          nii0.hdr.sform_code;
nii.NIFTIHeader.Quatern.b=      nii0.hdr.quatern_b;
nii.NIFTIHeader.Quatern.c=      nii0.hdr.quatern_c;
nii.NIFTIHeader.Quatern.d=      nii0.hdr.quatern_d;
nii.NIFTIHeader.QuaternOffset.x=nii0.hdr.qoffset_x;
nii.NIFTIHeader.QuaternOffset.y=nii0.hdr.qoffset_y;
nii.NIFTIHeader.QuaternOffset.z=nii0.hdr.qoffset_z;
nii.NIFTIHeader.Affine(1,:)=    nii0.hdr.srow_x;
nii.NIFTIHeader.Affine(2,:)=    nii0.hdr.srow_y;
nii.NIFTIHeader.Affine(3,:)=    nii0.hdr.srow_z;
nii.NIFTIHeader.Name=           deblank(char(nii0.hdr.intent_name));
nii.NIFTIHeader.NIIFormat=      deblank(char(nii0.hdr.magic));
if(isfield(nii0.hdr,'extension'))
    nii.NIFTIHeader.NIIExtender=    nii0.hdr.extension;
end
nii.NIFTIHeader.NIIQfac_=       nii0.hdr.pixdim(1);
nii.NIFTIHeader.NIIEndian_=     dataendian;
if(isfield(nii0.hdr,'reserved'))
    nii.NIFTIHeader.NIIUnused_= nii0.hdr.reserved;
end

nii.NIFTIData=nii0.img;

if(isfield(nii0.hdr,'extension') && nii0.hdr.extension(1)>0)
    fid=fopen(filename,'rb');
    fseek(fid,nii0.hdr.sizeof_hdr+4,'bof');
    nii.NIFTIExtension=cell(1);
    count=1;
    while(ftell(fid)<nii0.hdr.vox_offset)
       nii.NIFTIExtension{count}.Size=fread(fid,1,'int32=>int32');
       nii.NIFTIExtension{count}.Type=fread(fid,1,'int32=>int32');
       if(strcmp(dataendian,'big'))
           nii.NIFTIExtension{count}.Size=swapbytes(nii.NIFTIExtension{count}.Size);
           nii.NIFTIExtension{count}.Type=swapbytes(nii.NIFTIExtension{count}.Type);
       end
       nii.NIFTIExtension{count}.x0x5F_ByteStream_=fread(fid,nii.NIFTIExtension{count}.Size-8,'uint8=>uint8');
       count=count+1;
    end
    fclose(fid);
end

if(nargout==0 && strcmp(format,'nii')==0 && strcmp(format,'jnii')==0)
    if(~exist('savejson','file'))
        error('you must first install JSONLab from http://github.com/fangq/jsonlab/');
    end
    if(regexp(format,'\.jnii$'))
        savejson('',nii,'FileName',format,varargin{:});
    elseif(regexp(format,'\.bnii$'))
        savebj('',nii,'FileName',format,varargin{:});
    else
        error('file suffix must be .jnii for text JNIfTI or .bnii for binary JNIfTI');
    end
end