function dat = one_class_loss(algo,dat)

  [x y]=get_xy(dat);

  y = ones(size(x));
  lss=sum((x~=y))/length(y);

  dat=data([get_name(dat) ' -> one_class_loss='  num2str(lss,4) ],[],lss);


function [f,h] = kafbox_profiler_plotconvergence(algorithms,...
    mse_curves,resinds)

figure; hold all
set(gcf,'Position',[200, 200, 500 300])

titles = cell(length(algorithms),1);

for i=1:size(resinds,1)
    algo = algorithms{resinds(i,1)};

    ls = '-'; % line style
    if isfield(algo.figstyle,'line')
        ls = algo.figstyle.line;
    end

    lw = 1; % line width
    if isfield(algo.figstyle,'linewidth')
        lw = algo.figstyle.linewidth;
    end

    curve = mse_curves{resinds(i,1)}{resinds(i,2)};
    xs= ~isnan(curve);
    inds = 1:length(mse_curves{resinds(i,1)}{resinds(i,2)});
    plot(inds(xs),10*log10(curve(xs)),'color',algo.figstyle.color,...
        'LineWidth',lw,'LineStyle',ls)

    titles{i} = algo.name;
end

h = legend(titles);
grid on; box on
xlabel('iteration');
ylabel('(N)MSE');

% Expand figure axes
f = gcf;
style = hgexport('factorystyle'); style.Bounds = 'tight';
hgexport(f,'-clipboard',style,'applystyle', true);
drawnow;


function recall = boxesEval( varargin )
% Perform object proposal bounding box evaluation and plot results.
%
% boxesEval evaluates a set bounding box object proposals on the dataset
% specified by the 'data' parameter (which is generated by boxesData.m).
% The methods are specified by the vector 'names'. For each method the
% boxes must be stored in the file [resDir '/' name '-' data.split]. Each
% file should contain a single cell array 'bbs' of length n, with one set
% of bbs per image, where each matrix row has the format [x y w h score].
% Here score is the confidence of detection but if the boxes are sorted the
% score may be the same for every box. edgeBoxes.m stores results in this
% format by default, other methods can easily be converted to this format.
%
% For every method, evaluation is performed at every threshold in 'thrs'
% and every proposal count in 'cnts'. Two plots may be generated. If
% |cnts|>1 creates a plot with count on x-axis (and plots a separate set of
% curves for each threshold if necessary). If |thrs|>1 creates a plot with
% thresholds on x-axis (and plots a separate set of curves for each count).
%
% USAGE
%  recall = boxesEval( opts )
%
% INPUTS
%  opts       - parameters (struct or name/value pairs)
%   .data       - ['REQ'] data on which to evaluate (see boxesData.m)
%   .names      - ['REQ'] string cell array of object proposal methods
%   .resDir     - ['boxes/'] location for results and evaluation
%   .thrs       - [.7] IoU threshold(s) to use for evaluation
%   .cnts       - [...] propsal count(s) to use for evaluation
%   .maxn       - [inf] maximum number of images to use for evaluation
%   .show       - [1] figure for plotting results
%   .fName      - [''] optional filename for saving plots/recall to disk
%   .col        - [...] color(s) for plotting each method's results
%
% OUTPUTS
%  recall     - [MxTxK] recall for each count/threshold/method
%
% EXAMPLE
%
% See also edgeBoxesDemo, edgeBoxes, boxesData, bbGt
%
% Structured Edge Detection Toolbox      Version 3.01
% Code written by Piotr Dollar and Larry Zitnick, 2014.
% Licensed under the MSR-LA Full Rights License [see license.txt]

cnts=[1 2 5 10 20 50 100 200 500 1000 2000 5000]; col=cell(100,1);
for i=1:100, col{i}=max(.3,mod([.3 .47 .16]*(i+1),1)); end
dfs={ 'data','REQ', 'names','REQ', 'resDir','boxes/', 'thrs',.7, ...
  'cnts',cnts, 'maxn',inf, 'show',1, 'fName','', 'col',col };
o=getPrmDflt(varargin,dfs,1); if(~iscell(o.names)), o.names={o.names}; end
recall=boxesEvalAll(o); if(o.show), plotResult(recall,o); end

end

function recall = boxesEvalAll( o )
% compute and gather all results (caches individual results to disk)
M=length(o.cnts); T=length(o.thrs); K=length(o.names);
gt=o.data.gt; n=min(o.maxn,o.data.n); gt=gt(1:n);
recall=zeros(M,T,K); [ms,ts,ks]=ndgrid(1:M,1:T,1:K);
parfor i=1:M*T*K, m=ms(i); t=ts(i); k=ks(i);
  % if evaluation result exists simply load it
  rdir=[o.resDir '/eval/' o.names{k} '/' o.data.split '/'];
  rnm=[rdir 'N' int2str2(n,5) '-W' int2str2(o.cnts(m),5) ...
    '-T' int2str2(round(o.thrs(t)*100),2) '.txt']; %#ok<*PFBNS>
  if(exist(rnm,'file')), recall(i)=load(rnm,'-ascii'); continue; end
  % perform evaluation if result does not exist
  bbs=load([o.resDir '/' o.names{k} '-' o.data.split]); bbs=bbs.bbs;
  bbs1=bbs(1:n); for j=1:n, bbs1{j}=bbs1{j}(1:min(end,o.cnts(m)),:); end
  [gt1,bbs1]=bbGt('evalRes',gt,bbs1,o.thrs(t));
  [~,r]=bbGt('compRoc',gt1,bbs1,1); r=max(r); recall(i)=r;
  if(~exist(rdir,'dir')), mkdir(rdir); end; dlmwrite(rnm,r);
end
% display summary statistics
[ts,ks]=ndgrid(1:T,1:K); ms=log(o.cnts); rt=.75;
for i=1:T*K, t=ts(i); k=ks(i); r=recall(:,t,k)'; if(M==1), continue; end
  a=find(rt<=r); if(isempty(a)), m=inf; else a=a(1); b=a-1;
    m=round(exp((rt-r(b))/(r(a)-r(b))*(ms(a)-ms(b))+ms(b))); end
  auc=sum(diff(ms/ms(end)).*(r(1:end-1)+r(2:end))/2);
  fprintf('%15s  T=%.2f  A=%.2f  M=%4i  R=%.2f\n',...
    o.names{k},o.thrs(t),auc,m,max(r));
end
% optionally save results to text file
if(isempty(o.fName)), return; end
d=[o.resDir '/plots/']; if(~exist(d,'dir')), mkdir(d); end
dlmwrite([d o.fName '-' o.data.split '.txt'],squeeze(recall));
end

function plotResult( recall, o )
% plot results
[M,T,K]=size(recall); fSiz={'FontSize',12}; f=o.show;
for type=1:2
  if(type==1), xs=o.cnts; else xs=o.thrs; end;
  if(length(xs)==1), continue; end; s=[T,M]; M=s(type);
  R=recall; if(type==2), R=permute(R,[2 1 3]); end
  figure(f); f=f+1; clf; hold on; hs=zeros(M,K);
  for i=1:M, for k=1:K, hs(i,k)=plot(xs,R(:,i,k),...
        'Color',o.col{k},'LineWidth',3); end; end
  s={'# of proposals','IoU'}; xlabel(s{type},fSiz{:});
  s={'log','linear'}; set(gca,'XScale',s{type});
  ylabel('Detection Rate',fSiz{:}); set(gca,'YTick',0:.2:1);
  hold off; axis([min(xs) max(xs) 0 1]); grid on; set(gca,fSiz{:});
  set(gca,'XMinorGrid','off','XMinorTic','off');
  set(gca,'YMinorGrid','off','YMinorTic','off');
  s={'nw','ne'}; legend(hs(1,:),o.names,'Location',s{type});
  if(isempty(o.fName)), continue; end; s={'Cnt','IoU'};
  savefig([o.resDir '/plots/' s{type} '-' o.data.split '-' o.fName],'png');
end
end


function [frames, descrs] = vl_phow(im, varargin)
% VL_PHOW  Extract PHOW features
%   [FRAMES, DESCRS] = VL_PHOW(IM) extracts PHOW features from the
%   image IM. This function is a wrapper around VL_DSIFT() and
%   VL_IMSMOOTH().
%
%   The PHOW descriptors where introduced in [1]. By default,
%   VL_PHOW() computes the gray-scale variant of the descriptor.  The
%   COLOR option can be used to compute the color variant instead.
%
%   Verbose:: [false]
%     Set to true to turn on verbose output.
%
%   Sizes:: [[4 6 8 10]]
%     Scales at which the dense SIFT features are extracted. Each
%     value is used as bin size for the VL_DSIFT() function.
%
%   Fast:: [true]
%     Set to false to turn off the fast SIFT features computation by
%     VL_DSIFT().
%
%   Step:: [2]
%     Step (in pixels) of the grid at which the dense SIFT features
%     are extracted.
%
%   Color:: [GRAY]
%     Choose between GRAY (PHOW-gray), RGB, HSV, and OPPONENT
%     (PHOW-color).
%
%   ContrastThreshold:: [0.005]
%     Contrast threshold below which SIFT features are mapped to
%     zero. The input image is scaled to have intensity range in [0,1]
%     (rather than [0,255]) and this value is compared to the
%     descriptor norm as returned by VL_DSIFT().
%
%   WindowSize:: [1.5]
%     Size of the Gaussian window in units of spatial bins.
%
%   Magnif:: [6]
%     The image is smoothed by a Gaussian kernel of standard deviation
%     SIZE / MAGNIF.
%
%   FloatDescriptors:: [false]
%     If set to TRUE, the descriptors are returned in floating point
%     format.
%
%   See also: VL_DSIFT(), VL_HELP().

% Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

% -------------------------------------------------------------------
%                                                 Parse the arguments
% -------------------------------------------------------------------

  opts.verbose = false ;
  opts.fast = true ;
  opts.sizes = [4 6 8 10] ;
  opts.step = 2 ;
  opts.color = 'gray' ;
  opts.floatdescriptors = false ;
  opts.magnif = 6 ;
  opts.windowsize = 1.5 ;
  opts.contrastthreshold = 0.005 ;
  opts = vl_argparse(opts,varargin) ;

  dsiftOpts = {'norm', 'windowsize', opts.windowsize} ;
  if opts.verbose, dsiftOpts{end+1} = 'verbose' ; end
  if opts.fast, dsiftOpts{end+1} = 'fast' ; end
  if opts.floatdescriptors, dsiftOpts{end+1} = 'floatdescriptors' ; end
  dsiftOpts(end+(1:2)) = {'step', opts.step} ;

% -------------------------------------------------------------------
%                                                Extract the features
% -------------------------------------------------------------------

  % standarize the image
  imageSize = [size(im,2) ; size(im,1)] ;
  if strcmp(lower(opts.color), 'gray')
    numChannels = 1 ;
    if size(im,3) > 1, im = rgb2gray(im) ; end
  else
    numChannels = 3 ;
    if size(im,3) == 1, im = cat(3, im, im, im) ; end
    switch lower(opts.color)
      case 'rgb'
      case 'opponent'
        % Note that the mean differs from the standard definition of opponent
        % space and is the regular intesity (for compatibility with
        % the contrast thresholding).
        %
        % Note also that the mean is added pack to the other two
        % components with a small multipliers for monochromatic
        % regions.
        mu = 0.3*im(:,:,1) + 0.59*im(:,:,2) + 0.11*im(:,:,3) ;
        alpha = 0.01 ;
        im = cat(3, mu, ...
                 (im(:,:,1) - im(:,:,2))/sqrt(2) + alpha*mu, ...
                 (im(:,:,1) + im(:,:,2) - 2*im(:,:,3))/sqrt(6) + alpha*mu) ;
      case 'hsv'
        im = rgb2hsv(im) ;
      otherwise
        opts.color = 'hsv' ;
        warning('Color space not recongized, defaulting to HSV color space.') ;
    end
  end

  if opts.verbose
    fprintf('%s: color space: %s\n', mfilename, opts.color) ;
    fprintf('%s: image size: %d x %d\n', mfilename, imageSize(1), imageSize(2)) ;
    fprintf('%s: sizes: [%s]\n', mfilename, sprintf(' %d', opts.sizes)) ;
  end

  for si = 1:length(opts.sizes)

    % Recall from VL_DSIFT() that the first descriptor for scale SIZE has
    % center located at XC = XMIN + 3/2 SIZE (the Y coordinate is
    % similar). It is convenient to align the descriptors at different
    % scales so that they have the same geometric centers. For the
    % maximum size we pick XMIN = 1 and we get centers starting from
    % XC = 1 + 3/2 MAX(OPTS.SIZES). For any other scale we pick XMIN so
    % that XMIN + 3/2 SIZE = 1 + 3/2 MAX(OPTS.SIZES).
    %
    % In pracrice, the offset must be integer ('bounds'), so the
    % alignment works properly only if all OPTS.SZES are even or odd.

    off = floor(1 + 3/2 * (max(opts.sizes) - opts.sizes(si))) ;

    % smooth the image to the appropriate scale based on the size
    % of the SIFT bins
    sigma = opts.sizes(si) / opts.magnif ;
    ims = vl_imsmooth(im, sigma) ;

    % extract dense SIFT features from all channels
    for k = 1:numChannels
      [f{k}, d{k}] = vl_dsift(...
        ims(:,:,k), ...
        dsiftOpts{:},  ...
        'size', opts.sizes(si), ...
        'bounds', [off off +inf +inf]) ;
    end

    % remove low contrast descriptors
    % note that for color descriptors the V component is
    % thresholded
    switch opts.color
      case {'gray', 'opponent'}
        contrast = f{1}(3,:) ;
      case 'rgb'
        contrast = mean([f{1}(3,:) ; f{2}(3,:) ; f{3}(3,:)],1) ;
      otherwise % hsv
        contrast = f{3}(3,:) ;
    end
    for k = 1:numChannels
      d{k}(:, contrast < opts.contrastthreshold) = 0 ;
    end

    % save only x,y, and the scale
    frames{si} = [f{1}(1:3, :) ; opts.sizes(si) * ones(1,size(f{1},2))] ;
    descrs{si} = cat(1, d{:}) ;
  end
  descrs = cell2mat(descrs) ;
  frames = cell2mat(frames) ;
end


function output = callscs(model)
originalModel = model;
% *********************************************
% Bounded variables converted to constraints
% N.B. Only happens when caller is BNB
% *********************************************
if ~isempty(model.ub)
    [model.F_struc,model.K] = addStructureBounds(model.F_struc,model.K,model.ub,model.lb);
end

% Write nonlinear functions using exponential cone operators, if possible
[model,output] = normalizeExponentialCone(model);
if output.problem
    return
end

% Map to SCS format
data.A = -model.F_struc(:,2:end);
data.b = full(model.F_struc(:,1));
data.c = full(model.c);
cones = [];
cones.f = model.K.f;
cones.l = model.K.l;
cones.q = model.K.q;
cones.s = model.K.s;
cones.ep = model.K.e;

params = model.options.scs;
params.verbose = model.options.verbose;

if params.eliminateequalities
    tempmodel.F_struc = [data.b -data.A];
    tempmodel.c = data.c;
    tempmodel.K = cones;
    [tempmodel,xsol,H] =  removeequalitiesinmodel(tempmodel);
    data.b = full(tempmodel.F_struc(:,1));
    data.A = -tempmodel.F_struc(:,2:end);
    data.c = full(tempmodel.c);
    cones = tempmodel.K;
else
    H = 1;
    xsol = 0;
end

% Extract lower diagonal form for new SCS format
if ~isempty(cones.s) && any(cones.s)
    sdpA = data.A(1+cones.l + cones.f+sum(cones.q):end,:);
    sdpb = data.b(1+cones.l + cones.f+sum(cones.q):end,:);
    expA = data.A(end-3*cones.ep+1:end,:);
    expb = data.b(end-3*cones.ep+1:end,:);
    data.A = data.A(1:cones.l + cones.f+sum(cones.q),:);
    data.b = data.b(1:cones.l + cones.f+sum(cones.q),:);
    top = 1;
    for i = 1:length(cones.s)
        A = sdpA(top:top + cones.s(i)^2-1,:);
        b = sdpb(top:top + cones.s(i)^2-1,:);
        n = cones.s(i);
        ind = find(speye(n));
        b(ind) = b(ind)/sqrt(2);
        A(ind,:) = A(ind,:)/sqrt(2);
        ind = find(tril(ones(n)));
        A = A(ind,:);
        b = b(ind);
        data.A = [data.A;A];
        data.b = [data.b;b];
        top = top  + cones.s(i)^2;
    end
    data.A = [data.A;expA];
    data.b = [data.b;expb];
end

if model.options.savedebug
    save scsdebug data cones params
end

if model.options.showprogress;showprogress(['Calling ' model.solver.tag],model.options.showprogress);end
t = tic;
problem = 0;
switch  model.solver.tag
    case 'scs-direct'
         [x_s,y_s,s,info] = scs_direct(data,cones,params);
    otherwise
        if params.gpu == true
            [x_s,y_s,s,info] = scs_gpu(data,cones,params);
        else
            [x_s,y_s,s,info] = scs_indirect(data,cones,params);
        end
end
solvertime = toc(t);

% Internal format. Only recover the original variables
Primal = H*x_s+xsol;
Primal = Primal(1:length(originalModel.c));
if ~isempty(model.evalMap)
    % No support for duals when exponential cones yet
    Dual = [];
else
    % Map to full format from tril
    Dual = y_s(1:cones.f+cones.l+sum(cones.q));
    if ~isempty(cones.s) && any(cones.s)
        top = 1 + cones.f + cones.l + sum(cones.q);
        for i = 1:length(cones.s)
            n = cones.s(i);
            sdpdual = y_s(top:top + n*(n+1)/2-1,:);
            Z = zeros(n);
            Z(find(tril(ones(n)))) = sdpdual;
            Z = (Z + Z')/2;
            ind = find(speye(n));
            Z(ind) = Z(ind)/sqrt(2);
            Dual = [Dual;Z(:)];
            top = top  + n*(n+1)/2;
        end
    end
end

if nnz(data.c)==0 && isequal(info.status,'Unbounded/Inaccurate')
    info.status = 'Infeasible';
end

switch info.status
    case 'Solved'
        problem = 0;
    case 'Infeasible'
        problem = 1;
     case 'Unbounded'
        problem = 2;
    otherwise
        status = 9;
end

infostr = yalmiperror(problem,model.solver.tag);

% Save ALL data sent to solver
if model.options.savesolverinput
    solverinput.data = data;
    solverinput.cones = cones;
    solverinput.params = params;
else
    solverinput = [];
end

% Save ALL data from the solution?
if model.options.savesolveroutput
    solveroutput.x = x_s;
    solveroutput.y = y_s;
    solveroutput.s = s;
    solveroutput.info = info;
else
    solveroutput = [];
end

% Standard interface
output = createOutputStructure(Primal,Dual,[],problem,infostr,solverinput,solveroutput,solvertime);

function [model,x0,H] = removeequalitiesinmodel(model)

if model.K.f > 0
    % Extract the inequalities
    A_equ = model.F_struc(1:model.K.f,2:end);
    b_equ = -model.F_struc(1:model.K.f,1);

    if 1
        % Find a basis for the column space of A_equ
        [L,U,P] = lu(A_equ');
        r = colspaces(L');
        AA = L';
        H1 = AA(:,r);
        H2 = AA(:,setdiff(1:size(AA,2),r));
        try
            x0 = P'*linsolve(full(L'),linsolve(full(U'),full(b_equ),struct('LT',1==1)),struct('UT',1==1));
        catch
            x0 = A_equ\b_equ;
        end
        % FIX : use L and U stupid!
        H = P'*[-H1\H2;eye(size(H2,2))];

    else
        H = null(full(A_equ));
        x0 = A_equ\b_equ;
    end

    model.c = H'*model.c;
    model.F_struc(:,1) = model.F_struc(:,1) + model.F_struc(:,2:end)*x0;
    model.F_struc = [model.F_struc(:,1) model.F_struc(:,2:end)*H];
    model.F_struc(1:model.K.f,:)=[];
    model.K.f = 0;
else
    H = speye(length(model.c));
    x0 = zeros(length(model.c),1);
end

function  [indx]=colspaces(A)
indx = [];
for i = 1:size(A,2)
    s = max(find(A(:,i)));
    indx = [indx s];
end
indx = unique(indx);


classdef FourierComponent
% This class is obsolet since MTEX 5.9. Use the class @SO3FunHarmonic instead.
% Anyway the class is preserved, so that saved @ODFs can be loaded.

methods (Static = true, Hidden=true)
  function odf = loadobj(s)
    fhat = s.f_hat;
    CS = s.CS;
    SS = s.SS;
    if isempty(fhat), fhat = 0; end
    if isempty(CS), CS = crystalSymmetry; end
    if isempty(SS), SS = specimenSymmetry; end
    odf = SO3FunHarmonic(fhat);
    % We use L2-normalized Wigner-D functions since MTEX Version 5.9.
    odf = L2normalizeFourierCoefficients(odf);
    % The ODFs has been real valued before MTEX verison 5.9.
    odf.isReal = 1;
    % do not symmetrise odf by defining the symmetries.
    odf.CS = CS;
    odf.SS = SS;
  end
end

end


%ISAFFINE Test affine mapping
%
%    I = ISAFFINE(W)
%    ISAFFINE(W)
%
% I is true if W is an affine mapping.
% If called without an output argument ISAFFINE generates an error
% if W is not an affine mapping.


function dat=readinr(fname)
%
% vol=readinr(fname)
%
% load a volume from an INR file
%
% author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
% date: 2009/05/03
%
% input:
%      fname: input file name
%
% output:
%      dat: output, data read from the inr file
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

fid=fopen(fname,'rb');
s=fread(fid,256,'uchar');

s=char(s)';

if(regexp(s,'#INRIMAGE-4')~=1)
   error('INRIMAGE header was not found')
end

nx=regexp(s,'XDIM\s*=\s*([0-9]+)','tokens');
if(length(nx))
   nx=str2num(nx{1}{1});
else
   error('no XDIM found');
end

ny=regexp(s,'YDIM\s*=\s*([0-9]+)','tokens');
if(length(ny))
   ny=str2num(ny{1}{1});
else
   error('no YDIM found');
end

nz=regexp(s,'ZDIM\s*=\s*([0-9]+)','tokens');
if(length(nz))
   nz=str2num(nz{1}{1});
else
   error('no ZDIM found');
end

nv=regexp(s,'VDIM\s*=\s*([0-9]+)','tokens');
if(length(nv))
   nv=str2num(nv{1}{1});
else
   nv=1;
end

type=regexp(s,'TYPE=([a-z ]+)','tokens');
if(length(type))
   type=type{1}{1};
else
   error('no TYPE found');
end

pixel=regexp(s,'PIXSIZE=([0-9]+)','tokens');
if(length(pixel))
   pixel=str2num(pixel{1}{1});
else
   error('no PIXSIZE found');
end

%header=sprintf(['#INRIMAGE-4#{\nXDIM=%d\nYDIM=%d\nZDIM=%d\nVDIM=1\nTYPE=%s\n' ...
%  'PIXSIZE=%d bits\nCPU=decm\nVX=1\nVY=1\nVZ=1\n'],size(vol),btype,bitlen);

if(strcmp(type,'unsigned fixed') & pixel==8)
   dtype='uint8';
elseif(strcmp(type,'unsigned fixed') & pixel==16)
   dtype='uint16';
elseif(strcmp(type,'float') & pixel==32)
   dtype='float';
elseif(strcmp(type,'float') & pixel==64)
   dtype='double';
else
   error('volume format not supported');
end

dat=fread(fid,nx*ny*nz*nv,dtype);
fclose(fid);

if(nv==1)
   dat=reshape(dat,[nx,ny,nz]);
else
   dat=reshape(dat,[nx,ny,nz,nv]);
end


function removal(seg, segnum, between, label, near, centroids, url, grad, texthist)

    disp 'Removal'
    im = imread(url);

    epsilon=0.01;
    l_label = label;

    between = zeros([segnum, segnum]);
    for i = 1:size(between, 1)
        for j = 1:size(between, 2)
            %between(i, j) = sum((grad(i,:)-grad(j,:)).^2./(grad(i,:)+grad(j,:)+epsilon)) + sum((texthist(i,:)-texthist(j,:)).^2./(texthist(i,:)+texthist(j,:)+epsilon));
            distance = [centroids(i,1), centroids(i,2); centroids(j,1), centroids(j,2)];
            distance = sqrt((distance(1,1)-distance(2,1))^2 + (distance(1,2)-distance(2,2))^2) / max(size(im, 1), size(im, 2));
            between(i, j) = sum(abs(grad(i,:) - grad(j,:))) + sum(abs(texthist(i,:) - texthist(j,:))) + distance;

            if i == j
                between(i,j) = 100;
            end
        end
    end

    nim = im;
    [gx gy] = gradient(double(seg));
    eim = (gx.^2+gy.^2)>1e-10;
    t = nim(:,:,1); t(eim)=0; nim(:,:,1)=t;
    t = nim(:,:,2); t(eim)=0; nim(:,:,2)=t;
    t = nim(:,:,3); t(eim)=0; nim(:,:,3)=t;
%      imshow(nim);
%      hold on;

    c_im = double(rgb2hsv(im));
    c1_im = c_im(:,:,1);
    c2_im = c_im(:,:,2);
    c3_im = c_im(:,:,3);
    lab = calHsvHist(c_im, seg, segnum);

    for i = 1:size(label,2)
        if label(i) == 0
            j = near(i);
            num = 0;
            while label(j) ~= 255
                [value, j] = min(between(i,:));
                between(i,j) = 100;
                num = num + 1;

            end
            near(i) = j;
            if num ~= 21
                plot([centroids(i,1) centroids(j,1)], [centroids(i,2) centroids(j,2)], 'r');
                %text(centroids(i,1),centroids(i,2),[ num2str(centroids(i,1)) ,  num2str(centroids(i,2))])
            end
        end
    end

    for i = 1:size(label, 2)
        if label(i) == 0 && label(near(i)) == 255
            j = near(i);
            temp3 = reshape(lab(j,101:150),[50,1]);
            c3_im(seg==i) = hist_match(c3_im(seg==i),temp3);
            temp2 = reshape(lab(j,51:100),[50,1]);
            c2_im(seg==i) = hist_match(c2_im(seg==i),temp2);
            temp1 = reshape(lab(j,1:50),[50,1]);
            c1_im(seg==i) = hist_match(c1_im(seg==i),temp1);
            %c2_im(seg==i) = c2_im(seg==i) + (median(c2_im(seg==j)) - median(c2_im(seg==i)));
            %c1_im(seg==i) = c1_im(seg==i) + (median(c1_im(seg==j)) - median(c1_im(seg==i)));
        end
    end
    c_im(:,:,1) = c1_im;
    c_im(:,:,2) = c2_im;
    c_im(:,:,3) = c3_im;
    %imshow(hsv2rgb(c_im));

%end

%%
test_im = hsv2rgb(c_im);
circle = zeros(size(c_im, 1), size(c_im, 2));
for i = 8:size(c_im, 1)-8
    for j = 8:size(c_im, 2)-8
        if label(seg(i,j)) ~= label(seg(i-1,j)) || label(seg(i,j)) ~= label(seg(i+1,j)) || label(seg(i,j)) ~= label(seg(i,j-1)) || label(seg(i,j)) ~= label(seg(i,j+1))
            circle(i-1:i+1,j-1:j+1) = 1;

        end
    end
end
h = fspecial('gaussian', 15, 15);
pattern = imfilter(test_im, h);

label = l_label;

for i = 1:segnum
    if label(i) == 0

        for ch = 1:3
            fig = test_im(:,:,ch);

            for x = 20:size(fig, 1) - 20
                for y = 20:size(fig,2) - 20

                    if seg(x,y) == i && seg(x-4, y) ~= i && circle(x,y) == 1
                        %if abs(test_im(x,y,3) - avg(i,3)) > 0.05
                            fig(x,y) = pattern(x,y,ch);
                            fig(x-4,y) = pattern(x,y,ch);
                        %end
                        %
                    elseif seg(x,y) == i && seg(x+4, y) ~= i && circle(x,y) == 1
                        %if abs(test_im(x,y,3) - avg(i,3)) > 0.05
                            fig(x,y) = pattern(x,y,ch);
                            fig(x+4,y) = pattern(x,y,ch);
                        %end
                        %
                    elseif seg(x,y) == i && seg(x, y+4) ~= i && circle(x,y) == 1
                        %if abs(test_im(x,y,3) - avg(i,3)) > 0.05
                            fig(x,y) = pattern(x,y,ch);
                            fig(x,y+4) = pattern(x,y,ch);
                        %end
                        %
                    elseif seg(x,y) == i && seg(x, y-4) ~= i && circle(x,y) == 1
                        %if abs(test_im(x,y,3) - avg(i,3)) > 0.05
                            fig(x,y) = pattern(x,y,ch);
                            fig(x,y-4) = pattern(x,y,ch);
                        %end
                        %
                    end
                end
            end
            test_im(:,:,ch) = fig;
        end
    end

end
    imshow(test_im);
end


function dt = dtiImgToInd(dt, mask)
%Convert dti image to an alternative format
%
%    Yind = dtiImgToInd(Y, [MASK])
%
% Takes a XxYxZxpxN array as input and converts it to indexed form nxpxN,
% where n corresponds to a list of coordinates given by find(MASK).
%
% The form DT = dtiImgToInd(DT) works on the entire structure DT and
% implements the inverse of dtiIndToImg.m, in which case DT.mask is used as default.
% This results in a compression factor of about 50.
%
% See also:
%   dtiLoadTensorSubjects.m, dtiIndToImg.m
%
% HISTORY:
%   2004.11.24 Armin Shwartzmann wrote it

% If not struct
if ~isstruct(dt),
    Y = dt;
    sz = size(Y);
    L = prod(sz(1:3));
    N = sz(4:end);
    if isempty(N), N = 1; end
    Yind = reshape(Y, [L N]);
    imask = find(mask);
    Yind = Yind(imask,:);
    Yind = reshape(Yind, [length(imask) N]);
    dt = Yind;
    return
end

% If struct
if ~isfield(dt,'format'),
    error('Format field does not exist')
end
if strcmp(dt.format, 'Ind'),
    error('Data already in Ind format')
end
if ~exist('mask'),
    mask = dt.mask;
end

L = numel(mask);
imask = find(mask);

if isfield(dt,'fa'),
    N = size(dt.fa,4);
    Y = reshape(dt.fa, [L N]);
    dt.fa = Y(imask,:);
end
if isfield(dt,'val'),
    if (size(dt.val,4)~=3), error('Wrong "val" format'), end
    N = size(dt.val,5);
    Y = reshape(dt.val, [L 3 N]);
    dt.val = Y(imask,:,:);
end
if isfield(dt,'vec'),
    if (size(dt.vec,4)~=3 | size(dt.vec,5)~=3), error('Wrong "vec" format'), end
    N = size(dt.vec,6);
    Y = reshape(dt.vec, [L 3 3 N]);
    dt.vec = Y(imask,:,:,:);
end
if isfield(dt,'dt6'),
    if (size(dt.dt6,4)~=6), error('Wrong "val" format'), end
    N = size(dt.dt6,5);
    Y = reshape(dt.dt6, [L 6 N]);
    dt.dt6 = Y(imask,:,:);
end

dt.format = 'Ind';

return


function map = vega20(N)
% Colormap from MatPlotLib 2.0. For attractive plots using the ColorOrder.
%
%%% Syntax:
%  map = vega20
%  map = vega20(N)
%
% For MatPlotLib 2.0 improved colormaps were created for plot lines of
% categorical data. The new colormaps are introduced here:
% <http://matplotlib.org/2.0.0rc2/users/dflt_style_changes.html>
% <https://github.com/vega/vega/wiki/Scales#scale-range-literals>
% Note that VEGA10 is the new default Line Color Order for MatPlotLib 2.0.
%
% Information on the axes ColorOrder (note that this is NOT the axes COLORMAP):
% <https://www.mathworks.com/help/matlab/creating_plots/defining-the-color-of-lines-for-plotting.html>
% <https://www.mathworks.com/help/matlab/graphics_transition/why-are-plot-lines-different-colors.html>
%
%% Examples %%
%
%%% PLOT using matrices:
% N = 20;
% axes('ColorOrder',vega20(N),'NextPlot','replacechildren')
% X = linspace(0,pi*3,1000);
% Y = bsxfun(@(x,n)n*sin(x+2*n*pi/N), X(:), 1:N);
% plot(X,Y, 'linewidth',4)
%
%%% PLOT in a loop:
% N = 20;
% set(0,'DefaultAxesColorOrder',vega20(N))
% X = linspace(0,pi*3,1000);
% Y = bsxfun(@(x,n)n*sin(x+2*n*pi/N), X(:), 1:N);
% for n = 1:N
%     plot(X(:),Y(:,n), 'linewidth',4);
%     hold all
% end
%
%%% LINE using matrices:
% N = 20;
% set(0,'DefaultAxesColorOrder',vega20(N))
% X = linspace(0,pi*3,1000);
% Y = bsxfun(@(x,n)n*cos(x+2*n*pi/N), X(:), 1:N);
% line(X(:),Y)
%
%% Input and Output Arguments %%
%
%%% Inputs (*=default):
% N = NumericScalar, N>=0, an integer to define the colormap length.
%   = *[], use the length of the current figure's colormap (see COLORMAP).
%
%%% Outputs:
% map = NumericMatrix, size Nx3, a colormap of RGB values between 0 and 1.
%
% map = vega20(N)

if nargin<1
	N = size(get(gcf,'colormap'),1);
else
	assert(isscalar(N)&&isreal(N),'First argument must be a real numeric scalar.')
	assert(fix(N)==N&&N>=0,'First argument must be a positive integer.')
end
%
raw = [...
	031,119,180;... #1f77b4
	174,199,232;... #aec7e8
	255,127,014;... #ff7f0e
	255,187,120;... #ffbb78
	044,160,044;... #2ca02c
	152,223,138;... #98df8a
	214,039,040;... #d62728
	255,152,150;... #ff9896
	148,103,189;... #9467bd
	197,176,213;... #c5b0d5
	140,086,075;... #8c564b
	196,156,148;... #c49c94
	227,119,194;... #e377c2
	247,182,210;... #f7b6d2
	127,127,127;... #7f7f7f
	199,199,199;... #c7c7c7
	188,189,034;... #bcbd22
	219,219,141;... #dbdb8d
	023,190,207;... #17becf
	158,218,229;... #9edae5
	];

raw = reshape(raw,2,10,3);
raw = reshape(permute(raw,[2 1 3]),20,3);

%
map = raw(1+mod(0:N-1,size(raw,1)),:) / 255;
%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%vega20
% The file <vega_license.txt> contains the colormap license.
% This implmentation: Copyright (c) 2017 Stephen Cobeldick
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%license


function y = powercone(z,x,y,alpha)
%POWERCONE Defines a power cone x^alpha y ^(1-alpha) > |z|
%
% Input
%    z,y,x   : sclar SDPVAR objects.
%    alpha   : scalar double 0<=alpha<=1
%
% Example
%    F = powercone(z,x,y,alpha)

if numel(z)>1
    error('x must be a scalar')
end
if numel(x)>1
    error('x must be a scalar')
end
if numel(y)>1
    error('y must be a scalar')
end

try
    y = [x;y;z;alpha];
    y.typeflag = 20;
    y = lmi(y);
catch
    rethrow(lasterror)
end


function [ph_uw,msd]=uw_3d(ph,xy,day,ifgday_ix,bperp,options)
%UW_3D unwrap phase time series (single or multiple master)
%   PH_UW = UW_3D(PH,XY,DAY,IFGDAY_IX,BPERP,OPTIONS)
%
%   PH  = N x M matrix of wrapped phase values (real phase or complex phasor)
%        where N is number of pixels and M is number of interferograms
%   XY  = N x 2 matrix of coordinates in metres
%        (optional extra column, in which case first column is ignored)
%   DAY = vector of image acquisition dates in days, relative to master
%   IFGDAY_IX = M x 2 matrix giving index to master and slave date in DAY
%        for each interferogram
%   BPERP  = M x 1 vector giving perpendicular baselines
%   OPTIONS structure optionally containing following fields:
%      la_flag    = look angle error estimation flag (def='y')
%      scf_flag   = spatial cost function estimation flag (def='y')
%      master_day = serial date number of master (used for info msg only, def=0)
%      grid_size  = size of grid in m to resample data to (def=5)
%      prefilt_win = size of prefilter window in resampled grid cells (def=16)
%      time_win   = size of time filter window in days (def=365)
%      unwrap_method (def='3D' for single master, '3D_FULL' otherwise)
%      goldfilt_flag = Goldstein filtering, 'y' or 'n' (def='n')
%      gold_alpha    = alpha value for Goldstein filter (def=0.8)
%      lowfilt_flag  = Low pass filtering, 'y' or 'n' (def='n')
%      n_trial_wraps = no. phase cycles poss between neighbouring points due to la error (def=6)
%      temp          = optional M x 1 vector of temperature difference for each ifg (def=[])
%      n_temp_wraps  = no. phase cycles poss between neighbouring points due to temp diff (def=2)
%      variance      = N x 1 matrix of variance values
%   PH_UW = unwrapped phase
%
%   Andy Hooper, Jun 2007

% ============================================================
% 08/2009 AH: Goldstein alpha value added to options
% 01/2012 AH: Changes for easier running stand-alone
% 01/2012 AH: Add bperp for new look angle error estimation
% 02/2012 AH: Add new method 3D_NEW
% 11/2012 AH: Several new options
% 02/2014 AH: Add predefined ph_uw option
% ============================================================
tic;
if nargin<4
    help uw_3d
    error('not enough arguments')
end

if nargin<5
    bperp=[];
end

if nargin<6
    options=struct;
end

%if isempty(ifgday_ix) | length(unique(ifgday_ix(:,1)))==1
if isempty(ifgday_ix)
    single_master_flag=1;
else
    single_master_flag=0;
end

valid_options={'la_flag','scf_flag','master_day','grid_size','prefilt_win','time_win','unwrap_method','goldfilt_flag','lowfilt_flag','gold_alpha','n_trial_wraps','temp','n_temp_wraps','max_bperp_for_temp_est','variance','ph_uw_predef'};
invalid_options=setdiff(fieldnames(options),valid_options);
if length(invalid_options)>0
    error(['"',invalid_options{1}, '" is an invalid option'])
end

if ~isfield(options,'master_day')
    options.master_day=0;
end

if ~isfield(options,'grid_size')
    options.grid_size=5;
end

if ~isfield(options,'prefilt_win')
    options.prefilt_win=16;
end

if ~isfield(options,'time_win')
    options.time_win=365;
end

if ~isfield(options,'unwrap_method')
    if single_master_flag==1
        options.unwrap_method='3D';
    else
        options.unwrap_method='3D_FULL';
    end
end

if ~isfield(options,'goldfilt_flag')
    options.goldfilt_flag='n';
end

if ~isfield(options,'lowfilt_flag')
    options.lowfilt_flag='n';
end

if ~isfield(options,'gold_alpha')
    options.gold_alpha=0.8;
end

if ~isfield(options,'n_trial_wraps')
    options.n_trial_wraps=6;
end

if ~isfield(options,'la_flag')
    options.la_flag='y';
end

if ~isfield(options,'scf_flag')
    options.scf_flag='y';
end

if ~isfield(options,'temp')
    options.temp=[];
else
    if ~isempty(options.temp) & length(options.temp)~=size(ph,2)
        error('options.temp must be M x 1 vector where M is no. of ifgs')
    end
end

if ~isfield(options,'n_temp_wraps')
    options.n_temp_wraps=2;
end

if ~isfield(options,'max_bperp_for_temp_est')
    options.max_bperp_for_temp_est=100;
end

if ~isfield(options,'variance')
    options.variance=[];
end

if ~isfield(options,'ph_uw_predef')
    options.ph_uw_predef=[];
end

if size(xy,2)==2
   xy(:,2:3)=xy(:,1:2);
end

if size(day,1)==1
    day=day';
end

if strcmpi(options.unwrap_method,'3D') | strcmpi(options.unwrap_method,'3D_NEW')
    if length(unique(ifgday_ix(:,1)))==1
        options.unwrap_method='3D_FULL';
    else
        options.lowfilt_flag='y';
    end
end

uw_grid_wrapped(ph,xy,options.grid_size,options.prefilt_win,options.goldfilt_flag,options.lowfilt_flag,options.gold_alpha,options.ph_uw_predef);
clear ph
uw_interp;
%if single_master_flag==1
%    uw_unwrap_space_time(day,options.unwrap_method,options.time_win,options.master_day,options.la_flag,bperp,options.n_trial_wraps,options.prefilt_win,options.scf_flag,options.temp,options.n_temp_wraps);
%else
    uw_sb_unwrap_space_time(day,ifgday_ix,options.unwrap_method,options.time_win,options.la_flag,bperp,options.n_trial_wraps,options.prefilt_win,options.scf_flag,options.temp,options.n_temp_wraps,options.max_bperp_for_temp_est);
%end
uw_stat_costs(options.unwrap_method,options.variance);
[ph_uw,msd]=uw_unwrap_from_grid(xy,options.grid_size);


function     draw(graphic,value,v_EbN0_dB,v_ber,figur);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                       %
%%      Name: Draw.m                                                     %
%%                                                                       %
%%       Description: This file draws each one of the results of the     %
%%        different tests.                                               %
%%                                                                       %
%%       Parameters: It receives the necessary parameters to be able     %
%%        to draw the corresponding graphs.                              %
%%                                                                       %
%%       Result: It gives back grapsh for each simulations.              %
%%                                                                       %
%%                                                                       %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
grids on;
switch graphic
    case 'Channels'       % Here "value" is equivalent of the channel that we are simulating.
        switch value
            case 1
                form = 'y-';
            case 2
                form = 'm-o';
            case 3
                form = 'c-o';
            case 4
                form = 'r-o';
            case 5
                form = 'g-o';
            case 6
                form = 'b-*';
        end
        semilogy(v_EbN0_dB,v_ber,form);
        hold on;drawnow;

    case 'Encode'      % "value" is representing whether encoding is being used or not.
        switch value
            case 0                              % Uncoded
                form = 'o-';
            case 1                              % Encoded
                form = 'g-o';
        end
        semilogy(v_EbN0_dB,v_ber,form);
        hold on;drawnow;

    case 'CP'        % "value" is the size of the Cyclic Prefix.
        switch value
            case 1/4
                form = 'y-';
            case 1/8
                form = 'm-';
            case 1/16
                form = 'c-';
            case 1/32
                form = 'r-';
        end
        semilogy(v_EbN0_dB,v_ber,form);
        hold on;drawnow;

     case 'BW'            % Here "value" is equivalent to the bandwidth-BW.
        switch value
            case 28
                form = 'y-.';
            case 20
                form = 'm-.';
            case 15
                form = 'c-.';
            case 10
                form = 'r-.';
            case 2.50
                form = 'g-.';
            case 1.25
                form = 'b-*';
        end
        semilogy(v_EbN0_dB,v_ber,form);
        hold on;drawnow;

end


function animate_results(results, record, folder_name)
import iris.thirdParty.polytopes.*;

if nargin < 2
  record = false;
else
  if nargin < 3
    folder_name = ['videos/', datestr(now,'yyyy-mm-dd_HH.MM.SS')];
  end
end

dim = length(results.start);
C = results.e_history{1}.C;
d = results.e_history{1}.d;
A_bounds = results.p_history{1}.A(end-2*dim+1:end,:);
b_bounds = results.p_history{1}.b(end-2*dim+1:end);
bound_pts = lcon2vert(A_bounds, b_bounds);
lb = min(bound_pts)';
ub = max(bound_pts)';

if record
  frame = 1;
  system(sprintf('mkdir -p %s', folder_name));
  w = VideoWriter([folder_name, '/', 'animation']);
  w.FrameRate = 5;
  w.open();
  save([folder_name, '/', 'results'], 'results');

  delay = 1/w.FrameRate;
  delay1 = 1;
  delay2 = 2;
  gif_fname = [folder_name, '/', 'animation.gif'];
  loops = 65525;

  draw([], [], C, d, results.obstacles, lb, ub, results);
  h = gcf;
  movegui(h);
  w.writeVideo(getframe(h));
  print(gcf, sprintf('%s/%d_a', folder_name, 0), '-dpdf');
  img = getframe();
  [M, c_map]= rgb2ind(img.cdata,256);
  imwrite(M,c_map,[gif_fname],'gif','LoopCount',loops,'DelayTime',delay1);
end

figure(2);
clf;
for j = 1:length(results.p_history)
  A = results.p_history{j}.A;
  b = results.p_history{j}.b;
  draw(A, b, C, d, results.obstacles, lb, ub, results);
  if record
    h = gcf;
    movegui(h);
    w.writeVideo(getframe(h));
    print(gcf, sprintf('%s/%d_a', folder_name, j), '-dpdf');
    img = getframe();
    [M, c_map]= rgb2ind(img.cdata,256);
    imwrite(M,c_map,[gif_fname],'gif','WriteMode','append','DelayTime',delay)
  end
%   pause(0.1);
  C = results.e_history{j+1}.C;
  d = results.e_history{j+1}.d;
  draw(A, b, C, d, results.obstacles, lb, ub, results);
  if record
    h = gcf;
    movegui(h);
    w.writeVideo(getframe(h));
    print(gcf, sprintf('%s/%d_b', folder_name, j), '-dpdf', '-painters');
    img = getframe();
    [M, c_map]= rgb2ind(img.cdata,256);
    if j==length(results.p_history)
      imwrite(M,c_map,[gif_fname],'gif','WriteMode','append','DelayTime',delay2);
    else
      imwrite(M,c_map,[gif_fname],'gif','WriteMode','append','DelayTime',delay);
    end
  end
%   pause(0.25);
end

if record
  w.close();
end
end

function draw(A, b, C, d, obstacles, lb, ub, results)
  import iris.drawing.*;
  dim = length(results.start);
  if dim == 2
      draw_2d(A,b,C,d,obstacles,lb,ub);
      plot(results.start(1), results.start(2), 'go', 'MarkerFaceColor', 'g', 'MarkerSize', 8);
  elseif dim == 3
      draw_3d(A,b,C,d,obstacles,lb,ub);
      plot3(results.start(1), results.start(2), results.start(3), 'go', ...
        'MarkerFaceColor', 'g', 'MarkerSize', 15);
  else
    draw_Nd(A,b,C,d,obstacles,lb,ub);
  end
end


function ordered_textons = select_diverse_textons(tsim, nt)

next_t = zeros(nt, 1);
vals = zeros(nt, 1);
indices = (1:size(tsim, 1));
for t = 1:nt
    total_dsim = mean(tsim, 1);
    [vals(t), index] = max(total_dsim);
    next_t(t) = indices(index);
    tsim = tsim([(1:index-1) (index+1:end)], [(1:index-1) (index+1:end)]);
    indices = indices([(1:index-1) (index+1:end)]);
end

ordered_textons = next_t;


function Zvals = cp_wfg_sparse_setup(Z,W)
%CP_WFG_SPARSE_SETUP Creates a special array.
%
%   ZVALS = CP_WFG_SPARSE_SETUP(Z,W) creates an array ZVALS that
%   contains the values of Z corresponding to the indices specified
%   by W.subs.
%
%   See also CP_WFG_SPARSE.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2012) 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

Zsubs = Z.subs;
Wsubs = W.subs;
Zvals = zeros(size(W.vals));
[junk,loc] = ismember(Zsubs,Wsubs,'rows');
Zvals(loc) = Z.vals;


function SO3F = times(SO3F1,SO3F2)
% overloads |SO3F1 .* SO3F2|
%
% Syntax
%   sF = SO3F1 .* SO3F2
%   sF = a .* SO3F2
%   sF = SO3F1 .* a
%
% Input
%  SO3F1, SO3F2 - @SO3FunCBF
%  a - double
%
% Output
%  SO3F - @SO3Fun
%

if isnumeric(SO3F1)
  SO3F = SO3F2;
  SO3F.weights = SO3F.weights .* SO3F1;
  return
end

SO3F = times@SO3Fun(SO3F1,SO3F2);

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% init0.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% self-defined initialization list
L = 3*ones(n,1);
l = 2*ones(n,1);
x0 = [-10*ones(n,1) zeros(n,1) 10*ones(n,1)];


function [RIR_cell] = ISM_RIR_bank_GPU(setupstruc,RIRFileName,varargin)
%ISM_RIR_bank  Bank of RIRs using Lehmann & Johansson's image-source method
%
% [RIR_CELL] = ISM_RIR_bank(SETUP_STRUC,RIR_FILE_NAME)
% [RIR_CELL] = ISM_RIR_bank( ... ,'arg1',val1,'arg2',val2,...)
%
% This function generates a bank of room impulse responses (RIRs) for a
% particular user-defined room setup, using Lehmann and Johansson's
% implementation of the image-source method (see: "Prediction of energy
% decay in room impulse responses simulated with an image-source model", J.
% Acoust. Soc. Am., vol. 124(1), pp. 269-277, July 2008). The input
% SETUP_STRUC is a structure of enviromental parameters containing the
% following fields:
%
%          Fs: sampling frequency (in Hz).
%        room: 1-by-3 vector of enclosure dimensions (in m),
%              [x_length y_length z_length].
%     mic_pos: N-by-3 matrix, [x1 y1 z1; x2 y2 z2; ...] positions of N
%              microphones (in m).
%    src_traj: M-by-3 matrix, [x1 y1 z1; x2 y2 z2; ...] positions of M
%              source trajectory points (in m).
%  T20 or T60: scalar value (in s), desired reverberation time.
%           c: (optional) sound velocity (in m/s).
% abs_weights: (optional) 1-by-6 vector of absorption coefficients weights,
%              [w_x1 w_x2 w_y1 w_y2 w_z1 w_z2].
%
% If the field SETUP_STRUC.c is undefined, the function assumes a default
% value of sound velocity of 343 m/s.
%
% The field 'abs_weight' corresponds to the relative weights of each of the
% six absorption coefficients resulting from the desired reverberation time.
% For instance, defining 'abs_weights' as [1 1 0.8 0.8 0.6 0.6] will result
% in the absorption coefficients (alpha) for the walls in the y-dimension
% being 20% smaller compared to the x-dimension walls, whereas the floor
% and ceiling will end up with absorption coefficients 40% smaller (e.g.,
% to simulate the effects of a concrete floor and ceiling). If this field
% is omitted, the parameter 'abs_weight' will default to [1 1 1 1 1 1],
% which leads to uniform absorption coefficients for all room boundaries.
%
% The structure SETUP_STRUC may contain one of the two fields 'T60' or
% 'T20'. This function will automatically determine which reverberation
% type is used and compute the desired room absorption coefficients
% accordingly. T20 is defined as the time required for the impulse response
% energy to decay from -5 to -25dB, whereas T60 corresponds to the time
% required by the impulse response energy to decay by 60dB. Setting the
% corresponding field value to 0 achieves anechoic impulse responses
% (direct path only).
%
% In addition, a number of other (optional) parameters can be set using a
% series of 'argument'--value pairs. The following parameters (arguments)
% can be used:
%
%   'Delta_dB': scalar (in dB), parameter determining how much the resulting
%               impulse response is cropped: the impulse response is
%               computed until the time index where its overall energy
%               content has decreased by 'Delta_dB' decibels, after which
%               the computations stop. Not relevant if the reverberation
%               time is set to 0 (anechoic case). Defaults to 50.
% 'SilentFlag': set to 1 to disable this function's on-screen messages.
%               Defaults to 0.
%
% This function returns a 2-dimensional cell array RIR_CELL containing the
% RIRs for each source trajectory point and each microphone, organised as
% follows: RIR_CELL{mic_index,traj_index}. The resulting filter length
% may differ slightly in each computed RIR.
%
% This function also saves the computation results on file. The argument
% RIR_FILE_NAME determines the name of the .mat file where the variable
% RIR_CELL is to be saved. If a file already exists with the same name as
% the input argument, the user will be prompted to determine whether the
% file is to be overwritten or not. The given parameter RIR_FILE_NAME can
% be a full access path to the desired file. If no access path is given,
% the file is saved in the current working directory.

% Release date: November 2009
% Author: Eric A. Lehmann, Perth, Australia (www.eric-lehmann.com)
%
% Copyright (C) 2009 Eric A. Lehmann
%
% 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/>.

VarList = {'Delta_dB'       50;         % maximum attenuation in RIR computation
           'SilentFlag'     0;          % set to 1 to disable on-screen messages
           'useGPU'         0};         % whether to use GPU
eval(SetUserVars(VarList,varargin));    % set user-definable variables

if isempty(RIRFileName)
    DoNotSave = 1;
else
    DoNotSave = 0;
    if length(RIRFileName)<=4 || ~strcmpi(RIRFileName(end-3:end),'.mat'),
        RIRFileName = [RIRFileName '.mat'];
    end
end
if exist(RIRFileName,'file')==2,
    foo = input(' [ISM_RIR_bank] The file name passed as input already exists. Overwrite? [yes/no]: ','s');
    if ~strcmpi(foo,'yes');
        fprintf(' [ISM_RIR_bank] Terminating execution now (no data was saved).\n');
        return
    end
end

Fs = setupstruc.Fs;
room = setupstruc.room;
micpos = setupstruc.mic_pos;
straj = setupstruc.src_traj;

if isfield(setupstruc,'abs_weights'),
    weights = setupstruc.abs_weights;
else
    weights = ones(1,6);
end
if isfield(setupstruc,'c'),
    cc = setupstruc.c;
else
    cc = 343;
end
if isfield(setupstruc,'T60'),
    if isfield(setupstruc, 'reflect_weights')
        beta = setupstruc.reflect_weights;
    else
        alpha = ISM_AbsCoeff('t60',setupstruc.T60,room,weights,'LehmannJohansson','c',cc);
    end
    rttype = 'T60'; rtval = setupstruc.T60;
elseif isfield(setupstruc,'T20'),
    alpha = ISM_AbsCoeff('t20',setupstruc.T20,room,weights,'LehmannJohansson','c',cc);
    rttype = 'T20'; rtval = setupstruc.T20;
else
    error('Missing T60 or T20 field.');
end
if isfield(setupstruc, 'reflect_weights')==0
    beta = sqrt(1-alpha);
end

nMics = size(micpos,1);     % number of microphones
nSPts = size(straj,1);      % number of source trajectory points

%-=:=- Compute RIR bank -=:=-
RIR_cell = cell(nMics,nSPts); % pre-allocate cell array
if ~SilentFlag, PrintLoopPCw(' [ISM_RIR_bank] Computing room impulse responses. '); end;
for mm=1:nMics,
    X_rcv = micpos(mm,:);
    for tt=1:nSPts,         % compute ISM room impulse response for each source-receiver combinations
        if ~SilentFlag, PrintLoopPCw((mm-1)*nSPts+tt,nMics*nSPts); end;
        X_src = straj(tt,:);
        if strcmpi(rttype, 'T60')       % modified by Xiong Xiao: if we use T60, simply set RIR length to T60 length
            RIR_cell{mm,tt} = ISM_RoomResp_GPU(Fs,beta,rttype,rtval,X_src,X_rcv,room,'SilentFlag',1,'c',cc,'Delta_dB',Delta_dB, 'MaxDelay', rtval, 'useGPU', useGPU);
        else
            RIR_cell{mm,tt} = ISM_RoomResp_GPU(Fs,beta,rttype,rtval,X_src,X_rcv,room,'SilentFlag',1,'c',cc,'Delta_dB',Delta_dB, 'useGPU', useGPU);
        end
    end
end

%-=:=- Save results into .mat file -=:=-
if DoNotSave==0
    save(RIRFileName,'RIR_cell');
    if ~SilentFlag, fprintf(' [ISM_RIR_bank] RIR bank parameter ''RIR_cell'' saved in file ''%s''\n',RIRFileName); end;
end


classdef math_model_opf_acpi_legacy < mp.math_model_opf_acpi & mp.mm_shared_opf_legacy
%MP.MATH_MODEL_OPF_ACPI_LEGACY  MATPOWER mathematical model for AC optimal power flow (OPF) problem.
%   ?
%
%   MP.MATH_MODEL_OPF_ACPI_LEGACY ... power flow ...
%
%   Properties
%       ? - ?
%
%   Methods
%       ?

%   MATPOWER
%   Copyright (c) 2021-2022, 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.

%     properties
%     end

    methods
        %% constructor
        function obj = math_model_opf_acpi_legacy()
            obj@mp.math_model_opf_acpi();
            if nargin > 0 && isstruct(mpc)
                obj.mpc = mpc;
            end

            %% Due to a bug related to inheritance in constructors in
            %% Octave 5.2 and earlier (https://savannah.gnu.org/bugs/?52614),
            %% INIT_SET_TYPES() cannot be called directly in the
            %% MP_IDX_MANAGER constructor, as desired.
            %%
            %% WORKAROUND:  INIT_SET_TYPES() is called explicitly as needed
            %%              (if om.var is empty) in ADD_VAR(), DISPLAY() and
            %%              INIT_INDEXED_NAME(), after object construction,
            %%              but before object use.
        end

        function obj = add_named_set(obj, varargin)
            % call parent method (also checks for valid type for named set)
            add_named_set@mp.math_model_opf_acpi(obj, varargin{:});
            obj.add_named_set_legacy(varargin{:});
        end

        function obj = def_set_types(obj)
            obj.def_set_types_legacy();
        end

        function obj = init_set_types(obj)
            init_set_types@mp.math_model_opf_acpi(obj);
            obj.init_set_types_legacy();
        end

        function obj = build(obj, nm, dm, mpopt)
            obj.mpc = dm.source;
            build@mp.math_model_opf_acpi(obj, nm, dm, mpopt);
            obj.build_legacy(nm, dm, mpopt);
        end

        function obj = add_vars(obj, nm, dm, mpopt)
            add_vars@mp.math_model_opf_acpi(obj, nm, dm, mpopt);    %% call parent

            %% legacy user-defined variables
            if isfield(dm.userdata, 'legacy_opf_user_mods')
                obj.add_legacy_user_vars(nm, dm, mpopt);
            end
        end

        function add_system_costs(obj, nm, dm, mpopt)
            add_system_costs@mp.math_model_opf_acpi(obj, nm, dm, mpopt);    %% call parent

            %% legacy user-defined costs
            if isfield(dm.userdata, 'legacy_opf_user_mods')
                obj.add_legacy_user_costs(nm, dm, 0);
            end
        end

        function obj = add_system_constraints(obj, nm, dm, mpopt)
            %% call parent
            add_system_constraints@mp.math_model_opf_acpi(obj, nm, dm, mpopt);

            %% legacy user-defined constraints
            if isfield(dm.userdata, 'legacy_opf_user_mods')
                obj.add_legacy_user_constraints_ac(nm, dm, mpopt);
            end
        end

        function names = legacy_user_var_names(obj)
            names = {'Va', 'Vm', 'Pg', 'Qg'};
        end
    end     %% methods
end         %% classdef


%GRIDFACE Generate grid cell face numbering.
%
%   [ F, FV ] = GRIDFACE( C, B ) Generates an array F with global face
%   numbers and FV with grid point indices per face. Input data is an
%   array C with cell connectivities, and optionally the boundary
%   struct B if upper triangular (OpenFOAM) ordering should be used
%   (default normal ordering).
%
%       Input       Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       c           (n_v,n_c)              Cell connectivity pointer array where the
%                                          entries in each column correspond to the
%                                          cell vertex numbers specifying the cells.
%       b           struct                 Boundary struct to use upper triangular ordering
%                                                                                .
%       Output      Value/(Size)           Description
%       -----------------------------------------------------------------------------------
%       f           (n_f,n_c)              Array with global face numbers for all cells.
%       fv          (n_f,3/4)              Array with indices to vertices for each face.

% Copyright 2013-2022 Precise Simulation, Ltd.


function [output_width_map, output_height_map] = proposal_calc_output_size(conf, test_net_def_file)
% [output_width_map, output_height_map] = proposal_calc_output_size(conf, test_net_def_file)
% --------------------------------------------------------
% Faster R-CNN
% Copyright (c) 2015, Shaoqing Ren
% Licensed under The MIT License [see LICENSE for details]
% --------------------------------------------------------

%     caffe.init_log(fullfile(pwd, 'caffe_log'));
    caffe_net = caffe.Net(test_net_def_file, 'test');

     % set gpu/cpu
    if conf.use_gpu
        caffe.set_mode_gpu();
    else
        caffe.set_mode_cpu();
    end

    input = 100:conf.max_size;
    output_w = nan(size(input));
    output_h = nan(size(input));
    for i = 1:length(input)
        s = input(i);
        im_blob = single(zeros(s, s, 3, 1));
        net_inputs = {im_blob};

        % Reshape net's input blobs
        caffe_net.reshape_as_input(net_inputs);
        caffe_net.forward(net_inputs);

        cls_score = caffe_net.blobs('proposal_cls_score').get_data();
        output_w(i) = size(cls_score, 1);
        output_h(i) = size(cls_score, 2);
    end

    output_width_map = containers.Map(input, output_w)
    output_height_map = containers.Map(input, output_h)
    caffe.reset_all();
end


function c = butter(c,varargin)
   %butter   create and apply a butterworth filter to the traces
   % C = BUTTER(C,[TYPE],CUTOFF,[POLES])
   % This function creates and applies a butterworth filter to each waveform
   % in the correlation object. The function returns a correlation object.
   % Filtering is performed by an underlying call to the filterobject/filtfilt
   % routine. Note that filtfilt applies the filter once in each direction to
   % minimize phase distortion (effectively a zero-phase filter). This also
   % has the effect of doubling the order of the filter. 2 or 4 poles should
   % be sufficient for most applications.
   %
   % EXAMPLES:
   %  c = BUTTER(c,[1 5])            band pass filter on 1-5 Hz (4 poles)
   %  c = BUTTER(c,'B',[1 5])        same as previous example
   %  c = BUTTER(c,'L',5)            low  pass filter below 5 Hz (4 poles)
   %  c = BUTTER(c,'H',1)            high pass filter above 5 Hz (4 poles)
   %  c = BUTTER(c,...,2)            use 2 poles

   % Author: Michael West, Geophysical Institute, Univ. of Alaska Fairbanks
   % $Date$
   % $Revision$
   % TODO: should check to ensure low cutoff period is >> trace length

   % GET INPUTS
   if ischar(varargin{1})       % set filter type
      type = varargin{1};
      varargin = varargin(2:end);
   else
      type = 'B';
   end

   cutoff = varargin{1};            % set cutoff frequencies

   if length(varargin)>1
      poles = varargin{2};
   else
      poles = 4;                  % set number of poles
   end

   % CHECK FIRST LETTER OF FILTER TYPE
   type = upper(type(1));
   if (type~='B') && (type~='H') && (type~='L')
      error('Filter type not recognized')
   end;

   % CHECK NUMBER OF CUTOFF FREQUENCIES
   if type=='B'
      if length(cutoff)~=2
         error('Two cutoff frequecies needed for bandpass filter')
      end;
   else
      if length(cutoff)~=1
         error('High and lowpass filters require one cutoff frequency')
      end;
   end;

   % CHECK FREQUENCY RANGE
   if cutoff(end) >= c.traces(1).nyquist()
      error('Frequency cutoffs exceed the Nyquist frequency')
   end;

   % duration = get(c,'DURATION_EPOCH');
   % if 1/cutoff(1) >= duration(1)
   %     warning('Frequency cutoff is very low relative to trace length');
   % end;
   % uration(1)
   % 1/cutoff(1)

   % APPLY FILTER
   f = TraceFilter(type,cutoff,poles);
   c.traces = f.filtfilt(c.traces);
end


%     NeuroSLAM System Copyright (C) 2018-2019
%     NeuroSLAM: A Brain inspired SLAM System for 3D Environments
%
%     Fangwen Yu (www.yufangwen.com), Jianga Shang, Youjian Hu, Michael Milford(www.michaelmilford.com)
%
%     The NeuroSLAM V1.0 (MATLAB) was developed based on the OpenRatSLAM (David et al. 2013).
%     The RatSLAM V0.3 (MATLAB) developed by David Ball, Michael Milford and Gordon Wyeth in 2008.
%
%     Reference:
%     Ball, David, Scott Heath, Janet Wiles, Gordon Wyeth, Peter Corke, and Michael Milford.
%     "OpenRatSLAM: an open source brain-based SLAM system." Autonomous Robots 34, no. 3 (2013): 149-176.
%
%     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/>.

visual_odo_initial( ...
    'ODO_IMG_TRANS_Y_RANGE', 51:150, ...
    'ODO_IMG_TRANS_X_RANGE', 181:300, ...
    'ODO_IMG_HEIGHT_V_Y_RANGE', 51:150, ...
    'ODO_IMG_HEIGHT_V_X_RANGE', 180:300, ...
    'ODO_IMG_YAW_ROT_Y_RANGE', 51:150, ...
    'ODO_IMG_YAW_ROT_X_RANGE', 180:300, ...
    'ODO_IMG_TRANS_RESIZE_RANGE', [100, 120], ...
    'ODO_IMG_YAW_ROT_RESIZE_RANGE', [100, 120], ...
    'ODO_IMG_HEIGHT_V_RESIZE_RANGE', [100, 120], ...
    'ODO_TRANS_V_SCALE', 1, ...
    'ODO_YAW_ROT_V_SCALE', 1, ...
    'ODO_HEIGHT_V_SCALE', 1, ...
    'MAX_TRANS_V_THRESHOLD', 0.02, ...
    'MAX_YAW_ROT_V_THRESHOLD', 10, ...
    'MAX_HEIGHT_V_THRESHOLD', 0.03, ...
    'ODO_SHIFT_MATCH_HORI', 36, ...
    'ODO_SHIFT_MATCH_VERT', 20, ...
    'FOV_HORI_DEGREE', 90, ...
    'FOV_VERT_DEGREE', 50, ...
    'KEY_POINT_SET', [1644, 1741], ...
    'ODO_STEP', 1);

% global avg;
visual_odo_main('C:\NeuroSLAM_Datasets\01_NeuroSLAM_Datasets\02_SynPanData', ...
    'C:\NeuroSLAM_Datasets\02_NeuroSLAM_Groudtruth\02_SynPanData_GT.txt');


function [] = ManyPieces()
%MANYPIECES Produce a photomosiac from an image and a directory of images
%   Given an image and a directory of images create a photomosaic
%	Paramets may be modified within m file
%	Written by Justin Dailey
%	dailejl@auburn.edu

%Mosaic Parameters
%Number of thumbs spanning width of img
thumb_ratio = 100;
%Default thumb directory (only if saving thumbs)
thumb_dir = strcat(pwd, filesep, 'Thumbs');
%Coefficient for scaling of output tiles
output_scale = 2;
%Output file name
output_file_name = 'Mosaic.jpg';
%Dithering distance
dval = 1;

%List of file types
file_types = {['*.BMP;*.GIF;*.HDF;*.JPEG;*.JPG;*.PBM;*.PCX;*.PGM;',...
    '*.PNG;*.PNM;*.PPM;*.RAS;*.TIFF;*.TIF;*.XWD'],'MATLAB Graphical Files'};
comp_file_types = {'BMP' 'GIF' 'HDF' 'JPEG' 'JPG' 'PBM' 'PCX' 'PGM' ...
    'PNG' 'PNM' 'PPM' 'RAS' 'TIFF' 'TIF' 'XWD'};

%% Get main image and directory of images
img_path = uigetfile(file_types, 'Select the main mosiac image');
img_dir = uigetdir();

%Get original img size
ref_img = imread(img_path);
img_size = size(ref_img);
img_size = img_size(1:2);

%% Calc values
%Set size for thumbnail based on original size
thumb_pixels = floor(img_size(1)/thumb_ratio);
thumb_size = [thumb_pixels thumb_pixels];
%Make sure h/w are proportional to thumb size
new_height = floor(img_size(2)/thumb_pixels);
num_tiles = [thumb_ratio new_height];
new_size = [thumb_ratio new_height].*thumb_pixels;
ref_img = imresize(ref_img, new_size);

%% Get all directory images
dir_files = dir(img_dir);
mosaic_ind = 1;
%For each image add it to array
for dir_ind = 1:length(dir_files)
    if ~dir_files(dir_ind).isdir
        file_name = dir_files(dir_ind).name;
        %Check file extension
        [~, ~, ext, ~] = fileparts(file_name);
        if max(strcmpi(ext(2:end), comp_file_types))
            mosaic_files{mosaic_ind} = file_name;
            mosaic_ind = mosaic_ind+1;
        end
    end
end

%% Resize directory images into thumbs
progress = waitbar(0, 'Creating Mosaic Thumbnails...');
num_files = length(mosaic_files);
mosaic_imgs = cell(1, num_files);
%mkdir(thumb_dir);
%Resize each image
for mosaic_ind = 1:num_files
    img = imread([img_dir, filesep, mosaic_files{mosaic_ind}]);
    %if read in grayscale img
    if size(img, 3) == 1
        img = ind2rgb(img, gray(256));
    end
    res_img = uint8(imresize(img, thumb_size*output_scale));
    thumbs{mosaic_ind} = res_img;
    %imwrite(res_img, [thumb_dir, filesep, strcat(num2str(mosaic_ind),'.jpg')], 'jpg');
    waitbar(mosaic_ind/num_files, progress);
end
close(progress);

%% Calculating thumbnail averages
progress = waitbar(0, 'Calculating Thumbnail Averages...');
for mosaic_ind = 1:num_files
    %calc average vals for thumbs
    cur_thumb = thumbs{mosaic_ind};
    RGB_vals{mosaic_ind} = mean(reshape(cur_thumb, [], 3), 1);
    waitbar(mosaic_ind/num_files, progress);
end
close(progress);

%% For each tile of image find closest matching thumb
progress = waitbar(0, 'Creating Photomosiac...');
pic_map = zeros(num_tiles);
tiles_done = 0;
for row_tile = 1:num_tiles(1)
    for col_tile = 1:num_tiles(2)
        closest = 1;
        shortest_dist = 1000;
        %get mean vals for the image tiles
        cur_tile = ref_img(thumb_pixels*(row_tile-1)+1:thumb_pixels*(row_tile), ...
        thumb_pixels*(col_tile-1)+1:thumb_pixels*(col_tile),:);
        cur_RGB = mean(reshape(cur_tile, [], 3), 1);
        %find the closest thumb to each tile
        for thumb_tile = 1:num_files
            dist = calc_distance(RGB_vals{thumb_tile}, cur_RGB);
            %if new pt is closer
            if dist < shortest_dist
                %implement dithering to limit use of tile in an area
                if isempty(find( ...
                        pic_map(max(row_tile-dval,1): ...
                        min(row_tile+dval,num_tiles(1)),...
                        max(col_tile-dval,1): ...
                        min(col_tile+dval,num_tiles(2))) ...
                        == thumb_tile, 1))
                    shortest_dist = dist;
                    pic_map(row_tile, col_tile) = thumb_tile;
                end
            end
        end
        tiles_done = tiles_done + 1;
        waitbar(tiles_done/(num_tiles(1)*num_tiles(2)), progress);
    end
end
close(progress);

%% Take mapping of thumbnails and create photomosaic
progress = waitbar(0, 'Assembling Photomosaic...');
for row_tile = 1:num_tiles(1)
    cur_row = thumbs{pic_map(row_tile, 1)};
    for col_tile = 2:num_tiles(2)
        cur_row = horzcat(cur_row, thumbs{pic_map(row_tile, col_tile)});
    end
    if row_tile == 1
        mosaic = cur_row;
    else
        mosaic = vertcat(mosaic, cur_row);
        clear cur_row;
    end
    waitbar(row_tile/num_tiles(1), progress);
end
close(progress);

imshow(mosaic)
imwrite(mosaic, output_file_name, 'jpg');
end

function distance = calc_distance(pt1, pt2)
    distance = sqrt(sum((pt1-pt2).^2));
end


function y = hsv2hsl(x)

%hsv2hsl - Convert hue-saturation-value colors to hue-saturation-luminance.
%
%  USAGE
%
%    y = hsv2hsl(x)
%
%    x              Nx3 RGB matrix (values in [0..1])

% Copyright (C) 2013 by Michaël Zugaro
%
% 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.

% Check number of parameters
if nargin < 1,
  error('Incorrect number of parameters (type ''help hsv2hsl'' for details).');
end
if ~isdmatrix(x) || size(x,2) ~= 3 || any(x(:)<0) || any(x(:)>1),
  error('Incorrect HSL matrix (type ''help hsv2hsl'' for details).');
end

% Convert HSV to HSL
h = x(:,1);
s = x(:,2);
v = x(:,3);

H = h;
S = s .* v;
L = (2-s).*v;
in = L <= 1;
S(in) = S(in) ./ L(in);
S(in&v==0) = 0;
S(~in) = S(~in) ./ (2-L(~in));
S(~in&s==0&v==1) = 0;
L = L/2;

y = Clip([H S L],0,1);


function [y]=multifuncrs(X, funs, eps, varargin)
% Cross approximation of a (vector-)function of several TT-tensors.
%   [Y]=MULTIFUNCRS(X,FUNS,EPS, VARARGIN)
%   Computes approximation to the functions FUNS(X{1},...,X{N}) with accuracy EPS
%   X should be a cell array of nx TT-tensors of equal sizes.
%   The function FUNS should receive a 2d array V of sizes I x N, where the
%   first dimension stays for the reduced set of spatial indices, and  the
%   second is the enumerator of X.
%   The returned sizes should be I x D2, where D2 is the number of
%   components in FUNS. D2 should be either provided as the last (d+1)-th
%   TT-rank of the initial guess, or given explicitly as an option (see
%   below).
%   For example, a linear combination reads FUNS=@(x)(x*W), W is a N x D2
%   matrix.
%
%   Options are provided in form
%   'PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2 and so
%   on. The parameters are set to default (in brackets in the following)
%   The list of option names and default values are:
%       o y0 - initial approximation [random rank-2 tensor]
%       o nswp - maximal number of DMRG sweeps [10]
%       o rmax - maximal TT rank [Inf]
%       o verb - verbosity level, 0-silent, 1-sweep info, 2-block info [1]
%       o kickrank - the rank-increasing parameter [5]
%       o d2 - the last rank of y, that is dim(FUNS) [1]
%       o qr - do (or not) qr before maxvol [false]
%
%   The method is based on the alternating approximation, with
%   the one-block enrichment via KICKRANK random vectors or randomized AMR.
%
%
% TT-Toolbox 2.2, 2009-2012
%
%This is TT Toolbox, written by Ivan Oseledets et al.
%Institute of Numerical Mathematics, Moscow, Russia
%webpage: http://spring.inm.ras.ru/osel
%
%For all questions, bugs and suggestions please mail
%ivan.oseledets@gmail.com
%---------------------------

nswp = 10;
kickrank = 5;
y = [];
verb = 1;
% kicktype = 'rand';
kicktype = 'amr-two';
pcatype = 'svd';
%pcatype = 'uchol';
rmax = Inf;
d2 = 1;
wasrand = false;
trunctype = 'fro';
do_qr = false;
% trunctype = 'cross';

for i=1:2:length(varargin)-1
    switch lower(varargin{i})
        case 'nswp'
            nswp=varargin{i+1};
        case 'y0'
            y=varargin{i+1};
        case 'kickrank'
            kickrank=varargin{i+1};
        case 'rmax'
            rmax=varargin{i+1};
        case 'verb'
            verb=varargin{i+1};
        case 'kicktype'
            kicktype=varargin{i+1};
        case 'pcatype'
            pcatype=varargin{i+1};
        case 'trunctype'
            trunctype=varargin{i+1};
        case 'd2'
            d2=varargin{i+1};
        case 'qr'
            do_qr = varargin{i+1};
        otherwise
            error('Unrecognized option: %s\n',varargin{i});
    end
end

nx = numel(X);
d = X{1}.d;
n = X{1}.n;
rx = zeros(d+1,nx);
crX = cell(d,nx);
for i=1:nx
    rx(:,i) = X{i}.r;
    crX(:,i) = core2cell(X{i});
end;

if (isempty(y))
    ry = d2*ones(d+1,1); ry(1)=1;
    y = tt_rand(n, d, ry);
    wasrand = true;
end;
ry = y.r;
cry = core2cell(y);

Ry = cell(d+1,1);
Ry{1} = 1; Ry{d+1}=1;
Rx = cell(d+1,nx);
for i=1:nx
    Rx{1,i}=1; Rx{d+1,i}=1;
end;

block_order = [+(d), -(d)];

% Orth
for i=1:d-1
    cr = cry{i}; % r1,n,d2,r2
    cr = reshape(cr, ry(i)*n(i), ry(i+1));
    [cr, rv]=qr(cr, 0);
    cr2 = cry{i+1};
    cr2 = reshape(cr2, ry(i+1), n(i+1)*ry(i+2));
    cr2 = rv*cr2;
    ry(i+1) = size(cr, 2);
    cr = reshape(cr, ry(i), n(i), ry(i+1));
    cry{i+1} = reshape(cr2, ry(i+1), n(i+1), ry(i+2));
    cry{i} = cr;

    % Interface matrix for Y
    Ry{i+1} = Ry{i}*reshape(cr, ry(i), n(i)*ry(i+1));
    Ry{i+1} = reshape(Ry{i+1}, ry(i)*n(i), ry(i+1));
    if (wasrand)
        curind = [];
        while numel(curind)<ry(i+1)
            curind = [curind; ceil(rand(ry(i+1), 1)*(n(i)*ry(i)))];
            curind = unique(curind);
        end;
        curind = curind(1:ry(i+1));
    else

        curind = maxvol2(Ry{i+1},'qr',do_qr);
    end;
    Ry{i+1} = Ry{i+1}(curind, :);
    % Interface matrices for X
    for j=1:nx
        Rx{i+1,j} = reshape(crX{i,j}, rx(i,j), n(i)*rx(i+1,j));
        Rx{i+1,j} = Rx{i,j}*Rx{i+1,j};
        Rx{i+1,j} = reshape(Rx{i+1,j}, ry(i)*n(i), rx(i+1,j));
        Rx{i+1,j} = Rx{i+1,j}(curind, :);
    end;
end;

d2 = ry(d+1);
ry(d+1) = 1;
cry{d} = permute(cry{d}, [3,1,2]); % d2, rd, nd

last_sweep = false;
swp = 1;

% dy_old = ones(d,1);
dy = zeros(d,1);
max_dy = 0;
% For extra-rank addition
% dpows = ones(d,1)*min_dpow;
% dranks = zeros(d,1);

cur_order = block_order;
order_index = 2;
i = d;
dir = sign(cur_order(order_index));

% DMRG sweeps
while (swp<=nswp)||(dir>0)

    oldy = reshape(cry{i}, d2*ry(i)*n(i)*ry(i+1), 1);

    if (~last_sweep)
        % Compute the X superblocks
        curbl = zeros(ry(i)*n(i)*ry(i+1), nx);
        for j=1:nx
            cr = reshape(crX{i,j}, rx(i,j), n(i)*rx(i+1,j));
            cr = Rx{i,j}*cr;
            cr = reshape(cr, ry(i)*n(i), rx(i+1,j));
            cr = cr*Rx{i+1,j};
            curbl(:,j) = cr(:);
        end;
        % Call the function
        newy = funs(curbl); % sizes: rnr x nx -> rnr x d2
        % Multiply with inverted Ry
        newy = reshape(newy, ry(i), n(i)*ry(i+1)*d2);
        newy = (Ry{i}) \ newy;
        newy = reshape(newy, ry(i)*n(i)*ry(i+1), d2);
        newy = reshape(newy.', d2*ry(i)*n(i), ry(i+1));
        newy = newy / (Ry{i+1});
        newy = reshape(newy, d2*ry(i)*n(i)*ry(i+1), 1);
    else
        newy = oldy;
    end;

    dy(i) = norm(newy(:)-oldy)/norm(newy(:));
    max_dy = max(max_dy, dy(i));

    % Truncation
    if (dir>0) % left-to-right
        newy = reshape(newy, d2, ry(i)*n(i)*ry(i+1));
        newy = reshape(newy.', ry(i)*n(i), ry(i+1)*d2);
    else
        newy = reshape(newy, d2*ry(i), n(i)*ry(i+1));
    end;

    if (kickrank>=0)
        [u,s,v]=svd(newy, 'econ');
        s = diag(s);
        if (strcmp(trunctype, 'fro'))||(last_sweep)
            r = my_chop2(s, eps/sqrt(d)*norm(s));
        else
            % Truncate taking into account the (r+1) overhead in the cross
            cums = (s.*(2:numel(s)+1)').^2;
            cums = cumsum(cums(end:-1:1));
            cums = cums(end:-1:1)./cums(1);
            r = find(cums<(eps^2/d), 1);
            if (isempty(r))
                r = numel(s);
            end;
        end;
        r = min(r, rmax);
        r = min(r, numel(s));
    else
        if (dir>0)
            [u,v]=qr(newy, 0);
            v=v';
            r = size(u,2);
            s = ones(r,1);
        else
            [v,u]=qr(newy.', 0);
            v=conj(v);
            u=u.';
            r = size(u,2);
            s = ones(r,1);
        end;
    end;

    if (verb>1)
    	fprintf('=multifuncrs=   block %d{%d}, dy: %3.3e, r: %d\n', i, dir, dy(i), r);
    end;

    % Kicks and interfaces
    if (dir>0)&&(i<d) % left-to-right, kickrank, etc
        u = u(:,1:r);
        v = v(:,1:r)*diag(s(1:r));

        % kick
        radd = 0; rv = 1;
        if (~last_sweep)&&(kickrank>0)
            if (strcmp(kicktype, 'amr-two'))
                % AMR(two)-like kick. See also the M.Sc.Thesis by D. Zheltkov.
                % The left indices are nested, but the right are chosen
                % randomly. In Zheltkov's work, from all possible n^(d-k)
                % values. However, in the functional-cross it would result
                % in a d^2 complexity. Here, I use only the neighbouring
                % core for randomization. Additionally, the actual kick is
                % performed via the Z=PCA(supercore), since otherwise the
                % rank grows too high.

                % Compute the X superblocks
                ind2 = unique(ceil(rand(ry(i+1), 1)*(ry(i+2)*n(i+1))));
                rkick = numel(ind2);
                curbl = zeros(ry(i)*n(i)*rkick, nx);
                for j=1:nx
                    cr1 = reshape(crX{i,j}, rx(i,j), n(i)*rx(i+1,j));
                    cr1 = Rx{i,j}*cr1;
                    cr1 = reshape(cr1, ry(i)*n(i), rx(i+1,j));
                    cr2 = reshape(crX{i+1,j}, rx(i+1,j)*n(i+1), rx(i+2,j));
                    cr2 = cr2*Rx{i+2,j}; % now its size rx
                    cr2 = reshape(cr2, rx(i+1,j), n(i+1)*ry(i+2));
                    cr2 = cr2(:, ind2);
                    curbl(:,j) = reshape(cr1*cr2, ry(i)*n(i)*rkick, 1);
                end;
                % Call the function
                uk = funs(curbl); % rnr, d2
                uk = reshape(uk, ry(i), n(i)*rkick*d2);
                uk = Ry{i} \ uk;
                uk = reshape(uk, ry(i)*n(i), rkick*d2);
                if (strcmp(pcatype, 'svd'))
                    [uk,sk,vk]=svd(uk, 'econ');
                    uk = uk(:,1:min(kickrank, size(uk,2)));
                else
                    uk = uchol(uk.', kickrank+1);
                    uk = uk(:,end:-1:max(end-kickrank+1,1));
                end;
            else
                uk = rand(ry(i)*n(i), kickrank);
            end;
            [u,rv]=qr([u,uk], 0);
            radd = size(uk,2);
        end;
        v = [v, zeros(ry(i+1)*d2, radd)];
        v = rv*(v');
        r = size(u,2);

        cr2 = cry{i+1};
        cr2 = reshape(cr2, ry(i+1), n(i+1)*ry(i+2));
        v = reshape(v, r*ry(i+1), d2);
        v = reshape(v.', d2*r, ry(i+1));
        v = v*cr2; % size r+radd, n2, r3

        ry(i+1) = r;

        u = reshape(u, ry(i), n(i), r);
        v = reshape(v, d2, r, n(i+1), ry(i+2));

        % Stuff back
        cry{i} = u;
        cry{i+1} = v;

        % Recompute left interface matrices
        % Interface matrix for Y
        Ry{i+1} = Ry{i}*reshape(u, ry(i), n(i)*ry(i+1));
        Ry{i+1} = reshape(Ry{i+1}, ry(i)*n(i), ry(i+1));
        curind = maxvol2(Ry{i+1},'qr',do_qr);
        Ry{i+1} = Ry{i+1}(curind, :);
        % Interface matrices for X
        for j=1:nx
            Rx{i+1,j} = reshape(crX{i,j}, rx(i,j), n(i)*rx(i+1,j));
            Rx{i+1,j} = Rx{i,j}*Rx{i+1,j};
            Rx{i+1,j} = reshape(Rx{i+1,j}, ry(i)*n(i), rx(i+1,j));
            Rx{i+1,j} = Rx{i+1,j}(curind, :);
        end;
    elseif (dir<0)&&(i>1) % right-to-left
        u = u(:,1:r)*diag(s(1:r));
        v = conj(v(:,1:r));
        % kick
        radd = 0; rv = 1;
        if (~last_sweep)&&(kickrank>0)
            if (strcmp(kicktype, 'amr-two'))
                % Compute the X superblocks
                ind2 = unique(ceil(rand(ry(i), 1)*(ry(i-1)*n(i-1))));
                rkick = numel(ind2);
                curbl = zeros(rkick*n(i)*ry(i+1), nx);
                for j=1:nx
                    cr1 = reshape(crX{i,j}, rx(i,j)*n(i), rx(i+1,j));
                    cr1 = cr1*Rx{i+1,j};
                    cr1 = reshape(cr1, rx(i,j), n(i)*ry(i+1));
                    cr2 = reshape(crX{i-1,j}, rx(i-1,j), n(i-1)*rx(i,j));
                    cr2 = Rx{i-1,j}*cr2; % now its size rx
                    cr2 = reshape(cr2, ry(i-1)*n(i-1), rx(i,j));
                    cr2 = cr2(ind2, :);
                    curbl(:,j) = reshape(cr2*cr1, rkick*n(i)*ry(i+1), 1);
                end;
                % Call the function
                uk = funs(curbl); % rnr x d2
                uk = reshape(uk, rkick*n(i)*ry(i+1), d2);
                uk = reshape(uk.', d2*rkick*n(i), ry(i+1));
                uk = uk / Ry{i+1};
                uk = reshape(uk, d2*rkick, n(i)*ry(i+1));
                if (strcmp(pcatype, 'svd'))
                    [vk,sk,uk]=svd(uk, 'econ');
                    uk = uk(:,1:min(kickrank, size(uk,2)));
                else
                    uk = uchol(uk, kickrank+1);
                    uk = uk(:,end:-1:max(end-kickrank+1,1));
                end;
            else
                uk = rand(n(i)*ry(i+1), kickrank);
            end;
%             uk = rand(n(i)*ry(i+1), kickrank);
            [v,rv]=qr([v,uk], 0);
            radd = size(uk,2);
        end;
        u = [u, zeros(d2*ry(i), radd)];
        u = u*(rv.');
        r = size(v,2);

        cr2 = cry{i-1};
        cr2 = reshape(cr2, ry(i-1)*n(i-1), ry(i));
        u = reshape(u, d2, ry(i)*r);
        u = reshape(u.', ry(i), r*d2);
        u = cr2*u;

        u = reshape(u, ry(i-1)*n(i-1)*r, d2);
        u = reshape(u.', d2, ry(i-1), n(i-1), r);
        v = reshape(v.', r, n(i), ry(i+1));

        % Stuff back
        ry(i) = r;
        cry{i-1} = u;
        cry{i} = v;

        % Recompute left interface matrices
        % Interface matrix for Y
        Ry{i} = reshape(v, ry(i)*n(i), ry(i+1))*Ry{i+1};
        Ry{i} = reshape(Ry{i}, ry(i), n(i)*ry(i+1));
        curind = maxvol2(Ry{i}.','qr',do_qr);
        Ry{i} = Ry{i}(:, curind);
        % Interface matrices for X
        for j=1:nx
            Rx{i,j} = reshape(crX{i,j}, rx(i,j)*n(i), rx(i+1,j));
            Rx{i,j} = Rx{i,j}*Rx{i+1,j};
            Rx{i,j} = reshape(Rx{i,j}, rx(i,j), n(i)*ry(i+1));
            Rx{i,j} = Rx{i,j}(:, curind);
        end;
    elseif ((dir>0)&&(i==d))
        % Just stuff back the last core
        newy = u(:,1:r)*diag(s(1:r))*(v(:,1:r)');
        newy = reshape(newy, ry(i)*n(i)*ry(i+1), d2);
        cry{i} = reshape(newy.', d2, ry(i), n(i), ry(i+1));
    elseif ((dir<0)&&(i==1))
        % Just stuff back the last core
        newy = u(:,1:r)*diag(s(1:r))*(v(:,1:r)');
        newy = reshape(newy, d2, ry(i), n(i), ry(i+1));
        cry{i} = newy;
    end;

    i = i+dir;
    % Reversing, residue check, etc
    cur_order(order_index) = cur_order(order_index) - dir;
    % New direction
    if (cur_order(order_index)==0)
        order_index = order_index+1;

        if (verb>0)
            fprintf('=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g\n', swp, order_index-1, max_dy, sqrt(ry(1:d)'*(n.*ry(2:d+1))/sum(n)));
        end;

        if (last_sweep)
            break;
        end;

        if (max_dy<eps)&&(dir<0)
            last_sweep=true;
            kickrank=0;
        end;

        if (order_index>numel(cur_order)) % New global sweep
            cur_order = block_order;
            order_index = 1;
            %residue
            if (last_sweep)
                cur_order = d-1;
            end;

            max_dy = 0;
            swp = swp+1;
        end;

        dir = sign(cur_order(order_index));
        i = i+dir;
    end;
end

cry{d} = permute(cry{d}, [2,3,1]); % d2 is r(d+1)
y = cell2core(y, cry);

end


function [energy3M,entropy3M,sumAvg3M,corr3M,invDiffMom3M,contrast3M,...
    clustShade3M,clustPromin3M,haralCorr3M] = gpuTextureByPatch(scanArray3M, nL, ...
    patchSizeV, offsetsM, flagv, hWait, minIntensity,maxIntensity,separateDirnFlag)
% function [energy3M,entropy3M,sumAvg3M,corr3M,invDiffMom3M,contrast3M,...
%     clustShade3M,clustPromin3M] = gpuTextureByPatch(q, nL, ...
%     patchSizeV, offsetsM, flagv, hWait, minIntensity,maxIntensity,separateDirnFlag)
%
% Patch-wise texture calculation.
%
% APA, 09/09/2015

% Generate flags
if ~exist('flagv','var')
    flagv = ones(1,9);
elseif exist('flagv','var') && isempty(flagv)
    flagv = ones(1,9);
end

% Flag to draw waitbar
waitbarFlag = 0;
if exist('hWait','var') && ishandle(hWait)
    waitbarFlag = 1;
end

% Get indices of non-NaN voxels
calcIndM = ~isnan(scanArray3M);
% calcIndM = q > 0;

% % Grid resolution
slcWindow = 2 * patchSizeV(3) + 1;
rowWindow = 2 * patchSizeV(1) + 1;
colWindow = 2 * patchSizeV(2) + 1;

% Build distance matrices
numColsPad = floor(colWindow/2);
numRowsPad = floor(rowWindow/2);
numSlcsPad = floor(slcWindow/2);

% Get number of voxels per slice
[numRows, numCols, numSlices] = size(scanArray3M);
% [numRows, numCols, numSlices] = size(q);
numVoxels = numRows*numCols;

% Quantize the image

% minQ = min(scanArray3M(:));
% maxQ = max(scanArray3M(:));
% dq = (maxQ-minQ)/nL/4;
% levels = linspace(minQ,maxQ,nL);
% levels = linspace(dq,maxQ-dq,nL);
% q2 = imquantize(scanArray3M, levels);
%levels = multithresh(scanArray3M, nL);
%q3 = imquantize(scanArray3M, levels);

% q = imquantize_cerr(scanArray3M,nL);

% Pad q, so that sliding window works also for the edge voxels
%scanArrayTmp3M = padarray(scanArray3M,[numRowsPad numColsPad
%numSlcsPad],NaN,'both'); % aa commented
%q = padarray(q,[numRowsPad numColsPad numSlcsPad],NaN,'both');

% Quantize the image
if exist('minIntensity','var') && exist('maxIntensity','var')
    q = imquantize_cerr(scanArray3M,nL,minIntensity,maxIntensity);
else
    q = imquantize_cerr(scanArray3M,nL);
end

clear scanArray3M

% Pad q, so that sliding window works also for the edge voxels
%scanArrayTmp3M = padarray(scanArray3M,[numRowsPad numColsPad
%numSlcsPad],NaN,'both'); % aa commented
if exist('padarray.m','file')
    q = padarray(q,[numRowsPad numColsPad numSlcsPad],NaN,'both');
else
    q = padarray_oct(q,[numRowsPad numColsPad numSlcsPad],NaN,'both');
end
%nL = 16;
% if any(isnan(q)) % aa commented
%     nL = nL-1; % aa commented
% end % aa commented
%q = imquantize_cerr(scanArrayTmp3M,nL); % aa commented
%clear scanArrayTmp3M; % aa commented
%qmax = max(q(:));
nanFlag = 0; % the quantized image is always padded with NaN. Hence, always,
             % nanFlag = 1.
if any(isnan(q(:)))
    nanFlag = 1;
    q(isnan(q)) = nL+1;
end
lq = nL + 1;

% qs=sort(unique(q));
% lq=length(qs);
% for k = 1:length(qs)
% 	q(q==qs(k)) = k;
% end

q = uint16(q); % q is the quantized image
%numSlcsWithPadding = size(q,3);

% Create indices for 2D blocks
[m,n,~] = size(q);
m = uint32(m);
n = uint32(n);
colWindow = uint32(colWindow);
rowWindow = uint32(rowWindow);
slcWindow = uint32(slcWindow);

% Index calculation adapted from
% http://stackoverflow.com/questions/25449279/efficient-implementation-of-im2col-and-col2im

%// Start indices for each block
start_ind = reshape(bsxfun(@plus,[1:m-rowWindow+1]',[0:n-colWindow]*m),[],1); %//'

%// Row indices
lin_row = permute(bsxfun(@plus,start_ind,[0:rowWindow-1])',[1 3 2]);  %//'

%// Get linear indices based on row and col indices and get desired output
% imTmpM = A(reshape(bsxfun(@plus,lin_row,[0:ncols-1]*m),nrows*ncols,[]));
indM = reshape(bsxfun(@plus,lin_row,(0:colWindow-1)*m),rowWindow*colWindow,[]);

% Directional offsets
numOffsets = size(offsetsM,1);

% Indices of last level to filter out
nanIndV = false([lq*lq,1]);
if nanFlag
    nanIndV([lq:lq:lq*lq-lq, lq*lq-lq:lq*lq]) = true;
end

% Build levels vector for mu, sig
levRowV = repmat(1:lq,[1 lq]);
levColV = repmat(1:lq,[lq 1]);
levColV = levColV(:)';

% Build list of indices for px and contrast calculation
numElems = nL*nL; % APA 7/13
indCtrstM = false(nL,numElems); % APA 7/13
indPxM = false(nL,numElems); % APA 7/13
indPxPlusYm = false(nL,numElems); % APA 7/13
% for n=0:lq-1 % APA 7/13
for n = 0:nL-1
    % indices for p(x-y), contrast
    indCtrstV = false(lq*lq,1);
    indCtrst1V = 1:lq-n;
    indCtrst2V = 1+n:lq;
    indCtrstTmpV = indCtrst1V + (indCtrst2V-1)*lq;
    indCtrstTmpV = [indCtrstTmpV indCtrst2V + (indCtrst1V-1)*lq];
    indCtrstV(indCtrstTmpV) = 1;
    indCtrstV(nanIndV) = [];
    % indCtrstC{n+1} = indCtrstV; % APA 7/13
    indCtrstM(n+1,:) = indCtrstV;

    % indices for px
    indPxV = false(lq*lq,1);
    indPxV(lq*n+1:lq*(n+1)) = true;
    indPxV(nanIndV) = [];
    % indPxC{n+1} = indPxV; % APA 7/13
    indPxM(n+1,:) = indPxV;

end
% for n=1:2*lq
for n=1:2*nL
    % indices for p(x+y)
    indPxPlusYv = false(lq*lq,1);
    indPxPlusYv(levRowV + levColV == n) = 1;
    indPxPlusYv(nanIndV) = [];
    % indPxPlusYc{n} = indPxPlusYv; % APA 7/13
    indPxPlusYm(n,:) = indPxPlusYv;
end

% Build linear indices column/row-wise for Symmetry
indRowV = zeros(1,lq*lq,'uint16');
for i=uint16(1:lq)
    indRowV((i-1)*lq+1:(i-1)*lq+lq) = i:lq:lq*lq;
end

% Filter out NaN levels
levRowV(nanIndV) = [];
levColV(nanIndV) = [];

% Upload indices to GPU
indPxM = gpuArray(single(indPxM));
indPxPlusYm = gpuArray(single(indPxPlusYm));
indCtrstM = gpuArray(single(indCtrstM));

dim = 1;
if separateDirnFlag
    dim = numOffsets;
end

% Initialize
energy3M = [];
entropy3M = [];
sumAvg3M = [];
corr3M = [];
invDiffMom3M = [];
contrast3M = [];
clustShade3M = [];
clustPromin3M = [];
haralCorr3M = [];
if flagv(1)
    energy3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(2)
    entropy3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(3)
    sumAvg3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(4)
    corr3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(5)
    invDiffMom3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(6)
    contrast3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(7)
    clustShade3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(8)
    clustPromin3M = zeros([numRows, numCols, numSlices, dim],'single');
end
if flagv(9)
    haralCorr3M = zeros([numRows, numCols, numSlices, dim],'single');
end

tic
% Iterate over slices. compute cooccurance for all patches per slice
parfor (slcNum = 1:numSlices,4)

    disp(['--- Texture Calculation for Slice # ', num2str(slcNum), ' ----'])
    if flagv(1), energyV = zeros(dim,numVoxels,'single'); end
    if flagv(2), entropyV = zeros(dim,numVoxels,'single'); end
    if flagv(3), sumAvgV = zeros(dim,numVoxels,'single'); end
    if flagv(4), corrV = zeros(dim,numVoxels,'single'); end
    if flagv(5), invDiffMomV = zeros(dim,numVoxels,'single'); end
    if flagv(6), contrastV = zeros(dim,numVoxels,'single'); end
    if flagv(7), clustShadeV = zeros(dim,numVoxels,'single'); end
    if flagv(8), clustProminV = zeros(dim,numVoxels,'single'); end
    if flagv(9), haralCorrV = zeros(dim,numVoxels,'single'); end

    calcSlcIndV = calcIndM(:,:,slcNum);
    calcSlcIndV = calcSlcIndV(:);
    numCalcVoxs = sum(calcSlcIndV);
    %indSlcM = indM(:,calcSlcIndV); %moved to offset loop
    % List of Voxel numbers
    voxelNumsV = uint32(0:lq*lq:lq*lq*(numCalcVoxs-1));
    %voxelNumsV = uint32(0:nL*nL:nL*nL*(numCalcVoxs-1));
    for off = 1:numOffsets
        % Get voxels for this slice
        indSlcM = indM(:,calcSlcIndV);
        %cooccurPatchM = zeros(lq*lq*numCalcVoxs,1,'double'); % APA 7/13
        %cooccurPatchM = sparse(nL*nL*numCalcVoxs,1); % APA 7/13
        %cooccurPatchM = zeros(nL*nL*numCalcVoxs,1,'single'); % APA 7/14
        offset = offsetsM(off,:);
        % Choose correct neighbors for the selected offset. i.e. the
        % correct rows from indSlcM
        indNoNeighborV = [];
        if offset(1) == 1
            indNoNeighborV = [indNoNeighborV 1:rowWindow:rowWindow*colWindow];
        elseif offset(1) == -1
            indNoNeighborV = [indNoNeighborV rowWindow:rowWindow:rowWindow*colWindow];
        end
        if offset(2) == 1
            indNoNeighborV = [indNoNeighborV 1:colWindow];
        elseif offset(2) == -1
            indNoNeighborV = [indNoNeighborV rowWindow*colWindow:-1:(rowWindow*colWindow-colWindow)+1];
        end
        indSlcM(indNoNeighborV,:) = [];

        % index for various scalar features
        featDim = min(dim,off);

        slcNumV = slcNum:slcNum+slcWindow-1; % slices within the patch
        C = cell(length(slcNumV),1);
        for iSlc = 1:length(slcNumV)
            slc = slcNumV(iSlc);
            if slc-slcNum+offset(3) >= slcWindow
                continue;
            end
            slc1M = uint16(q(numRowsPad+(1:numRows),numColsPad+(1:numCols),slc));
            slc2M = uint16(q(:,:,slc+offset(3)));
            slc2M = circshift(slc2M,offset(1:2));
            slc2M(numRowsPad+(1:numRows),numColsPad+(1:numCols)) = ...
                slc2M(numRowsPad+(1:numRows),numColsPad+(1:numCols)) + (slc1M-1)*lq;
%             for colNum = 1:numCalcVoxs
%                 cooccurPatchTmpM(:,colNum) = ...
%                     accumarray(slc2M(indSlcM(:,colNum)),1,[lq*lq,1]);
%             end
            slc2M = uint32(slc2M(indSlcM));
            %slcTransp2M = uint32(indRowV(slc2M)); % for symmetry
            %nanInd2M = nanIndV(slc2M);
            slc2M = bsxfun(@plus,slc2M,voxelNumsV);
            %nanIndTransp2M = nanIndV(slcTransp2M);
            %slcTransp2M = bsxfun(@plus,slcTransp2M,voxelNumsV);
            cooccurSlcM = accumarray(slc2M(:) ...
                ,1, [lq*lq*numCalcVoxs,1],[],...
                [],true); % patch-wise cooccurance
            indToAddV = find(cooccurSlcM > 0);
            C{iSlc} = [indToAddV,cooccurSlcM(indToAddV)];
            %cooccurPatchM(indToAddV) = cooccurPatchM(indToAddV) + cooccurSlcM(indToAddV);
        end
        IJV = cell2mat(C);
        cooccurPatchM = sparse(IJV(:,1),IJV(:,1).^0,IJV(:,2),lq*lq*numCalcVoxs,1);
        cooccurPatchM = reshape(cooccurPatchM,lq*lq,numCalcVoxs);
        cooccurPatchM = cooccurPatchM + cooccurPatchM(indRowV,:); % for symmetry
        cooccurPatchM(nanIndV,:) = [];
        %cooccurPatchM = cooccurPatchM(~nanIndV,:);
        cooccurPatchM = bsxfun(@rdivide,cooccurPatchM,sum(cooccurPatchM)+1e-5);
        cooccurPatchM = gpuArray(full(cooccurPatchM));
        % Calculate scalar texture for this offset
        % Angular Second Moment (Energy)
        if flagv(1)
            energyV(featDim,calcSlcIndV) = energyV(featDim,calcSlcIndV) + ...
                gather(sum(cooccurPatchM .* cooccurPatchM)); % cooccurPatchM.^2
        end
        % Entropy
        if flagv(2)
            entropyV(featDim,calcSlcIndV) = entropyV(featDim,calcSlcIndV) - ...
                gather(sum(cooccurPatchM.*log2(cooccurPatchM+1e-10)));
        end
        % Contrast, inverse Difference Moment
%         cooccurPatchSiz = size(cooccurPatchM,2); % APA 7/13
%         px = zeros(nL,cooccurPatchSiz,'single'); %px = []; % APA 7/13
%         pXminusY = zeros(nL,cooccurPatchSiz,'single'); %pXminusY = []; % APA 7/13
%         pXplusY = zeros(nL,cooccurPatchSiz,'single'); %pXplusY = []; % APA 7/13
%         for n=0:nL-1
%             cooccurPatchM(indPxM(n+1,:),:);
%             % px
%             % px(n+1,:) = sum(cooccurPatchM(indPxC{n+1},:),1); % APA 7/13
%             px(n+1,:) = sum(cooccurPatchM(indPxM(n+1,:),:),1); % APA 7/13
%             % p(x-y)
%             % pXminusY(n+1,:) = sum(cooccurPatchM(indCtrstC{n+1},:),1); %
%             % APA 7/13
%             pXminusY(n+1,:) = sum(cooccurPatchM(indCtrstM(n+1,:),:),1); % APA 7/13
%             % Contrast
%             if flagv(6)
%                 %contrastV(featDim,calcSlcIndV) = contrastV(featDim,calcSlcIndV) + ...
%                 %    sum(n^2*cooccurPatchM(indCtrstC{n+1},:)); % APA 7/13
%                 contrastV(featDim,calcSlcIndV) = contrastV(featDim,calcSlcIndV) + ...
%                     sum(n^2*cooccurPatchM(indCtrstM(n+1,:),:)); % APA 7/13
%
%             end
%             % inv diff moment
%             if flagv(5)
%                 %invDiffMomV(featDim,calcSlcIndV) = invDiffMomV(featDim,calcSlcIndV) + ...
%                 %    sum((1/(1+n^2))*cooccurPatchM(indCtrstC{n+1},:)); %
%                 %    APA 7/13
%                 invDiffMomV(featDim,calcSlcIndV) = invDiffMomV(featDim,calcSlcIndV) + ...
%                     sum((1/(1+n^2))*cooccurPatchM(indCtrstM(n+1,:),:)); % APA 7/13
%
%             end
%         end
%
%         for n=1:2*nL
%             % p(x+y)
%             % pXplusY(n,:) = sum(cooccurPatchM(indPxPlusYc{n},:),1); % APA
%             % 7/13
%             pXplusY(n,:) = sum(cooccurPatchM(indPxPlusYm(n,:),:),1);
%             % Sum Average
%             if flagv(3)
%                 sumAvgV(featDim,calcSlcIndV) = sumAvgV(featDim,calcSlcIndV) ...
%                     + n*pXplusY(n,:);
%             end
%         end
        px = indPxM * cooccurPatchM;
        %pXminusY = indCtrstM * cooccurPatchM;
        %pXplusY = indPxPlusYm * cooccurPatchM;
        contrastV(featDim,calcSlcIndV) = contrastV(featDim,calcSlcIndV) + ...
            gather((0:nL-1).^2 * indCtrstM * cooccurPatchM);
        invDiffMomV(featDim,calcSlcIndV) = invDiffMomV(featDim,calcSlcIndV) + ...
            gather(1./(1+(0:nL-1).^2) * indCtrstM * cooccurPatchM);
        sumAvgV(featDim,calcSlcIndV) = sumAvgV(featDim,calcSlcIndV) + ...
            gather((1:2*nL) * indPxPlusYm * cooccurPatchM);

        % weighted pixel average (mu), weighted pixel variance (sig)
        mu = (1:nL) * px;
        sig = bsxfun(@minus,(1:nL)',mu);
        sig = sum(sig .*sig .* px, 1);

        if flagv(4) || flagv(7) || flagv(8)
            levIMinusMu = bsxfun(@minus,levRowV',mu);
            levJMinusMu = bsxfun(@minus,levColV',mu);
        end

        % Correlation
        if flagv(4)
            corrV(featDim,calcSlcIndV) = corrV(featDim,calcSlcIndV) + ...
                gather(sum(levIMinusMu .* levJMinusMu  .* cooccurPatchM, 1) ...
                ./ (sig + 1e-10)); % sig.^2 to match ITK results (ITK bug)
        end

        % Cluster Shade
        if flagv(7)
            clstrV = levIMinusMu + levJMinusMu;
            clustShadeV(featDim,calcSlcIndV) = clustShadeV(featDim,calcSlcIndV) + ...
                gather(sum(clstrV.*clstrV.*clstrV .* cooccurPatchM, 1));
        end
        % Cluster Prominence
        if flagv(8)
            clstrV = levIMinusMu + levJMinusMu;
            clustProminV(featDim,calcSlcIndV) = clustProminV(featDim,calcSlcIndV) + ...
                gather(sum(clstrV.*clstrV.*clstrV.*clstrV .* cooccurPatchM, 1));
        end

        % Haralick Correlation
         if flagv(9)
             % muX = mean(px,1);
             muX = 1/nL;
             % sigX = bsxfun(@minus,px,muX);
             sigX = px - muX;
             sigX = sum(sigX .*sigX, 1)/(nL);

%              % Knuth method for mean and standard deviation (like ITK)
%              muX = px(1,:);
%              muPrevX = muX;
%              sigX = muX*0;
%              for col = 2:size(px,1)
%                  muX = muPrevX + (px(col,:) - muPrevX)/col;
%                  sigX = sigX + (px(col,:)-muX).*(px(col,:)-muPrevX);
%                  muPrevX = muX;
%              end
%              sigX = sigX/nL;

             haralCorrV(featDim,calcSlcIndV) = haralCorrV(featDim,calcSlcIndV) + ...
                 gather((levRowV .* levColV * cooccurPatchM - ...
                 muX .* muX) ./ (sigX + eps));   % (levRowV-1) .* (levColV-1) to match ITK? Bug?

         end
    end

    % Average texture from all directions
    if flagv(1)
        energyV = energyV / numOffsets;
        energy3M(:,:,slcNum,:) = reshape(energyV',[numRows, numCols, 1, dim]);
    end
    if flagv(2)
        entropyV = entropyV / numOffsets;
        entropy3M(:,:,slcNum,:) = reshape(entropyV',[numRows, numCols, 1, dim]);
    end
    if flagv(3)
        sumAvgV = sumAvgV / numOffsets;
        sumAvg3M(:,:,slcNum,:) = reshape(sumAvgV',[numRows, numCols, 1, dim]);
    end
    if flagv(4)
        corrV = corrV / numOffsets;
        corr3M(:,:,slcNum,:) = reshape(corrV',[numRows, numCols, 1, dim]);
    end
    if flagv(5)
        invDiffMomV = invDiffMomV / numOffsets;
        invDiffMom3M(:,:,slcNum,:) = reshape(invDiffMomV',[numRows, numCols, 1, dim]);
    end
    if flagv(6)
        contrastV = contrastV / numOffsets;
        contrast3M(:,:,slcNum,:) = reshape(contrastV',[numRows, numCols, 1, dim]);
    end
    if flagv(7)
        clustShadeV = clustShadeV / numOffsets;
        clustShade3M(:,:,slcNum,:) = reshape(clustShadeV',[numRows, numCols, 1, dim]);
    end
    if flagv(8)
        clustProminV = clustProminV / numOffsets;
        clustPromin3M(:,:,slcNum,:) = reshape(clustProminV',[numRows, numCols, 1, dim]);
    end
    if flagv(9)
        haralCorrV = haralCorrV / numOffsets;
        haralCorr3M(:,:,slcNum,:) = reshape(haralCorrV',[numRows, numCols, 1, dim]);
    end

    if waitbarFlag
        set(hWait, 'Vertices', [[0 0 slcNum/numSlices slcNum/numSlices]' [0 1 1 0]']);
        drawnow;
    end

end
toc