function [fallback,dodge_x,dodge_color,dodge_lightness,dodge_ind,dodge_n]=dodge_comp(x,color,lightness,uni_color,uni_lightness)

if iscell(x)
    %If x is given as cell, we don't do the advanced dodging
    fallback=true;
    uni_x=1;
else
    fallback=false;
    uni_x=unique(x);
    %Here we need to implement a loose 'unique' because of
    %potential numerical errors
    uni_x(diff(uni_x)<1e-10)=[];

    %Fallback if there are too many unique x values (dodging only makes
    %sense for discrete x values)... 4000 x unique values is already a lot
    %but quick enough to compute below
    if numel(uni_x)>2000
        fallback=true;
        uni_x=1;
    end
end

N=length(uni_x)*length(uni_color)*length(uni_lightness);

%Initialize return values
dodge_x=zeros(N,1);
if iscell(color)
    dodge_color=cell(N,1);
else
    dodge_color=zeros(N,1);
end
if iscell(lightness)
    dodge_lightness=cell(N,1);
else
    dodge_lightness=zeros(N,1);
end
dodge_ind=zeros(N,1);
dodge_n=zeros(N,1);

ind=1;

%Loop over unique X values and count how many lightness and color values
%there are for each (unless we are in fallback in which case we plan for
%all possible lightness and colors).
for ind_x=1:length(uni_x)

    if ~fallback
        %And here we have a loose selection also because of
        %potential numerical errors
        sel=abs(x-uni_x(ind_x))<1e-10;
    end

    temp_ind=1;

    for ind_color=1:length(uni_color)

        if ~fallback
            sel_color=sel & multi_sel(color,uni_color{ind_color});
        end

        %loop over lightness
        for ind_lightness=1:length(uni_lightness)

            if ~fallback
                sel_lightness=sel_color & multi_sel(lightness,uni_lightness{ind_lightness});
            end

            if fallback || any(sel_lightness)
                dodge_x(ind)=uni_x(ind_x);
                if iscell(color)
                    dodge_color{ind}=uni_color{ind_color};
                else
                    dodge_color(ind)=uni_color{ind_color};
                end
                if iscell(lightness)
                    dodge_lightness{ind}=uni_lightness{ind_lightness};
                else
                    dodge_lightness(ind)=uni_lightness{ind_lightness};
                end
                dodge_ind(ind)=temp_ind;

                temp_ind=temp_ind+1;
                ind=ind+1;
            end
        end
    end

    dodge_n(ind-(temp_ind-1):ind-1)=temp_ind-1;

end

dodge_x=dodge_x(1:ind-1);
dodge_color=dodge_color(1:ind-1);
dodge_lightness=dodge_lightness(1:ind-1);
dodge_ind=dodge_ind(1:ind-1);
dodge_n=dodge_n(1:ind-1);

end


function out_backprop()
    global config mem;
    current_layer = config.misc.current_layer;
    mem.deltas{current_layer} = config.DERI_OUT_ACT(config.DERI_COST_FUN(mem.output, mem.GT_output));
    config.EXPAND_DELTA_OUT();
    config.misc.current_layer = config.misc.current_layer - 1;
end


clear all; close all;
I=imread('pout.tif');
J=imadjust(I, [0.1 0.5], [0, 1], 0.4);
K=imadjust(I, [0.1, 0.5], [0, 1], 4);
figure;
subplot(121);
imshow(uint8(J));
subplot(122);
imshow(uint8(K));


function [ know, x ] = p10_sol ( n )

%*****************************************************************************80
%
%% P10_SOL returns the solution for problem 10.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 October 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the problem.  This value
%    is only needed for those problems with variable N.
%
%    Output, integer KNOW.
%    If KNOW is 0, then the solution is not known.
%    If KNOW is positive, then the solution is known, and is returned in X.
%
%    Output, real X(N), the solution, if known.
%
  know = 1;

  x = [ 1.0E+06, 2.0E-06 ]';

  return
end


xk=[0,0]';
dk=-grad_obj2(xk);
alpha=linspace(0,0.1,50);
phi_alpha=zeros(1,50);
for i=1:50
    phi_alpha(i)=phi(alpha(i),xk,dk);
end

plot(alpha,phi_alpha);


filename='Cantilever_triangle_fine';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = 1;
constraint = {'volume'};
optimizer = 'SLERP';
incrementFactor = 1;
designVariable = 'LevelSet';
filterType = 'P1';
constraint_case = 'INEQUALITY';
line_search_initiator = 'STANDARD';

nsteps = 15;
Vfrac_final = 0.4;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

Vfrac_initial = 1;
optimality_initial = 1e-3;
constr_initial = 1e-3;
TOL.rho_plus = 1;
TOL.rho_minus = 0;
TOL.E_plus = 1;
TOL.E_minus = 1e-3;
TOL.nu_plus = 1/3;
TOL.nu_minus = 1/3;


function handles = plotTMPCPrediction(ax, tPred, data, plot_tube, center_points, M_s, be_l, be_u, K_t, ...
    isConstrained, ub, lb, direction, isInput, TargetAvailable, target, LinearizationAvailable, lin)
% function plotStatePrediction
% Authors:      Martin Euler
%               Alexander Wischnewski
% Description:
%   helper function used to plot state predictions
% Inputs/parameters:
%   tPlot: vector containing the time window for plotting [tStart, tEnd]
%   tPred: vector with the time instants corresponding to the prediction
%   data: data of real beahvior
%   plot_tube: flag for tube plots
%   center_points: data for center points
%   M_s: tube shape matrices
%   be_l: lower bound of terminal set constraints
%   be_u: upper bound of terminal set constraints
%   K_t: tube controller
%   isConstrained: flag whether the signal is constrained or not
%   ub: upper limit for the signal
%   lb: lower limit for the signal
%   isInput: set to true in case this is an input (different calculation of tubes)
%   TargetAvailable: target trajectory available and should be plotted
%   target: actual target trajectory
%   LinearizationAvailable: linearization trajectory available and should be plotted
%   lin: actual linearization trajectory

% plot real signal
handles.real = plot(ax, data.Time, data.Data, 'Color', [0 0.3961 0.7412], ...
    'LineWidth', 1, 'DisplayName', 'Real');
% plot predicted signal
handles.pred = plot(ax, tPred, center_points, '*', 'Color', [0.8902, 0.4471, 0.1333], ...
    'DisplayName', 'Prediction');
% plot tube and terminal sets
if plot_tube
    % get tube bounds
    [y_low, y_up] = calcBoundsPlot(center_points, M_s, isInput, K_t, length(tPred), direction);
    % plot tube lower bounds
    handles.tube_ub = plot(ax, tPred, y_low(1,:), '-.', ...
        'Color', [0, 0, 0], 'LineWidth', 1, 'DisplayName', 'Tube');
    % plot tube upper bounds
    handles.tube_lb = plot(ax, tPred, y_up(1,:), '-.', ...
        'Color', [0, 0, 0], 'LineWidth', 1, 'HandleVisibility','off');
    % plot terminal set lower bounds and use a virtual time interval of one second (half a second
    % forth and back) to visualize it properly
    handles.terminal_ub = plot(ax, [tPred(end)-0.5, tPred(end)+0.5], be_l*ones(2, 1), ...
        'Color', [0, 0, 1],'LineWidth', 1.1, 'DisplayName', 'Terminal set');
    % plot terminal set upper bounds
    handles.terminal_lb = plot(ax, [tPred(end)-0.5, tPred(end)+0.5], be_u*ones(2, 1), ...
        'Color', [0, 0, 1], 'LineWidth', 1.1,'HandleVisibility','off');
else
end
if isConstrained
    handles.const_lb = plot(ax, tPred, ub, 'm--', ...
        'Color', [0.6275 0.1255 0.9412], 'LineWidth', 1, 'HandleVisibility', 'off');
    handles.const_ub = plot(ax, tPred, lb, 'm--', ...
        'Color', [0.6275 0.1255 0.9412], 'LineWidth', 1, 'DisplayName', 'Constraint');
end
if TargetAvailable
    handles.target = plot(ax, tPred, target, '-', 'DisplayName', 'Target');
end
if LinearizationAvailable
    handles.lin = plot(ax, tPred, lin, 'c', 'DisplayName', 'Linearization');
end

% adjust x limits appropriately such that it covers a certain range
xlim(ax, [tPred(1)-5, tPred(1)+10]);
legend(ax);

end


% seconds of the day.
function sod = mydatesod (epoch, epoch0)
    if (nargin < 2),  epoch0 = [];  end
    if isempty(epoch)
        sod = epoch;
        return;
    end
    num0 = mydatesod_aux (epoch, epoch0);

    if (size(epoch,2) == 1)
        % epoch is in mydatenum format
        num = epoch;
        %no need to calculate vec.
        %vec = mydatevec(num);
    else
        % epoch is in mydatevec format
        vec = epoch;
        num = mydatenum(vec);
    end

    %%
    sod = (num - num0);
    %num, num0  % DEBUG
    %vec, vec0  % DEBUG
end

%!test
%! d = [2000 1 1 0 5 0];
%! sod_correct = 300;
%! sod_answer = mydatesod(mydatenum(d));
%! myassert (sod_answer, sod_correct, -sqrt(eps));

%!test
%! d  = [2000 1 2 0 5 0];
%! d0 = [2000 1 1 0 0 0];
%! sod_correct = 300 + 24*60^2;
%! sod_answer = mydatesod(mydatenum(d), d0);
%! myassert (sod_answer, sod_correct, -sqrt(eps));
%! sod_answer = mydatesod(mydatenum(d), mydatenum(d0));
%! myassert (sod_answer, sod_correct, -sqrt(eps));

%!test
%! in = NaN(2,1);
%! out = mydatesod(in);
%! myassert(out, in)


%TESTDATASIZE of datafiles and convert to dataset
%
%	 B = TESTDATASIZE(A,STRING)
%  I = TESTDATASIZE(A,STRING,FALSE)
%  I = TESTDATASIZE(N)
%
% INPUT
%  A         datafile or dataset
%  STRING    'data' (default) or 'features' or 'objects'
%  N         Given data size to be tested
%
% OUTPUT
%  B         Converted dataset
%  I         TRUE:  conversion possible
%            FALSE: conversion not possible
%
% DESCRIPTION
% Depending on the value of PRMEMORY and the size of the datafile A, it is
% converted to a dataset, otherwise an error is generated.
% In case the third parameter is FALSE or the first is a scalar just a test
% is executed. In case of no output arguments an error is generated if
% conversion in impossible.
%
% The parameter STRING controls the type of comparison:
%
% 'data'          PROD(SIZE(A)) < PRMEMORY
% 'objects'       SIZE(A,1).^2  < PRMEMORY
% 'features'      SIZE(A,2).^2  < PRMEMORY
%
% SEE ALSO (PRTools Guide)
% DATASETS, DATAFILES, PRMEMORY

% Copyright: R.P.W. Duin, r.p.w.duin@37steps.com
% Faculty EWI, Delft University of Technology
% P.O. Box 5031, 2600 GA Delft, The Netherlands

function b = testdatasize(a,type,flag)

	if nargin < 3,
		flag = 1;
	end

	if nargin < 2
		type = 'data';
  end

  b = true;
	if nargin == 1 & isdouble(a) & numel(a) == 1
    % estimated data size in a
    if a > prmemory
      if nargout == 0
        error(['Dataset too large for memory.' newline ...
          'Size (Mega elements) is ' int2str(round(a/1000000)) ', memory is ' int2str(prmemory/1000000) newline ...
          'Possible solutions:' newline ...
          '- decrease data size' newline ...
          '- increase PRMEMORY, see prmemory' newline ...
          '- consider batch processing, see setbatch']);
      else
        b = false;
      end
    end
    return
  end

	if isdataset(a) | isdouble(a)
		if flag
			b = a;
		end
		return
	end

  % Now we have a datafile
	a = setfeatsize(a,0); % featsize of datafiles is unreliable
	switch type
		case 'data'
			if prod(size(a)) > prmemory
				if flag
					error(['Dataset too large for memory.' newline ...
          'Size is ' int2str(prod(size(a))) ', memory is ' int2str(prmemory) newline ...
          'Possible solutions:' newline ...
          '- decrease data size' newline ...
          '- increase PRMEMORY, see prmemory' newline ...
          '- consider batch processing, see setbatch']);
				else
					b = false;
				end
			end
		case 'objects'
			if size(a,1).^2 > prmemory
				if flag
					error(['Number of objects too large for memory.' newline ...
          'Size is ' int2str(size(a,1).^2) ', memory is ' int2str(prmemory) newline ...
          'Possible solutions:' newline ...
          '- decrease data size' newline ...
          '- increase PRMEMORY, see prmemory' newline ...
          '- consider batch processing, see setbatch']);
				else
					b = false;
				end
			end
		case 'features'
			if size(a,2).^2 > prmemory
				if flag
					error(['Number of features too large for memory.' newline ...
          'Size is ' int2str(size(a,2).^2) ', memory is ' int2str(prmemory) newline ...
          'Possible solutions:' newline ...
          '- decrease data size' newline ...
          '- increase PRMEMORY, see prmemory' newline ...
          '- consider batch processing, see setbatch']);
				else
					b = false;
				end
			end
		otherwise
			error('Unknown test requested')
	end
	if nargout > 0
		if flag
			b = prdataset(a);
		end
	end

return


function []=panel6disp(n,N,m,p,k,T,d1,d2,d3,d4,d5,d,Ymat,Xtilde,Units,endo,exo,const,Xi,theta_median,theta_std,theta_lbound,theta_ubound,sigma_median,D_estimates,gamma_estimates,alpha0,delta0,gama,a0,b0,rho,psi,acceptrate,startdate,enddate,forecast_record,forecast_estimates,Fcperiods,stringdates3,Fstartdate,Fcenddate,Feval,Fcomp,data_endo_c,IRF,IRFt,pref,names)

% recover a point estimate (the median) of the VAR coefficients
betatilde=Xi*theta_median(:,:,end);
Btilde=reshape(betatilde,k,N*n);

% check whether the model is stationary
[stationary,eigmodulus]=bear.checkstable(betatilde,N*n,p,k);

% estimate the in-sample evaluation criteria

% obtain a point estimate thetatilde of the structural factors, which is the median
Thetatilde=reshape(theta_median,T*d,1);
% compute fitted values
Ytilde=full(reshape(Xtilde*Thetatilde,N*n,T)');
% reshape for convenience
Ytilde=reshape(Ytilde,T,n,N);
Ymat=reshape(Ymat,T,n,N);

% loop over units
for ii=1:N
% estimate the residuals for this unit
EPS(:,:,ii)=Ymat(:,:,ii)-Ytilde(:,:,ii);

% Compute then the sum of squared residuals
% compute first the RSS matrix, defined in (1.9.5)
RSS(:,:,ii)=EPS(:,:,ii)'*EPS(:,:,ii);
% retain only the diagonal elements to get the vector of RSSi values
rss(:,:,ii)=diag(RSS(:,:,ii));

% Go on calculating R2
% generate Mbar
Mbar=eye(T)-ones(T,T)/T;
% then compute the TSS matrix, defined in (1.9.8)
TSS(:,:,ii)=Ymat(:,:,ii)'*Mbar*Ymat(:,:,ii);
% generate the R2 matrix in (1.9.9)
R2(:,:,ii)=eye(n)-RSS(:,:,ii)./TSS(:,:,ii);
% retain only the diagonal elements to get the vector of R2 values
r2(:,:,ii)=diag(R2(:,:,ii));

% then calculate the adjusted R2, using (1.9.11)
R2bar(:,:,ii)=eye(n)-((T-1)/(T-k))*(eye(n)-R2(:,:,ii));
% retain only the diagonal elements to get the vector of R2bar values
r2bar(:,:,ii)=diag(R2bar(:,:,ii));

end

% estimate the forecast evaluation criteria
% first note that forecast evaluation can only be conducted if it is activated, and if there is some observable data after the beginning of the forecast
if Feval==1 && Fcomp==1

% generate the elements required for the evaluation
forecast_record=reshape(forecast_record,N*n,1);
forecast_estimates=reshape(forecast_estimates,N*n,1);
data_endo_c=reshape(data_endo_c,Fcperiods,N*n);

% compute forecast evaluation
[RMSE,MAE,MAPE,Ustat,CRPS_estimates]=bear.panel6feval(N,n,forecast_record,forecast_estimates,Fcperiods,data_endo_c);

end

% start displaying and saving the general results

% preliminary task: create and open the txt file used to save the results

filelocation=fullfile(pref.results_path, [pref.results_sub '.txt']);
fid=fopen(filelocation,'wt');

% print toolbox header

fprintf('%s\n','');
fprintf(fid,'%s\n','');

% print the list of contributors
bear.printcontributors(fid);

% print then estimation results

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

toolboxinfo='BEAR toolbox estimates';
fprintf('%s\n',toolboxinfo);
fprintf(fid,'%s\n',toolboxinfo);

time=clock;
datestring=datestr(time);
dateinfo=['Date: ' datestring(1,1:11) '   Time: ' datestring(1,13:17)];
fprintf('%s\n',dateinfo);
fprintf(fid,'%s\n',dateinfo);

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

VARtypeinfo='Panel VAR: structural factor (dynamic)';
fprintf('%s\n',VARtypeinfo);
fprintf(fid,'%s\n',VARtypeinfo);

if IRFt==1
SVARinfo='structural decomposition: none';
fprintf('%s\n',SVARinfo);
fprintf(fid,'%s\n',SVARinfo);
elseif IRFt==2
SVARinfo='structural decomposition: choleski factorisation';
fprintf('%s\n',SVARinfo);
fprintf(fid,'%s\n',SVARinfo);
elseif IRFt==3
SVARinfo='structural decomposition: triangular factorisation';
fprintf('%s\n',SVARinfo);
fprintf(fid,'%s\n',SVARinfo);
end

temp='units: ';
for ii=1:N
temp=[temp ' ' Units{ii,1} ' '];
end
unitinfo=temp;
fprintf('%s\n',unitinfo);
fprintf(fid,'%s\n',unitinfo);

temp='endogenous variables: ';
for ii=1:n
temp=[temp ' ' endo{ii,1} ' '];
end
endoinfo=temp;
fprintf('%s\n',endoinfo);
fprintf(fid,'%s\n',endoinfo);

temp='exogenous variables: ';
if const==0 && m==0
temp=[temp ' none'];
elseif const==1 && m==1
temp=[temp ' constant '];
elseif const==0 && m>0
   for ii=1:m-1
   temp=[temp ' ' exo{ii,1} ' '];
   end
elseif const==1 && m>1
temp=[temp ' constant '];
   for ii=1:m-1
   temp=[temp ' ' exo{ii,1} ' '];
   end
end
exoinfo=temp;
fprintf('%s\n',exoinfo);
fprintf(fid,'%s\n',exoinfo);

sampledateinfo=['estimation sample: ' startdate '-' enddate];
fprintf('%s\n',sampledateinfo);
fprintf(fid,'%s\n',sampledateinfo);

samplelengthinfo=['sample size (omitting initial conditions): ' num2str(T)];
fprintf('%s\n',samplelengthinfo);
fprintf(fid,'%s\n',samplelengthinfo);

laginfo=['number of lags included in regression: ' num2str(p)];
fprintf('%s\n',laginfo);
fprintf(fid,'%s\n',laginfo);

hyperparam1='hyperparameters:';
fprintf('%s\n',hyperparam1);
fprintf(fid,'%s\n',hyperparam1);

hyperparam2=['IG shape on residual variance (alpha0):         ' num2str(alpha0)];
fprintf('%s\n',hyperparam2);
fprintf(fid,'%s\n',hyperparam2);

hyperparam3=['IG scale on residual variance (delta0):         ' num2str(delta0)];
fprintf('%s\n',hyperparam3);
fprintf(fid,'%s\n',hyperparam3);

hyperparam4=['AR coefficient on residual variance (gamma):    ' num2str(gama)];
fprintf('%s\n',hyperparam4);
fprintf(fid,'%s\n',hyperparam4);

hyperparam5=['IG shape on factor variance (a0):               ' num2str(a0)];
fprintf('%s\n',hyperparam5);
fprintf(fid,'%s\n',hyperparam5);

hyperparam6=['IG scale on factor variance (b0):               ' num2str(b0)];
fprintf('%s\n',hyperparam6);
fprintf(fid,'%s\n',hyperparam6);

hyperparam7=['AR coefficient on factors (rho):                ' num2str(rho)];
fprintf('%s\n',hyperparam7);
fprintf(fid,'%s\n',hyperparam7);

hyperparam8=['variance of Metropolis draw (psi):              ' num2str(psi)];
fprintf('%s\n',hyperparam8);
fprintf(fid,'%s\n',hyperparam8);

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% Metropolis Hastings summary

MHinfo1=['The acceptance rate of the Metropolis-Hastings step during the Gibbs sampler was ' num2str(acceptrate,'%.2f') '%.'];
fprintf('%s\n',MHinfo1);
fprintf(fid,'%s\n',MHinfo1);

MHinfo2='A good acceptance rate is typically comprised between 20% and 30%.';
fprintf('%s\n',MHinfo2);
fprintf(fid,'%s\n',MHinfo2);

if acceptrate<=20

MHinfo3='Your acceptance rate is therefore low, which implies that some values may be repeated';
fprintf('%s\n',MHinfo3);
fprintf(fid,'%s\n',MHinfo3);
MHinfo4='in the estimation of the posterior distribution for Z.';
fprintf('%s\n',MHinfo4);
fprintf(fid,'%s\n',MHinfo4);
MHinfo5='Your may consider decreasing the value of psi in order to remedy to this situation.';
fprintf('%s\n',MHinfo5);
fprintf(fid,'%s\n',MHinfo5);

elseif acceptrate>=30

MHinfo3='Your acceptance rate is therefore high, which implies that only a small portion of the';
fprintf('%s\n',MHinfo3);
fprintf(fid,'%s\n',MHinfo3);
MHinfo4='support of the posterior distribution of Z may have been covered by the algorithm.';
fprintf('%s\n',MHinfo4);
fprintf(fid,'%s\n',MHinfo4);
MHinfo5='Your may consider increasing the value of psi in order to remedy to this situation.';
fprintf('%s\n',MHinfo5);
fprintf(fid,'%s\n',MHinfo5);

elseif (acceptrate>20 && acceptrate<30)

MHinfo3='This is satisfied in this case. Hence, the value of psi that has been selected seems';
fprintf('%s\n',MHinfo3);
fprintf(fid,'%s\n',MHinfo3);
MHinfo4='suitable for an efficient estimation of the posterior distribution of Z.';
fprintf('%s\n',MHinfo4);
fprintf(fid,'%s\n',MHinfo4);

end

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% display factor estimates

factorinfo=['Structural factors (final sample period):'];
fprintf('%s\n',factorinfo);
fprintf(fid,'%s\n',factorinfo);

fprintf('%s\n','');
fprintf(fid,'%s\n','');

factorheader=fprintf('%35s %15s %15s %15s %15s\n','','Median','St.dev','Low.bound','Upp.bound');
factorheader=fprintf(fid,'%35s %15s %15s %15s %15s\n','','Median','St.dev','Low.bound','Upp.bound');

% common component

fprintf('%s\n','theta1 (common component)');
fprintf(fid,'%s\n','theta1 (common component)');
values=[theta_median(1,1,end) theta_std(1,1,end) theta_lbound(1,1,end) theta_ubound(1,1,end)];
fprintf('%-35s %15.3f %15.3f %15.3f %15.3f\n','common component',values);
fprintf(fid,'%-35s %15.3f %15.3f %15.3f %15.3f\n','common component',values);
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% unit component

fprintf('%s\n','theta2 (unit-specific component)');
fprintf(fid,'%s\n','theta2 (unit component)');
for ii=1:d2
values=[theta_median(d1+ii,1,end) theta_std(d1+ii,1,end) theta_lbound(d1+ii,1,end) theta_ubound(d1+ii,1,end)];
fprintf('%-35s %15.3f %15.3f %15.3f %15.3f\n',['unit ' int2str(ii) ' component'],values);
fprintf(fid,'%-35s %15.3f %15.3f %15.3f %15.3f\n',['unit ' int2str(ii) ' component'],values);
end
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% variable component

fprintf('%s\n','theta3 (variable-specific component)');
fprintf(fid,'%s\n','theta3 (endogenous variable component)');
for ii=1:d3
values=[theta_median(d1+d2+ii,1,end) theta_std(d1+d2+ii,1,end) theta_lbound(d1+d2+ii,1,end) theta_ubound(d1+d2+ii,1,end)];
fprintf('%-35s %15.3f %15.3f %15.3f %15.3f\n',['variable ' int2str(ii) ' component'],values);
fprintf(fid,'%-35s %15.3f %15.3f %15.3f %15.3f\n',['variable ' int2str(ii) ' component'],values);
end
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% lag component (if applicable)

if d4~=0
fprintf('%s\n','theta4 (lag-specific component)');
fprintf(fid,'%s\n','theta4 (lag component)');
for ii=1:d4
values=[theta_median(d1+d2+d3+ii,1,end) theta_std(d1+d2+d3+ii,1,end) theta_lbound(d1+d2+d3+ii,1,end) theta_ubound(d1+d2+d3+ii,1,end)];
fprintf('%-35s %15.3f %15.3f %15.3f %15.3f\n',['lag ' int2str(ii) ' component'],values);
fprintf(fid,'%-35s %15.3f %15.3f %15.3f %15.3f\n',['lag ' int2str(ii) ' component'],values);
end
fprintf('%s\n','');
fprintf(fid,'%s\n','');
end

% exogenous component (if applicable)

if d5~=0
fprintf('%s\n','theta5 (exogenous variable component)');
fprintf(fid,'%s\n','theta5 (exogenous component)');
% initiate equation count
eqcount=0;
% initiate exogenous count
exocount=0;
for ii=1:d5
   if exocount==m
   exocount=0;
   end
   if exocount==0
   eqcount=eqcount+1;
   end
exocount=exocount+1;
values=[theta_median(d1+d2+d3+d4+ii,1,end) theta_std(d1+d2+d3+d4+ii,1,end) theta_lbound(d1+d2+d3+d4+ii,1,end) theta_ubound(d1+d2+d3+d4+ii,1,end)];
fprintf('%-35s %15.3f %15.3f %15.3f %15.3f\n',['equation ' int2str(eqcount) ', exogenous ' int2str(exocount) ' component'],values);
fprintf(fid,'%-35s %15.3f %15.3f %15.3f %15.3f\n',['equation ' int2str(eqcount) ', exogenous ' int2str(exocount) ' component'],values);
end
fprintf('%s\n','');
fprintf(fid,'%s\n','');
end

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% display VAR stability results
eigmodulus=reshape(eigmodulus,p,N*n);
stabilityinfo1=['Roots (modulus) of the characteristic polynomial for the final sample period:'];
fprintf('%s\n',stabilityinfo1);
fprintf(fid,'%s\n',stabilityinfo1);
for jj=1:p
temp=num2str(eigmodulus(jj,1),'%.3f');
   for kk=2:N*n
   temp=[temp,'  ',num2str(eigmodulus(jj,kk),'%.3f')];
   end
fprintf('%s\n',temp);
fprintf(fid,'%s\n',temp);
end
if stationary==1;
stabilityinfo2=['No root lies outside the unit circle.'];
stabilityinfo3=['The estimated VAR model satisfies the stability condition'];
fprintf('%s\n',stabilityinfo2);
fprintf(fid,'%s\n',stabilityinfo2);
fprintf('%s\n',stabilityinfo3);
fprintf(fid,'%s\n',stabilityinfo3);
else
stabilityinfo2=['Warning: at leat one root lies on or outside the unit circle.'];
stabilityinfo3=['The estimated VAR model will not be stable'];
end

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% display posterior for sigma
% reshape sigma
sigma_median=reshape(sigma_median(:,:,end),N*n,N*n);
% start displaying
sigmainfo=['sigma (residual covariance matrix): posterior estimates for the final sample period'];
fprintf('%s\n',sigmainfo);
fprintf(fid,'%s\n',sigmainfo);
% calculate the (integer) length of the largest number in sigma, for formatting purpose
width=length(sprintf('%d',floor(max(abs(bear.vec(sigma_median))))));
% add a separator, a potential minus sign, and three digits (total=5) to obtain the total space for each entry in the matrix
width=width+5;
for ii=1:N*n
temp=[];
   for jj=1:N*n
   % convert matrix entry into string
   number=num2str(sigma_median(ii,jj),'% .3f');
      % pad potential missing blanks
      while numel(number)<width
      number=[' ' number];
      end
   number=[number '  '];
   temp=[temp number];
   end
fprintf('%s\n',temp);
fprintf(fid,'%s\n',temp);
end

fprintf('%s\n','');
fprintf(fid,'%s\n','');

% then display the results for D and gamma, if a structural decomposition was selected

if IRF==1 && IRFt~=1
svarinfo1=['D (structural decomposition matrix): posterior estimates'];
fprintf('%s\n',svarinfo1);
fprintf(fid,'%s\n',svarinfo1);

% recover D
D=reshape(D_estimates(:,:,end),N*n,N*n);
% calculate the (integer) length of the largest number in D, for formatting purpose
width=length(sprintf('%d',floor(max(abs(bear.vec(D))))));
% add a separator, a potential minus sign and three digits (total=5) to obtain the total space for each entry in the matrix
width=width+5;
for ii=1:N*n
temp=[];
   for jj=1:N*n
   % convert matrix entry into string
   number=num2str(D(ii,jj),'% .3f');
      % pad potential missing blanks
      while numel(number)<width
      number=[' ' number];
      end
   number=[number '  '];
   temp=[temp number];
   end
fprintf('%s\n',temp);
fprintf(fid,'%s\n',temp);
end

fprintf('%s\n','');
fprintf(fid,'%s\n','');

svarinfo2=['gamma (structural disturbances covariance matrix): posterior estimates'];
fprintf('%s\n',svarinfo2);
fprintf(fid,'%s\n',svarinfo2);

% recover gamma
gamma=reshape(gamma_estimates(:,:,end),N*n,N*n);
% calculate the (integer) length of the largest number in D, for formatting purpose
width=length(sprintf('%d',floor(max(abs(bear.vec(D))))));
% add a separator, a potential minus sign and three digits (total=5) to obtain the total space for each entry in the matrix
width=width+5;
for ii=1:N*n
temp=[];
   for jj=1:N*n
   % convert matrix entry into string
   number=num2str(gamma(ii,jj),'% .3f');
      % pad potential missing blanks
      while numel(number)<width
      number=[' ' number];
      end
   number=[number '  '];
   temp=[temp number];
   end
fprintf('%s\n',temp);
fprintf(fid,'%s\n',temp);
end

end

fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');
fprintf('%s\n','');
fprintf(fid,'%s\n','');

% finally display in-sample and forecast evaluation measures
% if forecast evaluation is activated and possible, display the results
if Feval==1 && Fcomp==1
bear.panel6fprint(Units,N,n,endo,rss,r2,r2bar,RMSE,MAE,MAPE,Ustat,CRPS_estimates,stringdates3,Fstartdate,Fcenddate,Fcperiods,fid);

% if forecast evaluation is activated but not possible, return a message to signal it
elseif Feval==1 && Fcomp==0

finfo1=['Forecast evaluation cannot be conducted.'];
fprintf('%s\n',finfo1);
fprintf(fid,'%s\n',finfo1);
finfo2=['Forecasts start in ' Fstartdate ', while observable data is available only until ' names{end,1} '.'];
fprintf('%s\n',finfo2);
fprintf(fid,'%s\n',finfo2);
finfo3=['To obtain forecast evaluation, the forecast start date must be anterior to the end of the data set.'];
fprintf('%s\n',finfo3);
fprintf(fid,'%s\n',finfo3);

% if forecast evaluation is not activated altogether, do not do anything

end


function gen_cropped_MPII_validate_images()
% Author: Guanghan Ning, Feb 2017
clear all;
clc;

target_dist = 1.45;
boxsize = 368;

flag_showScaledImg = 1;
% Get [input images paths] and [output images path]
mpii_img_folder_path = '../dataset/MPI/images/';
img_output_folder = 'dataset_mpii/images_validate_cropped/qualitative/';
if exist(img_output_folder) ~= 7  % if not a folder path
    mkdir(img_output_folder);
end

% Load annotations
load('eval_MPII/mpii_Tompson_validation', 'annolist');
load('eval_MPII/mpii_Tompson_validation', 'keypointsAll');
load('eval_MPII/mpii_Tompson_validation', 'RELEASE_img_index');
load('eval_MPII/mpii_Tompson_validation', 'RELEASE_person_index');

annolist_test = annolist;
num_test_imgs = size(annolist_test, 2);

load('eval_MPII/mpii_human_pose_v1_u12_1','RELEASE');
annolist_all = RELEASE.annolist;

%% Start from here if everything already read from mat file.
for img_id = 1:num_test_imgs

    img_index = RELEASE_img_index(img_id);

    % (1) Deal with rect ids

        % Get rect id. Note the difference between rect_ct and rect_id
        rect_id = RELEASE_person_index(img_id);

        % Find scale and mid-points in order to convert prediction
        x_mid = annolist_test(img_id).annorect.objpos.x;
        y_mid = annolist_test(img_id).annorect.objpos.y;
        objpos_org = [x_mid, y_mid];
        scale_provided = annolist_test(img_id).annorect.scale;

        % (2) Deal with images
        img_name = annolist_all(img_index).image.name;
        img_path = strcat(mpii_img_folder_path, img_name);
        if ~exist(img_path, 'file')
            continue
        end

        img = imread(img_path);

        scale_in_cpp = target_dist/scale_provided;
        center_s = objpos_org * scale_in_cpp;
        fprintf('scale: %f\n', scale_in_cpp);

        img = imresize(img, scale_in_cpp);
        disp(size(img));
        [img, pad] = padAround(img, boxsize, center_s);
        disp(size(img));

        [pathstr, name, ext] = fileparts(img_path);
        img_output_path = strcat(img_output_folder, name, '_', num2str(rect_id), ext);
        imwrite(img, img_output_path);

        output_scale(img_id) = scale_in_cpp;
end
save('scale_in_cpp_MPII_validate.mat', 'output_scale');

function [img_padded, pad] = padAround(img, boxsize, center)
    center = round(center);
    h = size(img, 1);
    w = size(img, 2);
    pad(1) = boxsize/2 - center(2); % up
    pad(3) = boxsize/2 - (h-center(2)); % down
    pad(2) = boxsize/2 - center(1); % left
    pad(4) = boxsize/2 - (w-center(1)); % right

    pad_pixel_value = 128;

    pad_up = repmat(img(1,:,:)*0, [pad(1) 1 1]) + pad_pixel_value;
    img_padded = [pad_up; img];
    pad_left = repmat(img_padded(:,1,:)*0, [1 pad(2) 1]) + pad_pixel_value;
    img_padded = [pad_left img_padded];
    pad_down = repmat(img_padded(end,:,:)*0, [pad(3) 1 1]) + pad_pixel_value;
    img_padded = [img_padded; pad_down];
    pad_right = repmat(img_padded(:,end,:)*0, [1 pad(4) 1]) + pad_pixel_value;
    img_padded = [img_padded pad_right];

    center = center + [max(0,pad(2)) max(0,pad(1))];
    img_padded = img_padded(center(2)-(boxsize/2-1):center(2)+boxsize/2, center(1)-(boxsize/2-1):center(1)+boxsize/2, :); %cropping if needed

function [x,y] = findMaximum(map)
    [~,i] = max(map(:));
    [x,y] = ind2sub(size(map), i);


function [sol,info] = solvebilevel(varargin)
%SOLVEBILEVEL Simple global bilevel solver
%
%   min        Objective(Pouter)(x,y)
%   subject to Constraints(Pouter)(x,y)>0
%              y = arg min Objective(Pinner)(x,y)
%              subject to Constraints(Pinner)(x,y)>0
%
%   [DIAGNOSTIC,INFO] = SOLVEBILEVEL(Pouter, Pinner, y, options)
%
%   diagnostic : Struct with standard YALMIP diagnostics
%   info       : Bilevel solver specific information
%
%   Input
%      Pouter   : Outer problem
%      Pinner   : Inner problem
%      y        : Inner variables
%      options  : solver options from SDPSETTINGS.
%
%   The behaviour of the bilevel solver can be controlled
%   using the field 'bilevel' in SDPSETTINGS
%
%      bilevel.outersolver : Solver for outer problems with inner KKT removed
%      bilevel.innersolver : Solver for inner problem
%      bilevel.rootcut     : Number of cuts (based on complementary
%                            constraints) added in root (experimental)
%      bilevel.relgaptol   : Termination tolerance
%      bilevel.compslacktol: Tolerance for accepting complementary slackness
%      bilevel.feastol     : Tolerance for feasibility in outer problem
%
%
%   See also SDPVAR, SDPSETTINGS, SOLVESDP

if isa(varargin{2},'optimizer')
    Pout = varargin{1};
    s = struct(varargin{2});
    if nargin < 3
        options = sdpsettings;
    else
        options = varargin{3};
    end
    [sol,info] = solvebilevel(Pout.Constraints,Pout.Objective,s.F,s.h,s.output.expression,options)
else
    Pout = varargin{1};
    Pinn = varargin{2};
    y = varargin{3};

    if nargin < 4
        options = sdpsettings;
    else
        options = varargin{4};
    end

    [sol,info] = solvebilevel(Pout.Constraints,Pout.Objective,Pinn.Constraints,Pinn.Objective,y,options)
end


function e = sarimax_errors(parameters,p,q,constant,seasonal,y,x,sigma)
% PURPOSE:
%   Likelihood function for armaxfilter
%
% USAGE:
%   [LLF, LIKELIHOODS, ERRORS] = armaxfilter_likelihood(PARAMETERS,P,Q,CONSTANT,Y,X,M)
%   [LLF, LIKELIHOODS, ERRORS] = armaxfilter_likelihood(PARAMETERS,P,Q,CONSTANT,Y,X,M)
%
% INPUTS:
%   PARAMETERS  - A vector of GARCH process aprams of the form [constant, arch, garch]
%   P           - Vector containing lag indices of the AR component
%   Q           - Vector containing lag indices of the MA component
%   CONSTANT    - Value indicating whether the model contains a constant (1) or not (0)
%   Y           -
%   X           -
%   M           - Index to first element to use in the recursive residual calculation
%   SIGMA       - T by 1 vector
%
% OUTPUTS:
%   LLF         - Minus 1 times the log likelihood
%   LIKELIHOODS - Time series of likelihoods
%   ERRORS      - Time series of model errors
%
% COMMENTS:
%
% See also armaerrors

% Author: Kevin Sheppard
% kevin.sheppard@economics.ox.ac.uk
% Revision: 3    Date: 4/1/2004

m = size(x,2);
[armaParameters, p, q] = sarma2arma(parameters(m+1:length(parameters)), p, q, seasonal);
parameters = [parameters(1:m);armaParameters];
e = armaxerrors(parameters,p,q,constant,y,x,m,sigma);


function this = compute_stat_images(this)
% computes statistical images for time series QC, such as
%   mean, standard deviation (sd), signal-to-noise ratio (snr)
%   coefficient of variation (1/snr) images
%   difference images between last/first (drift) and odd/even (image noise)
%   volumes
%
%   Y = MrSeries()
%   Y.compute_stat_images(inputs)
%
% This is a method of class MrSeries.
%
% IN
%   parameters.compute_stat_images
%
% OUT
%   this.mean
%   this.snr
%   this.sd
%   this.coeff_var
%   this.diffLastFirst
%   this.diffOddEven
%
% EXAMPLE
%   compute_stat_images
%
%   See also MrSeries MrImage MrImage.compute_stat_image

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

this.init_processing_step('compute_stat_images');
applicationDimension = this.parameters.compute_stat_images.applicationDimension;

% compute statistical images via MrImage method and update save-parameters
[~, nameStatImageArray] = this.get_all_image_objects('stats');

for iImage = 1:numel(nameStatImageArray)
    img = nameStatImageArray{iImage};
    parameters = this.(img).parameters;
    this.(img) = this.data.compute_stat_image(img, ...
        'applicationDimension', applicationDimension);
    this.(img).name = sprintf('%s (%s)', img, this.name);
    this.(img).parameters.save = parameters.save;
end

this.finish_processing_step('compute_stat_images', this.(img));


function [pts] = helen_annotation_load( fpath )

%fpath = ['/home/tranngoctrung/Workspace/These/3dpose/data/input/HELEN/points/' '232194_1.txt'];

pts = [];

if exist(fpath,'file') ~= 0

fp = fopen(fpath,'r');

npts = 194; %predefined
pts  = zeros(npts,2);

count = 0;

while ~feof(fp)

    count = count + 1;

    line = fgetl(fp);

    if count > 1
        terms = strsplit(line,',');
        pts(count-1,1) = str2num(terms{1});
        pts(count-1,2) = str2num(terms{2});
    end

end

end

fclose(fp);

end


function err = alignmentError(pcCalib, pcGroundTruth, param, camW, camH, verbose, figName)
%% Calculate alignment error between calibration and Intel RealSense F200 captured point cloud.
% Calculate and compare the 3D alignment errors between reconstructed
% point cloud and Intel RealSense F200 captured point cloud. Four
% calibration methods are compared.

%% License
% ACADEMIC OR NON-PROFIT ORGANIZATION NONCOMMERCIAL RESEARCH USE ONLY
% Copyright (c) 2018 Bingyao Huang
% All rights reserved.

% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:

% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.

% If you publish results obtained using this software, please cite our paper.

% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
% SOFTWARE.

%%
if(nargin < 7)
    figName = '';
end

%%
% convert point cloud to XYZ map
% imPC = zeros(camH, camW, 3);
% imPC(:,:,1) = (reshape(pcGroundTruth.Location(:,1), camW, camH))';
% imPC(:,:,2) = (reshape(pcGroundTruth.Location(:,2), camW, camH))';
% imPC(:,:,3) = (reshape(pcGroundTruth.Location(:,3), camW, camH))';
% imPC = double(imPC);

% pts3dGT = double(pcGroundTruth.Location);
% pts3dGT = pts3dGT(pts3dGT(:,3)>0,:);
% pts2dGT = cv.projectPoints(pts3dGT, [0,0,0], [0,0,0], param.camK, 'DistCoeffs', param.camKc);
% imD = zeros(camH, camW);
% pts2dGT = round(pts2dGT);
% inlierIdx = pts2dGT(:,1)<=camW & pts2dGT(:,2)<=camH & pts2dGT(:,1)>0 & pts2dGT(:,2)>0;
% pts2dGT = pts2dGT(inlierIdx,:);
% pts3dGT = pts3dGT(inlierIdx,:);
% imD(sub2ind([camH, camW], pts2dGT(:,2), pts2dGT(:,1))) = pts3dGT(:,3);

pts3d = double(pcCalib.Location);
pts3d = pts3d(pts3d(:,3)>0,:);
pts2d = cv.projectPoints(pts3d, [0,0,0], [0,0,0], param.camK, 'DistCoeffs', param.camKc);
imD = zeros(camH, camW);
pts2d = round(pts2d);
inlierIdx = pts2d(:,1)<=camW & pts2d(:,2)<=camH & pts2d(:,1)>0 & pts2d(:,2)>0;
pts2d = pts2d(inlierIdx,:);
pts3d = pts3d(inlierIdx,:);
imD(sub2ind([camH, camW], pts2d(:,2), pts2d(:,1))) = pts3d(:,3);

% find depth image mask
imMask = false(size(imD));
imMask(imD > 0) = 1;
se = strel('disk', 5);
% imMask = imclose(imopen(imMask,  se), se);
imMask = imclose(imMask, se);
imMask = imfill(imMask, 'holes');
imMask = bwareafilt(imMask, 1);
imMask = imgaussfilt(double(imMask), 7) > 0.2; % smooth edges
% fs(imMask);

%% align reconstructed point cloud with ground truth point cloud using icp

% downsample and denoise to save time and memory
% gridSize = 0.1;
% fixed = pcdownsample(pcdenoise(pcGroundTruth, 'Threshold',5), 'gridAverage', gridSize);
% % moving = pcdenoise(pcdownsample(pointCloud(pts3dInterp), 'gridAverage', gridSize));
% moving = pcdownsample(pcdenoise(pcCalib,'Threshold',5), 'gridAverage', gridSize);
%
% % register pcCalib to fixed pcGroundTruth
% [tform, ~, ~] = pcregistericp(moving, fixed,'Extrapolate', true, 'MaxIterations', 50);
% pcCalibAligned = pctransform(pcCalib, tform);
% figure;pcshowpair(fixed, pcCalibAligned)

%% interpolate point cloud
rp = regionprops(imMask, 'boundingbox');
desity = 1;
npX = rp.BoundingBox(3)*desity;
npY = rp.BoundingBox(4)*desity;

% xRange contains lower and higher bounds
xRange = double(pcCalib.XLimits);
xDiff = xRange(1) - xRange(2);
xStep = -xDiff / npX;

yRange = double(pcCalib.YLimits);
yDiff = yRange(1) - yRange(2);
yStep = -yDiff/npY;

% use griddata to interpolate a mesh from given point cloud
% pts3d = pcCalibAligned.Location;
[xq,yq] = meshgrid(xRange(1):xStep:xRange(2), yRange(1):yStep:yRange(2));
zq = griddata(pts3d(:,1),pts3d(:,2),pts3d(:,3), xq, yq,'cubic');

% pcInterp is the interpolated denser point cloud
pcInterp = pointCloud([xq(:), yq(:), zq(:)]);

% finer registration
% moving = pcdownsample(pcdenoise(pcInterpAligned,'Threshold',5), 'gridAverage', gridSize);
% [tform, ~, ~] = pcregrigid(moving, fixed,'Extrapolate', true);
% pcInterpAligned = pctransform(pcInterpAligned, tform);

[~, ~, ~, pcInlierIdx] = Reconstruct.filterPointCloud(pcInterp, imMask, param, camW, camH);
pcOutlierIdx = setdiff(1:size(xq,1)*size(xq,2), pcInlierIdx);

if(verbose)
    figure('Name', figName);
    h = surf(xq, yq, zq, 'FaceColor', 'interp', 'FaceLighting', 'gouraud'); % square mesh
%     h = trisurf(delaunay(xq,yq),xq, yq, zq, 'FaceColor', 'interp', 'FaceLighting', 'gouraud'); % triangular mesh

    % remove interpolated meth that are out of ground truth range
    h.XData(pcOutlierIdx) = nan;
    h.YData(pcOutlierIdx) = nan;
    h.ZData(pcOutlierIdx) = nan;
    h.CData(pcOutlierIdx) = nan;

    h.EdgeColor = 'none';
%     h.EdgeColor = [0.3,0.3,0.3];
    h.LineStyle = ':';
    colormap parula

    % title
    title(figName)
    caxis([0 50])
%     colorbar

    % remove ticks
    set(gca,'xtick',[])
    set(gca,'xticklabel',[])
    set(gca,'ytick',[])
    set(gca,'yticklabel',[])
    set(gca,'ztick',[])
    set(gca,'zticklabel',[])

    % font
    set(gca, 'FontSize', 20);
    daspect([1 1 1]);
    axis vis3d tight

    rotate3d on
    box on
    set(gca, 'visible', 'off'); % ge trid of ugly box edges
end

light('Position',[0 1 -1]);
material dull % metal, shiny, default

%% calculte 3D alignment error using knn search
[~, err] = knnsearch(pcGroundTruth.Location, pcInterp.Location);

% visualize errors as pseudocolor
if(verbose)
    errOutlierIdx = isnan(err);
    errInlierIdx = ~errOutlierIdx;
    h.ZData(errOutlierIdx) = nan;
    h.CData(errInlierIdx) = err(errInlierIdx); % use err as color
%      h.CData(errInlierIdx) = abs(err(errInlierIdx)); % use abs err as color
end

% remove nan values
err = err(~isnan(err));
end


%  plots the curvature of an estimated parameter at the model
%
%  ::
%
%    [h,legend_]=curvature(xname,db)
%
%  Args:
%
%     - **xname** [char]: name of the parameter to plot
%     - **db** [struct]: structure containing the various parameters. Each
%       parameter field is itself a structure with the following
%
%       - **tex_name** [char]: name of the parameter as it should appear in the
%         title of the plot
%       - **mode** [scalar]: value of the parameter at the mode
%       - **log_post_mode** [scalar]: value of the log posterior mode
%       - **log_lik_mode** [scalar]: value of the log likelihood at the mode
%       - **x** [vector]: x-axis values
%       - **log_post** [vector]: value of the log-posterior for each value of x
%       - **log_lik** [vector]: value of the log-likelihood for each value of x
%
%  Returns:
%     :
%
%     - **h** [handle]: handle for the plot
%     - **legend_** [cellstr]: names of the lines in the plot
%     - **tex_name** [char]: name of the parameter
%
%


function [params, names] = linearExtractParam(model,dim);

% LINEAREXTRACTPARAM Extract weights from a linear model.
%
% MODIFICATIONS : Carl Henrik Ek, 2009
%
% MLTOOLS

if(nargin<2)
  params = [model.W(:)' model.b];
else
  params = model.W(:,dim);
  params = [params(:)' model.b(dim)];
end

if nargout > 1
  counter = 0;
  for j = 1:size(model.W, 2)
    for i = 1:size(model.W, 1)
      counter = counter + 1;
      names{counter} = ['Weight ' num2str(i) '-' num2str(j)];
    end
  end
    for j = 1:size(model.b, 2)
    counter = counter + 1;
    names{counter} = ['Bias ' num2str(j)];
  end
end


function qout = ch_qconj(qin)
qout = [qin(1); -qin(2:4)];


function [cmap_i]=resampleColormap(cmap,n)

% function [cmap_i]=resampleColormap(cmap,n)
% ------------------------------------------------------------------------
%
% This function resamples the input colormap cmap using n steps. Resampling
% is based on linear interpolation.
%
% Kevin Mattheus Moerman
% gibbon.toolbox@gmail.com
%
% Change log:
% 2014/09/25
% 2018/06/13 Added handling of single color colormap
%------------------------------------------------------------------------

%%

if n~=size(cmap,1) %If resampling is required
    if size(cmap,1)==1
        cmap_i=cmap(ones(n,1),:);
    else
        ind=(1:1:size(cmap,1))';
        ind_i=linspace(1,size(cmap,1),n)';
        cmap_i=zeros(n,size(cmap,2));

        %Interpolate color data
        for q=1:1:size(cmap,2)
            cmap_i(:,q)=interp1(ind,cmap(:,q),ind_i,'linear');
        end
    end
else
    cmap_i=cmap;
end

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% 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/>.


function plotAxis = plotBackground(target,param)

hold on;

%%% Figure out the axis for the figure:
pixelDim = param.diagnostics.gifPixelDim;
axisRatio = pixelDim(2)/pixelDim(1);
xBnd = [-0.2*target.x, 1.2*target.x];
yBnd = xBnd*axisRatio;
plotAxis = [xBnd,yBnd];

%%% Set the color for the background and size of figure
set(gca,'Color',0.7*[1 1 1]);  %Grey
position = get(gcf,'Position');
position(3:4) = pixelDim;
set(gcf,'Position',position);

%%% Plot the ground
xGround = [-0.2*target.x, 1.2*target.x];
yGround = [0, 0];
brown = [0.5, 0.2, 0.1];  %Color for ground
plot(xGround, yGround,'color',brown,'LineWidth',6);

%%% Plot the tree, start position, and target position
drawTree(0.6*target.x, 0, 1);  %Plot a tree for scale
plot(0,0,'k.','MarkerSize',35);   %Start
plot(target.x,target.y,'ko','LineWidth',4,'MarkerSize',14)   %Finish

%%% Axis Stuff
xlabel('Horizontal Position')
ylabel('Vertical Position')
axis equal; axis(plotAxis); drawnow; hold off;

end


function [bg, cga, cgb, tg] = computeDepthCues(I, colorParam)
	[mPb_nmax, mPb_nmax_rsz, bg1, bg2, bg3, cga1, cga2, cga3, cgb1, cgb2, cgb3, tg1, tg2, tg3, textons] = multiscalePb(im2double(I));

	bg = cat(4, bg1, bg2, bg3);
	tg = cat(4, tg1, tg2, tg3);
	cgb = cat(4, cgb1, cgb2, cgb3);
	cga = cat(4, cga1, cga2, cga3);
end


function r8vec_bracket3_test ( )

%*****************************************************************************80
%
%% R8VEC_BRACKET3_TEST tests R8VEC_BRACKET3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 September 2014
%
%  Author:
%
%    John Burkardt
%
  n = 10;
  ntest = 6;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8VEC_BRACKET3_TEST\n' );
  fprintf ( 1, '  R8VEC_BRACKET3 finds a pair of entries in a\n' );
  fprintf ( 1, '  sorted real array which bracket a value.\n' );

  xtest(1:6) = [ -10.0, 1.0, 4.5, 5.0, 10.0, 12.0 ];

  x = r8vec_indicator1 ( n );
  x(6) = x(5);

  r8vec_print ( n, x, '  Sorted array:' );

  left = floor ( ( n + 1 ) / 2 );

  for itest = 1 : ntest

    xval = xtest(itest);

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Search for XVAL = %f\n', xval );

    fprintf ( 1, '  Starting guess for interval is = %d\n', left );

    left = r8vec_bracket3 ( n, x, xval, left );

    fprintf ( 1, '  Nearest interval:' );
    fprintf ( 1, '    X[%d]= %f\n', left, x(left) );
    fprintf ( 1, '    X[%d]= %f\n', left+1, x(left+1) );

  end

  return
end


 function pot = potential_fun(ptype, delta, param, varargin)
%function pot = potential_fun(ptype, delta, param, varargin)
%|
%| Define roughness penalty potential functions (as strum).
%|
%| The penalty will have the form
%|	R(x) = sum_k w_k * potential_k([Cx]_k, delta_k)
%| where w_k is provided elsewhere, not here!
%|
%| in
%|	ptype		quad broken huber hyper2 hyper3 cauchy qgg2 genhub
%|			lange1 lange3 (fair) geman&mcclure gf1 li98cfs
%|			Recommended: 'hyper3'
%|			To list all possible choices, use:
%|			potential_fun('list') for "smooth" options
%|			potential_fun('list1') for "non-smooth" options
%|	delta		scalar, or image-sized array;
%|			"cutoff" parameter for edge-preserving regularization
%|	param		optional additional parameter(s) for some choices:
%|				'gf1' (generalized Fair) : [a b]
%|				'qgg2' : q
%|				'genhub' & 'stevenson94dpr' : [p q]
%|				'table1' : [dz, dpot([1:K] * dz)]
%|
%| option
%|	'dummy'		include extra dummy argument for backward compatibility
%|			e.g., pot.potk([], C*x). default: 0
%|
%| out
%|	pot		strum object, with data: delta and param
%|	methods:
%|		pot.potk(C*x)	potential function value
%|		pot.wpot(C*x)	potential 'weights' (aka half-quad. curvatures)
%|		pot.dpot(C*x)	potential derivative
%|		pot.shrink(b, reg)	proximal (shrinkage) operation:
%|					argmin_z 1/2 |z - b|^2 + reg * pot(z)
%|		pot.plot()	plot all of the above functions
%|
%| trick: for ptype 'gf1-fit', the param argument should be:
%|	{'name of potential to fit', points, param}
%| and this function returns the [a b] parameters needed for a subsequent
%| call with ptype 'gf1'
%|
%| Copyright 2004-5-18, Jeff Fessler, University of Michigan

if nargin < 1, ir_usage, end
if streq(ptype, 'test') ir_potential_fun_test, return, end
if streq(ptype, 'test_lpp') ir_potential_fun_test_lpp, return, end

if streq(ptype, 'list') % return list of all "smooth" choices
	pot = {'quad', 'huber', 'huber2', ...
	'hyper2', 'hyper3', 'cauchy', ...
	'qgg2', 'genhub', 'lange1', 'lange3', 'geman&mcclure', 'gf1', ...
	'table0', 'table1', 'li98cfs'};
%	'stevenson94dpr' omit this one; use 'genhub' instead
return
end

if streq(ptype, 'list1') % return list of 'l1' type choices (mostly non-smooth)
	pot = {'l0', 'l1', 'lpp', 'tav', 'broken', 'fair-l1'};
return
end

if ~isvar('delta'), delta = []; end
if ~isvar('param'), param = []; end

arg.dummy = false;
arg.scale = 1;
arg = vararg_pair(arg, varargin);

if streq(ptype, 'gf1-fit') % trick: just return parameters for this case
	pot = ir_potential_fun_gf1_fit(param{:});
return
end

[pot.type, pot.delta, pot.param, potk, wpot, dpot, shrink] = ...
	ir_potential_fun_parse(ptype, delta(:), param(:));

if arg.scale ~= 1
	potk = @(pot, z) arg.scale * potk(pot, z);
	dpot = @(pot, z) arg.scale * dpot(pot, z);
	wpot = @(pot, z) arg.scale * wpot(pot, z);
end

if arg.dummy
	potk = @(pot, dum, z) potk(pot, z);
	dpot = @(pot, dum, z) dpot(pot, z);
	wpot = @(pot, dum, z) wpot(pot, z);
end

meth = {'potk', potk, 'wpot', wpot, 'dpot', dpot, 'shrink', shrink, ...
	'plot', @ir_potential_fun_plot};
pot = strum(pot, meth);

end % potential_fun()

% ir_potential_fun_gf1_fit()
% trick: gf1-fit means match gf1 to named potential at given points [0, s1, s2]
% where the given point values are s = z / delta, i.e., in "delta" units
% param: {'name of potential to fit', points, param}
function ab = ir_potential_fun_gf1_fit(ptype, sv, param)
sv = sv(:);
pot = potential_fun(ptype, 1, param); % trick: delta=1 here
pt = pot.wpot(sv);

% ab = [1 1; -pt']' \ ((pt-1) ./ sv);

s1 = sv(1);
s2 = sv(2);
w1 = pt(1);
w2 = pt(2);
ab(1) = (w2 * s2 * (1 - w1) - w1 * s1 * (1 - w2)) ...
		/ ((w1 - w2) * s1 * s2);
ab(2) = (s2 * (1 - w1) - s1 * (1 - w2)) ...
		/ ((w1 - w2) * s1 * s2);
end % ir_potential_fun_gf1_fit()

% ir_potential_fun_parse()
function [ptype, delta, param, potk, wpot, dpot, shrink] = ...
	ir_potential_fun_parse(ptype, delta, param)

dpot = [];
shrink = [];

% trick: huber2 is just a huber with delta / 2
% so that weighting function drops to 1/2 at delta, like hyper3 etc.
if streq(ptype, 'huber2')
	ptype = 'huber';
	delta = delta / 2;
end

% trick: hyper3 is just a hyperbola with delta scaled by sqrt(3)
% to approximately "match" the properties of 'cauchy' (old erroneous 'hyper')
if streq(ptype, 'hyper3')
	ptype = 'hyper2';
	delta = delta / sqrt(3);
end

if streq(ptype, 'gf1') && param(1) == 0
	if param(2) ~= 1
		fail 'only b=1 makes sense for gf1 with a=0'
	end
	ptype = 'lange3'; param = []; % trick: gf1 with a=0 and b=1 is lange3
end

switch ptype

% quadratic potential function
case 'quad'
	potk = @(pot, z) (abs(z).^2) / 2;
	wpot = @(pot, z) ones(size(z), class(z));
	dpot = @(pot, z) z;
	shrink = @(pot, b, reg) b ./ (1 + reg);

% broken parabola
case 'broken'
	potk = @(pot, z) min(z.^2, pot.delta.^2)/2;
	wpot = @(pot, z) ir_tonumeric(abs(z) < pot.delta, z);
	dpot = @(pot, z) z .* (abs(z) < pot.delta);
	shrink = @(pot, b, reg) ir_broken_shrink(b, reg, pot.delta);

% l0 (hard threshold)
case 'l0'
	potk = @(pot, z) ir_tonumeric(z ~= 0, z);
	wpot = @(pot, z) nan(size(z), class(z));
	dpot = @(pot, z) nan(size(z), class(z));
	shrink = @(pot, b, reg) b .* (abs(b) > sqrt(2*reg));

% absolute value (i.e., l1, for soft threshold)
case {'abs', 'l1'}
	potk = @(pot, z) abs(z);
	wpot = @(pot, z) 1 ./ abs(z); % invalid at z=0
	dpot = @(pot, z) sign(z);
	shrink = @(pot, b, reg) sign(b) .* max(abs(b) - reg, 0);

% l_p^p aka generalized gaussian (gg)
case 'lpp'
	potk = @(pot, z) abs(z).^param;
	dpot = @(pot, z) param * sign(z) .* abs(z).^(param-1); % invalid at z=0
	wpot = @(pot, z) param .* abs(z).^(param-2); % invalid at z=0
	switch param
	case 0
		potk = @(pot, z) ir_tonumeric(z ~= 0, z);
		dpot = @(pot, z) zeros(size(z), class(z)); % meaningless
		shrink = @(pot, b, reg) b .* (abs(b) > sqrt(2*reg));
	case 1
		potk = @(pot, z) abs(z);
		dpot = @(pot, z) sign(z); % invalid at t=0
		shrink = @(pot, b, reg) sign(b) .* max(abs(b) - reg, 0);
	case 0.5 % p=1/2
		shrink = @(pot, b, reg) ir_lpp_1_2_shrink(b, reg);
	case 4/3. % p=4/3
		shrink = @(pot, b, reg) ir_lpp_4_3_shrink(b, reg);
	case 1.5 % p=3/2
		shrink = @(pot, b, reg) sign(b) .* ...
			( sqrt((3/4*reg).^2 + abs(b)) - 3/4*reg ).^2;
		% from eqn. (4.5) in chaux:07:avf
	%	z + 9 * reg.^2 * sign(z) .* (1 - sqrt(1 + 16*abs(z)/(9*reg^2))) / 8;

	otherwise
		warn('no shrink for p=%g', param)
	end

% truncated absolute value
case 'tav'
	potk = @(pot, z) min(abs(z), pot.delta);
	wpot = @(pot, z) (1 ./ abs(z)) .* (abs(z) < pot.delta); % bad at t=0
	dpot = @(pot, z) sign(z) .* (abs(z) < pot.delta);
	shrink = @(pot, b, reg) ir_tav_shrink(b, reg, pot.delta);

% huber potential function
case 'huber'
	potk = @(pot, z) huber_pot(z, pot.delta);
	wpot = @(pot, z) huber_wpot(z, pot.delta);
	dpot = @(pot, z) huber_dpot(z, pot.delta);
	shrink = @(pot, b, reg) ir_huber_shrink(b, reg, pot.delta);

% cauchy penalty: d^2 / 2 * log(1 + (t/d)^2) (not convex!)
case 'cauchy'
	potk = @(pot, z) pot.delta.^2 / 2 .* log(1 + abs(z ./ pot.delta).^2);
	wpot = @(pot, z) 1 ./ (1 + abs(z ./ pot.delta).^2);
	dpot = @(pot, z) z ./ (1 + abs(z ./ pot.delta).^2);
	shrink = @(pot, b, reg) cauchy_shrink(b, reg, pot.delta);

% Geman&McClure penalty: d^2 / 2 * |z/d|^2 / (1 + |z/d|^2)
% Not convex!
case 'geman&mcclure'
	potk = @(pot, z) pot.delta.^2 / 2 .* abs(z/pot.delta).^2 ./ (1 + abs(z ./ pot.delta).^2);
	wpot = @(pot, z) 1 ./ (1 + abs(z ./ pot.delta).^2).^2;
	dpot = @(pot, z) z ./ (1 + abs(z ./ pot.delta).^2).^2;

% gf1: Generalized Fair 1st-order
% wpot(z) = (1 + a * |z/d|) / (1 + b * |z/d|)
case 'gf1'
	potk = @(pot, z) gf1_potk(z, pot.delta, pot.param(1), pot.param(2));
	wpot = @(pot, z) (1 + pot.param(1) .* abs(z ./ pot.delta)) ...
		./ (1 + pot.param(2) .* abs(z ./ pot.delta));
	shrink = @(pot, b, reg) ...
		ir_gf1_shrink(b, reg, pot.delta, pot.param(1), pot.param(2));

% hyperbola penalty: d^2 * [ sqrt(1 + (z/d)^2) - 1 ]
case 'hyper2'
	potk = @(pot, z) pot.delta.^2 .* (sqrt(1 + abs(z ./ pot.delta).^2) - 1);
	wpot = @(pot, z) 1 ./ sqrt(1 + abs(z ./ pot.delta).^2);
	dpot = @(pot, z) z ./ sqrt(1 + abs(z ./ pot.delta).^2);

case 'hyper'
	error 'use "cauchy" or "hyper3" not "hyper" now'

% Lange1 penalty
case 'lange1'
	potk = @(pot, z) abs(z).^2 / 2 ./ (1+abs(z./pot.delta));
	wpot = @(pot, z) (1 + abs(z ./ pot.delta) / 2) ./ (1 + abs(z ./ pot.delta)).^2;

% Lange3 penalty
case {'lange3', 'fair'}
	potk = @(pot, z) pot.delta.^2 .* (abs(z./pot.delta) - log(1+abs(z./pot.delta)));
	wpot = @(pot, z) 1 ./ (1 + abs(z ./ pot.delta));
	dpot = @(pot, z) z ./ (1 + abs(z ./ pot.delta));
	% caution: no built-in shink, use 'fair-l1' if you want shrink!

% Fair potential "rounded corner" approximation to l1
case 'fair-l1'
	potk = @(pot, z) abs(z) - pot.delta .* log(1+abs(z./pot.delta));
	wpot = @(pot, z) 1 ./ (pot.delta + abs(z));
	dpot = @(pot, z) z ./ (pot.delta + abs(z));
	shrink = @(pot, b, reg) fair_l1_shrink(b, reg, pot.delta);

% li98cfs
case 'li98cfs'
	% f = @(x) atan(x) / x - 0.5; fsolve(f, 2.3)
	delta = delta / 2.3311;
	potk = @(pot, z) ir_li98cfs_potk(z, pot.delta);
	wpot = @(pot, z) ir_li98cfs_wpot(z, pot.delta);

% qgg2: q-generalized gaussian for p=2, due to Thibault, Sauer, Bouman
% q = "param", same as lange1 when q=1
case 'qgg2'
	potk = @(pot, z) z.^2 / 2 ./ (1+abs(z./pot.delta).^(2-pot.param));
	wpot = @(pot, z) (1 + abs(z ./ pot.delta).^(2-pot.param) * pot.param ...
		 / 2) ./ (1 + abs(z ./ pot.delta).^(2-pot.param)).^2;

% genhub : generalized Huber (switch between two generalized gaussians)
% same as Huber when p=2 and q=1
% p is power near 0, q is asymptotic power
case 'genhub'
	potk = @(pot, z) ir_genhub_potk(z, pot.delta, pot.param(1), pot.param(2));
	wpot = @(pot, z) ir_genhub_wpot(z, pot.delta, pot.param(1), pot.param(2));

% from stevenson:94:dpr
% p = param(1), q = param(2), same as Huber when p=2 and q=1 ???
case 'stevenson94dpr'
	warn('Potential %s does not work well; use "genhub" instead', ptype)
	potk = @(pot, z) ir_stevenson94dpr_potk(z, pot.delta, pot.param(1), pot.param(2));
	wpot = @(pot, z) ones(size(z), class(z)); % bogus attempt at upper bound

% tabulate derivative of pot at z_k = dz * k for k=1,...,K
% param is samples of derivative dpot(z_k)
% dpot(0) = 0, and use sample-and-hold interpolation of dpot()
% except use linear interpolation over [0 dz]
case 'table0'
	if ~isnumeric(param) || numel(param) < 10
%	if ~iscell(param) || numel(param) ~= 2
%		fail 'for table0 param must be {dz, dpot([1:K]*dz}'
		fail 'for table0 param must be [dz, dpot([1:K]*dz)]'
	end
%	param = ir_table0_setup(param{1}, col(param{2}));
	param = ir_table0_setup(param(1), col(param(2:end)));
	potk = @(pot, z) ir_table0_potk(z, pot.param);
	wpot = @(pot, z) ir_table0_wpot(z, pot.param);
	shrink = @(pot, b, reg) ir_table0_shrink(b, reg, pot.param);

% tabulate derivative of pot at z_k = dz * k for k=1,...,K
% param is samples of derivative dpot(z_k)
% dpot(0 = 0, and use linear interpolation of dpot(t)
case 'table1'
	if ~isnumeric(param) || numel(param) < 10
%	if ~iscell(param) || numel(param) ~= 2
%		fail 'for table1 param must be {dz, dpot([1:K]*dz}'
		fail 'for table1 param must be [dz, dpot([1:K]*dz)]'
	end
%	param = ir_table1_setup(param{1}, col(param{2}));
	param = ir_table1_setup(param(1), col(param(2:end)));
	potk = @(pot, z) ir_table1_potk(z, pot.param);
	wpot = @(pot, z) ir_table1_wpot(z, pot.param);
	shrink = @(pot, b, reg) ir_table1_shrink(b, reg, pot.param);

otherwise
	fail('Unknown potential "%s"', ptype)
end

if isempty(dpot) % default is z * wpot(z)
	dpot = @(pot, z) z .* wpot(pot, z);
end
if isempty(shrink)
	shrink = @ir_potential_fun_shrink;
end

end % ir_potential_fun_parse()

% ir_potential_fun_shrink()
% find argmin_z 1/2 |z - b|^2 + reg * pot(z)
% default method uses fzero() which will be slow!
function out = ir_potential_fun_shrink(pot, b, reg)
out = zeros(size(b), class(b));
opt = optimset('tolx', 1e-7);
for ii=1:numel(b)
	a = abs(b(ii));
	s = sign(b(ii));
	cost = @(z) 0.5 * (z - a).^2 + reg * pot.potk(z);
%	dfun = @(z) z - a + reg * pot.dpot(z);
	try
	%	out(ii) = s * fzero(dfun, a);
	%	out(ii) = s * fminsearch(cost, a, opt);
		z0 = s * fminsearch(cost, 0, opt);
		z1 = s * fminsearch(cost, a, opt);
		if cost(z0) < cost(z1)
			out(ii) = z0;
		else
			out(ii) = z1;
		end
	catch
		whos
		keyboard
	end
end % for
end % ir_potential_fun_shrink

% ir_table0_setup()
% dz	[1]	z spacing
% dk	[K]	dpot([1:K] * dz)
function out = ir_table0_setup(dz, dk)
sk = dk(1)*dz/2 + dz * [0; cumsum(dk(1:end-1))]; % [K]
out.dz = dz;
out.dk = dk; % [1:K] samples of dpot
out.sk = sk; % [K] cumulative sums for pot(z)
K = numel(dk);
out.K = K;
end % ir_table0_setup

% ir_table0_potk()
function out = ir_table0_potk(z, param)
dz = param.dz;
dk = param.dk;
sk = param.sk;
z = abs(z);
k = floor(z / dz);
k = min(k, param.K); % at most K
big = z > dz;
out = zeros(size(z), class(z));
out(~big) = 0.5 * dk(1) / dz * z(~big).^2;
k = k(big);
out(big) = sk(k) + dk(k) .* (z(big) - k * dz);
end % ir_table0_potk

% ir_table0_wpot()
function out = ir_table0_wpot(z, param)
dz = param.dz;
dk = param.dk; % [K]
z = abs(z);
k = floor(z / dz);
k = min(k, param.K); % at most K
out = repmat(dk(1) / dz, size(z));
big = k > 0;
k = k(big);
z = z(big);
out(big) = dk(k) ./ z;
end % ir_table0_wpot

% ir_table0_shrink()
function out = ir_table0_shrink(b, reg, param)
K = param.K;
dk = param.dk;
dz = param.dz;
zk = (1:K)' * dz;
bk = zk + reg * dk; % must be done here because depends on reg
ck = bk + dz;
tmp = [0; col([bk ck]')];
out = [zk zk+dz];
out = [0; col([zk zk+dz]')];
out = sign(b) .* interp1(tmp, out, abs(b), 'linear', 'extrap');
end % ir_table0_shrink

% ir_table1_setup()
% dz	[1]	z spacing
% dk	[K]	dpot([1:K] * dz)
function out = ir_table1_setup(dz, dk)
K = numel(dk);
k = [0:K]'; % [K+1]
zk = dz * k; % [K+1]
dk0 = [0; dk]; % [K+1] prepend sample at zero
ck = [diff(dk0); 0] / dz; % [K+1] curvatures 0:K
tmp = (dk0 - zk .* ck) * dz ...
	+ dz^2/2 * ck .* ((k+1).^2 - k.^2); % [K+1]
sk = cumsum( [0; tmp] );
out.dz = dz;
out.dk = dk; % [1:K] samples of dpot
out.ck = ck; % [K+1] curvatures 0:K
out.sk = sk; % [K] cumulative sums for pot(t)
out.K = K;
end % ir_table1_setup

% ir_table1_potk()
function out = ir_table1_potk(z, param)
sk = param.sk;
dz = param.dz;
ck = param.ck;
dk0 = [0; param.dk]; % [K+1] prepend sample at zero
z = abs(z);
k = floor(z / dz);
k = min(k, param.K); % at most K
sk = sk(1+k); % matlab indexing
ck = ck(1+k); % matlab indexing
dk = dk0(1+k);
zk = k * dz;
ck = reshape(ck, size(z));
dk = reshape(dk, size(z));
sk = reshape(sk, size(z));
out = sk + (dk - zk .* ck) .* (z - zk) + ck / 2 .* (z.^2 - zk.^2);
end % ir_table1_potk

% ir_table1_wpot()
function out = ir_table1_wpot(z, param)
dz = param.dz;
ck = param.ck;
dk = param.dk;
z = abs(z);
k = floor(z / dz);
k = min(k, param.K); % at most K
out = repmat(dk(1) / dz, size(z));
big = k > 0;
k = k(big);
z = z(big);
dk = reshape(dk(k), size(z));
ck = reshape(ck(k+1), size(z));
out(big) = (dk + (z - k * dz) .* ck) ./ z;
end % ir_table1_wpot

% ir_table1_shrink()
% unfortunately this routine works only for a single scalar reg value.
function out = ir_table1_shrink(z, reg, param)
K = param.K;
zk = (1:K)' * param.dz;
bk = zk + reg * param.dk; % must be done here because depends on reg
out = sign(z) .* interp1([0; bk], [0; zk], abs(z), 'linear', 'extrap');
end % ir_table1_shrink

% gf1_potk()
% gf1: generalized fair 1st-order potential
function pot = gf1_potk(z, delta, a, b)
atd = abs(z ./ delta);
pot = delta.^2 ./ (2 * b.^3) * ...
	(2 * b.^2 .* atd + a .* b.^2 .* atd.^2 ...
	- 2 * a .* b .* atd + 2 * (a-b) .* log(1 + b .* atd));

if 0 % symbolic check
	syms x
	syms a positive
	syms b positive
	syms z positive
	int(x*(1+a*x) / (1+b*x), x, 0, z)
end
end % gf1_potk

% ir_broken_shrink()
function out = ir_broken_shrink(z, reg, delta)
out = z ./ (1 + reg);
big = delta * (1 + reg) < abs(z);
out(big) = z(big);
end % ir_broken_shrink

% cauchy_shrink()
function out = cauchy_shrink(z, reg, delta)
z = z(:);
coef = ones(numel(z),1);
coef = [1/delta^2*coef -z/delta^2 (1+reg)*coef -z];
out = zeros(size(z));
for ii=1:numel(z)
	tmp = roots(coef(ii,:));
	pick = tmp == real(tmp); % empirically, 3rd root is often real
	if sum(pick) ~= 1 % if multiple real roots, empirically pick largest
		pick = imax(abs(tmp));
	end
	out(ii) = tmp(pick);
end
end % cauchy_shrink

% ir_huber_shrink()
function out = ir_huber_shrink(z, reg, delta)
out = z ./ (1 + reg);
big = delta .* (1 + reg) < abs(z);
if numel(reg) > 1, reg = reg(big); end
if numel(delta) > 1, delta = delta(big); end
z = z(big);
out(big) = z .* (1 - reg .* delta ./ abs(z));
end % ir_huber_shrink

% fair_l1_shrink()
function out = fair_l1_shrink(z, reg, delta)
out = sign(z) .* (abs(z) - (delta + reg) ...
	+ sqrt( (delta + reg - abs(z)).^2 + 4 * delta .* abs(z) )) ./ 2;
end % fair_l1_shrink

% ir_gf1_shrink()
function out = ir_gf1_shrink(z, reg, delta, a, b)
u = a / delta;
v = b / delta;
out = sign(z) .* (v .* abs(z) - (1+reg) ...
	+ sqrt( (1 + reg - v.*abs(z)).^2 + 4 * (v + reg .* u) .* abs(z) )) ...
	./ (2 * (v + reg .* u));
end % ir_gf1_shrink

% ir_lpp_1_2_shrink()
% for l_p with p=1/2
% for a > 0 and z = t^2 the minimizer solves t^3 - a t + reg/2 = 0
function out = ir_lpp_1_2_shrink(b, reg)
sb = sign(b); a = abs(b);
%reg = 1;
%a = 50; roots([1 0 -a reg/2])
%a = linspace(0, 4, 401);
out = zeros(size(b), class(b));
%big = true(size(b));
%{
% loop method
for ib=1:numel(b)
	tmp = roots([1 0 -a(iz) reg/2])'
	out(ib) = max(tmp).^2;
end
%}
%{
% hyperbolic method for one real root:
big = 27 * (reg/2)^2 > 4 * a.^3;
t0 = -2 * sqrt(a/3) .* cosh(1/3 * acosh(3/2 * (reg/2) ./ a .* sqrt(3./a)));
%}
%{
% https://en.wikipedia.org/wiki/Cubic_function#Vieta.27s_substitution
% vieta solves t^3 + p t + q = 0 using t = w - p / (3w), i.e. p=-a and q=reg/2
% for which w^6 + q w^3 - p^3/27 = 0
% i.e. (w^3)^2 + reg/2 (w^3) + a^3/27 = 0
w3 = (-reg/2 + sqrt((reg/2).^2 - 4 * a.^3/27)) / 2; % w^3 solution by quad form
w1 = w3 .^ (1/3);
t0 = w1 + a ./ (3*w1);
out(big) = t0(big).^2;
%}
% trigonometric method for three real roots:
% https://en.wikipedia.org/wiki/Cubic_function#Trigonometric_method_for_three_real_roots
t0 = 2 * sqrt(a/3) .* cos(1/3 * acos(3*(reg/2)/2./(-a) .* sqrt(3./a)));
a_1_2 = 3/2 * reg^(2/3);
big = a > a_1_2;
out(big) = t0(big).^2;
% plot(z, out, '-o', z, z, ':', z, z-reg, '--')
out = out .* sb;
end % ir_lpp_1_2_shrink

% ir_lpp_4_3_shrink()
% for l_p with p=4/3
% from eqn. (4.5) in chaux:07:avf
function out = ir_lpp_4_3_shrink(b, reg)
sb = sign(b); a = abs(b);
x = sqrt(a.^2 + 256 * reg^3 / 729);
out = sb .* (a + 4 * reg / (3 * 2^1/3) * ((x - a).^1/3 - (x + a).^1/3));
end % ir_lpp_4_3_shrink

% ir_tav_shrink()
function out = ir_tav_shrink(z, reg, delta)
out = zeros(size(z), class(z));
big = reg < abs(z) & abs(z) < reg + delta;
out(big) = z(big) .* (1 - reg ./ abs(z(big)));
big = reg + delta <= abs(z);
out(big) = z(big);
end % ir_tav_shrink

% ir_li98cfs_potk()
function pot = ir_li98cfs_potk(z, d)
pot = d.^2 .* ((z ./ d) .* atan(z ./ d) - 0.5 * log(1 + (z ./ d).^2));
end % ir_li98cfs_potk

% ir_genhub_potk()
function pot = ir_genhub_potk(z, d, p, q)
pot = 0.5 * abs(z) .^ p .* (abs(z) <= d) ...
 + 0.5 * (p ./ q .* d .^ (p-q) .* abs(z) .^ q ...
 + (1 - p ./ q) .* d .^ p) .* (abs(z) > d);
end % ir_genhub_potk

% ir_genhub_wpot()
function pot = ir_genhub_wpot(z, d, p, q)
pot = p / 2 .* (d .^ (p-q)) .* (abs(z) .^ (q-2)) .* (abs(z) > d);
ii = abs(z) <= d;
pot(ii) = p / 2 .* (abs(z(ii)) .^ (p-2));
%pot = p / 2 .* abs(t) .^ (p-2) .* (abs(t) <= d) ...
% + p / 2 .* d .^ (p-q) .* abs(t) .^ (q-2) .* (abs(t) > d);
end % ir_genhub_wpot

% ir_stevenson94dpr_potk()
function pot = ir_stevenson94dpr_potk(z, d, p, q)
% pr [d p q]
tmp1 = (0.5 * abs(z) .^ p) .* (abs(z) <= d);
tmp2 = 0.5 * ( (p .* (d .^ (p-1)) .* abs(z) - p .* (d .^ p) ...
 + (1 ./ q) .^ (1 ./ (q-1)) ) .^ q ...
 + d .^ p - (1 ./ q) .^ (q ./ (q-1)) ) .* (abs(z) > d);
pot = tmp1 + tmp2;
end % ir_stevenson94dpr_potk

% ir_tonumeric()
% convert x to type of y
function out = ir_tonumeric(x, y)
switch class(y)
case 'double'
	out = double(x);
case 'single'
	out = single(x);
otherwise
	fail('unknown type %s', class(y))
end
end % ir_tonumeric

% ir_potential_fun_plot()
function dummy = ir_potential_fun_plot(pot)
z = linspace(-1,1,101)*2;
if isvar('pot.delta')
	z = z * pot.delta;
end
if ~im, return, end
im plc 2 2
im subplot 1
plot(z, pot.potk(z), '-', z, z.^2/2, ':', z, abs(z), ':')
axis([min(z) max(z) minmax(pot.potk(z))'])

im subplot 2
plot(z, pot.dpot(z), '-', z, z, ':')
axis([min(z) max(z) minmax(pot.dpot(z))'])

im subplot 3
plot(z, pot.wpot(z), '-', z, 1+0*z, ':')
axis([min(z) max(z) 0 1])

im subplot 4
reg = 1;
tmp = pot.shrink(z, reg);
plot(z, tmp, '-', z, z, ':')
axis([min(z) max(z) minmax(tmp)'])

dummy = [];
end % ir_potential_fun_plot

% ir_potential_fun_test()
% test routine
% examine potential functions after rescaling.
function ir_potential_fun_test

delta = 10; zmax = 4 * delta; reg = 1.5 * delta;
plist = potential_fun('list');
%plist = {'l1', 'fair-l1'}; delta = 0.5;
%plist = {'quad', 'li98cfs', 'hyper3', 'huber2'}; % show li98cfs roughly hyper3
%plist = {'quad', 'genhub', 'huber', 'stevenson94dpr'};
%plist = {'genhub'}
%plist = {'hyper3', 'qgg2', 'huber'}; delta = 10; zmax = 50;
%plist = {'lange3', 'qgg2'}; zmax = 200;
%plist = {'qgg2', 'gf1-fit'};
%plist = potential_fun('list1'); delta = 0.5;
%plist = {plist{:}, 'quad', 'gf1', 'huber', 'broken'}; % todo: more!
%plist = {'qgg2', 'table1', 'table0'};
%plist = {'qgg2', 'table1'}; fname = 'fig_reg_pot_table1_qgg2';
%plist = {'qgg2', 'table0'}; fname = 'fig_reg_pot_table0_qgg2';
%plist = {'qgg2', 'table1', 'gf1'}; fname = 'fig_reg_pot_table0_gf1_qgg2';
%plist = {'cauchy', 'l1'};
zz = zmax * linspace(-1, 1, 2001)';
bb = 3 * max(delta + reg, delta * (1+reg)) * linspace(-1, 1, 301)';
ps = [];
lshrink = {};
for ii=1:numel(plist)
	ptype = plist{ii}; % pr ptype
	if streq(ptype, 'quad')
		leg{ii} = ptype;
	else
		leg{ii} = [ptype sprintf(', $\\delta = %g$', delta)];
	end

	switch ptype
	case {'gf1', 'gf1-fit'}
		param = potential_fun('gf1-fit', nan, {'qgg2', [1 10], 1.2});
		ptype = 'gf1'; % trick
		leg{ii} = [leg{ii} sprintf(' %.3g %.4f', param(1), param(2))];
	case 'qgg2'
		param = 1.2;
		leg{ii} = [leg{ii} sprintf(', $q = %g$', param)];
	case 'genhub'
		param = [2.0 1.2];
		leg{ii} = [leg{ii} sprintf(', $p=%g, q=%g$', param(1), param(2))];
	case 'stevenson94dpr'
		param = [2 1.2];
		leg{ii} = [leg{ii} sprintf(', $p=%g, q=%g$', param(1), param(2))];
	case {'table0', 'table1'}
		dz = delta / 20;
		tmp = potential_fun('qgg2', delta, 1.2);
%		param = {dz, tmp.dpot([1:1e4] * dz)};
		param = [dz, tmp.dpot([1:1e4] * dz)];
%		tmp = sprintf(' K = %d dz = %g', numel(param{2}), param{1});
		tmp = sprintf(', $K = %d$, $\\Delta t = %g$', numel(param)-1, param(1));
		leg{ii} = [leg{ii} tmp];
	otherwise
		param = [];
	end

	pot = potential_fun(ptype, delta, param);
	pp(:,ii) = pot.potk(zz);
	pw(:,ii) = pot.wpot(zz);
	pd(:,ii) = pot.dpot(zz);

	% replace 0 with 1 to make (slow) figure showing fzero-based shrinkage
	if 0 || ~streq(func2str(pot.meth.shrink), 'ir_potential_fun_shrink')
		tmp = pot.shrink(bb, reg);
		if any(tmp ~= 0)
			ps(:,end+1) = pot.shrink(bb, reg);
			lshrink{end+1} = leg{ii};
		end
	end

	if 0 % test vs old
		try
			opot = potential_func(ptype, delta, param);
			opp = opot.potk(opot, zz);
			opw = opot.wpot(opot, zz);
			opd = opot.dpot(opot, zz);
		catch
			printm('%s no old version', ptype)
		%	keyboard % problem with private scope of ir_li98cfs_wpot
			continue
		end
		if ~isequal(opp, pp(:,ii)), 'p bug', ptype, keyboard, end
		if ~isequal(opw, pw(:,ii)), 'w bug', ptype, keyboard, end
		if ~isequal(opd, pd(:,ii)), 'd bug', ptype, keyboard, end
	end
end

if im
%	set(0,'DefaultAxesLineStyleOrder', '-|:')
	clf, pl = @(i) subplot(410 + i);
	pl(1), plot(zz, pp), title 'potk'
	axis tight, axisy([-0.0 2.5] * delta^2)
	ir_legend(leg, 'location', 'north')
	pl(2), plot(zz, pw), title 'wpot'
	axis tight, axisy(0, 1.1), ytick([0 1])
	pl(3), plot(zz, pd), title 'dpot'
	axis tight, axisy([-1 1] * 1.3 * delta)
	xlabelf '$z$'
%	ir_savefig eps_c fname
	% check derivatives
	pl(4)
	plot(zz, pd)
	title 'dpot check'
	hold on
	d = diffc(pp) / (zz(2)-zz(1));
	plot(zz(1:end-1), d(1:end-1,:), '--', ...
		zz(1:end-1), d(1:end-1,:)-pd(1:end-1,:), ':')
	hold off
	axis tight, axisy([-1 1] * 1.3 * delta)
end

if 1 && im
	if ~isempty(lshrink)
		prompt
		clf
		plot(bb, ps, '-', bb, bb, '-')
		axis equal, axis square
		axis([-1 1 -1 1]*400)
		xtick([-1 0 1] * 400)
		ytick([-1 0 1] * 400)
		ir_legend(lshrink, 'location', 'southeast')
		xlabelf '$c$'
%		ylabelf 'xhat(z)'
		ylabelf '$\hat{z}(c)$'
		grid
%		ir_savefig cw fig_reg_pot_table0_qgg2_shrink

		if 0 % figure for book
			plot(bb, ps(:,[3 2]) - repmat(ps(:,1), [1 2]), 'o')
			plot(	bb, ps(:,3) - ps(:,1), 'bo', ...
				bb, ps(:,2) - ps(:,1), 'gx')
			axis([0 500 -0.05 0.5]), ytick([0 0.05 0.1 0.5])
			xtick([0 500])
			ir_fontsize label 18
			ir_fontsize text 18
			xlabelf 'c', ylabelf 'shrinkage error for QGG2'
			ir_legend(lshrink([3 2]), 1)
%			ir_savefig cw fig_reg_pot_table01_qgg2_shrinker
			keyboard
		end
	end
end

% check 'scale' option
pot1 = potential_fun('lange3', 10, []);
pot2 = potential_fun('lange3', 10, [], 'scale', 2);
jf_equal(2 * pot1.potk(zz), pot2.potk(zz))
jf_equal(2 * pot1.dpot(zz), pot2.dpot(zz))
jf_equal(2 * pot1.wpot(zz), pot2.wpot(zz))

end % ir_potential_fun_test

% ir_potential_fun_test_lpp()
function ir_potential_fun_test_lpp
params = [0 0.01 0.1 1/2 3/4 1 4/3];
params = [0 1/2 1];
reg = 4*2^4; zmax = 2 * reg;
zz = zmax * linspace(-1, 1, 2001)';
bb = 2 * reg * linspace(-1, 1, 201);
%a_1_2 = 3 * (reg/4)^(2/3) % saddle point for p=1/2
a_1_2 = 3/2 * reg^(2/3); % breakpoint for p=1/2
if 0
	a = a_1_2;
	pot = potential_fun('lpp', nan, 1/2);
	z0 = ir_potential_fun_shrink(pot, a+1e-9, reg)
	cost = @(z) 1/2 * (z - a).^2 + reg * pot.potk(z);
	t0 = sqrt(z0)
	t0^3 - 2*a*t0 + 2*reg % should be 0
	t0^3 - a*t0 + reg/2 % should be 0
	3/2*reg - a * t0 % should be 0
	(3^(3/2) * reg)/(4*a^(3/2)) % should be 1/sqrt(2)
	cost(0)
	cost(z0)
%	syms x; solve(3 * acos(x) - acos(-x), x) % 1/sqrt(2)
return
end
tmp = [sqrt(2*reg) reg a_1_2];
tmp = outer_sum(tmp, [-1 +1]*1e-5);
bb = sort([bb col(tmp)' -col(tmp)'])'; % trick
ps = [];
lshrink = {};
if 0
	pot = potential_fun('lpp', nan, 1/2);
	potk = @(z) pot.potk(z);

%	y = sqrt(2*reg); % l0
%	y = reg; % l1
	y = a_1_2 + 1e-9; % p=1/2
	if 0
		ir_potential_fun_shrink(pot, y, reg)
		ir_potential_fun_shrink(pot, y, reg)
	return
	end

	if 0
		z1 = pot.shrink(y, reg)
		d1 = z1 - y + reg * pot.dpot(z1) % 1st derivative
		d2 = 1 + reg * (1/2)*(-1/2) * z1^(-3/2) % 2nd derivative > 0?

		dfit = 1/2 * (y - zz).^2;
		cost = dfit + reg * potk(zz);
		plot(zz, dfit, '--', zz, reg*potk(zz), '-', zz, cost, '-')
		tmp = minmax(zz(cost <= 3*min(cost)));
		tmp(1) = min(tmp(1), -10);
		tmp(2) = max(tmp(2), reg/3);
		xlim(tmp), ylim([0.0 2*1.2] * min(cost)), grid
	%	ytick([0 round(min(cost))])
		ytick([0 min(cost)])
		xtick([0 z1 a_1_2]), xlabelf '$z$', ylabelf '$\Psi(z)$'
	return
	end

	zs = ir_potential_fun_shrink(pot, bb, reg);
	zp = pot.shrink(bb, reg);

	plot(bb, zs, '-o', bb, zp, '.-', bb, bb, ':')
	legend({'fmin', 'trig'}, 'location', 'northwest')
	xlabelf '$b$'
	ylabelf '$\hat{z}(b)$'
	axis equal, axis square
	axis([-1 1 -1 1]*1.1*reg)
	tmp = [sqrt(2*reg) a_1_2 reg]; % l0 and l1 breakpoints
	xtick([-tmp 0 tmp])
	ytick([-1 0 1] * reg)
	grid
%	ir_savefig cw fig_?
return
end

for ip=1:length(params)
	pot = potential_fun('lpp', 0, params(ip));

	% replace 0 with 1 to make (slow) figure showing fzero-based shrinkage
	if 0 || ~streq(func2str(pot.meth.shrink), 'ir_potential_fun_shrink')
		tmp = pot.shrink(bb, reg);
		if any(tmp ~= 0)
			ps(:,end+1) = pot.shrink(bb, reg);
			lshrink{end+1} = sprintf('p=%g', params(ip));
		end
	end

	clf
	plot(bb, ps, '-', bb, bb, ':')
	legend(lshrink{:}, 'location', 'southeast')
	xlabelf '$b$'
	ylabelf '$\hat{z}(b)$'
	axis equal, axis square
	axis([-1 1 -1 1]*1.5*reg)
	tmp = [sqrt(2*reg) a_1_2 reg]; % l0 and l1 breakpoints
	xtick([-tmp 0 tmp])
	ytick([-1 0 1] * reg)
	grid
%	ir_savefig cw fig_?
end

end % ir_potential_fun_test_lpp()


function modelnet_off2mat(off_path, data_path, classes, volume_size, pad_size, angle_inc)
% Put the mesh object in a volume grid and save the volumetric
% represenation file.
% This is the input volumetric data for 3D ShapeNets.
% off_path: root off data folder
% data_path: destination volumetric data folder

phases = {'train', 'test'};

data_size = pad_size * 2 + volume_size;
for c = 1 : length(classes)
    fprintf('writing the %s category\n', classes{c});
    category_path = [off_path '/' classes{c}];
    dest_path = [data_path '/' classes{c} '/' num2str(data_size)];
    if ~exist(dest_path, 'dir')
        mkdir(dest_path);
    end
    % for train and test phases
    for t = 1 : numel(phases)
        phase = phases{t};
        off_list = [category_path '/' phase];
        dest_tsdf_path = [dest_path '/' phase];
        if ~exist(dest_tsdf_path, 'dir')
            mkdir(dest_tsdf_path);
        end
        files = dir(off_list);
        for i = 1 : length(files)
            if strcmp(files(i).name, '.') || strcmp(files(i).name, '..') || files(i).isdir == 1 || ~strcmp(files(i).name(end-2:end), 'off')
                continue;
            end
%             rnd_Vol = randi([0 4]);
            filename = [off_list '/' files(i).name];
            for viewpoint = 1 : 360/angle_inc
                destname = [dest_tsdf_path '/' files(i).name(1:end-4) '_' num2str(viewpoint) '.mat'];
                off_data = off_loader(filename, (viewpoint-1)*angle_inc);
%                 instance = polygon2voxel(off_data, [volume_size, volume_size, volume_size], 'auto',t,rnd_Vol);
                instance = polygon2voxel(off_data, [volume_size, volume_size, volume_size], 'auto');
                instance = padarray(instance, [pad_size, pad_size, pad_size]);
                instance = int8(instance);
                save(destname, 'instance');
            end
        end
    end
end

function offobj = off_loader(filename, theta, axis, stretch)

offobj = struct();
fid = fopen(filename, 'rb');
OFF_sign = fscanf(fid, '%c', 3);
assert(strcmp(OFF_sign, 'OFF') == 1);

info = fscanf(fid, '%d', 3);
offobj.vertices = reshape(fscanf(fid, '%f', info(1)*3), 3, info(1))';
offobj.faces = reshape(fscanf(fid, '%d', info(2)*4), 4, info(2))';

% do some translation and rotation
center = (max(offobj.vertices) + min(offobj.vertices)) / 2;
offobj.vertices = bsxfun(@minus, offobj.vertices, center);
if exist('axis', 'var')
    switch axis
        case 'x',
            offobj.vertices(:,1) = offobj.vertices(:,1) * stretch;
        case 'y',
            offobj.vertices(:,2) = offobj.vertices(:,2) * stretch;
        case 'z',
            offobj.vertices(:,3) = offobj.vertices(:,3) * stretch;
        otherwise,
            error('off_loader axis set wrong');
    end
end
theta = theta * pi / 180;
R = [cos(theta), -sin(theta), 0;
     sin(theta), cos(theta) , 0;
        0      ,    0       , 1];

offobj.vertices = offobj.vertices * R;

% These vertices to define faces should be offset by one to follow the matlab convention.
offobj.faces = offobj.faces(:,2:end) + 1;

fclose(fid);


classdef prtRvVq < prtRv
    % prtRvVq  Vector quantization random variable
    %
    %   RV = prtRvVq creates a prtRvVq object with empty means and
    %   probabilities. The means and probabilties must be set either
    %   directly, or by calling the MLE method.
    %
    %   Vector quanitization uses k-means to discretize the data space
    %   using nCategories means. The means are the discrete points in space and
    %   have probabilies representing their prominence in the data. The
    %   pdf is calculated by mapping to the nearest entry of the means and
    %   giving the data point the corresponding entry in probabilities.
    %
    %   RV = prtRvVq(PROPERTY1, VALUE1,...) creates a prtRvVq object RV
    %   with properties as specified by PROPERTY/VALUE pairs.
    %
    %   A prtRvVq object inherits all properties from the prtRv class. In
    %   addition, it has the following properties:
    %
    %   nCategories   - The number of categories
    %   means         - The means of each catergory that are used to
    %                   approximate the density
    %   probabilities - The probabilities of each category
    %
    %  A prtRvVq object inherits all methods from the prtRv class. The MLE
    %  method can be used to estimate the distribution parameters from
    %  data.
    %
    %  Example:
    %
    %  dataSet = prtDataGenUnimodal;        % Load a dataset consisting of
    %                                       % 2 features
    %  dataSet = retainFeatures(dataSet,1); % Retain only the first feature
    %
    %  RV = prtRvVq;                        % Create a prtRvVq object
    %  RV = RV.mle(dataSet);                % Compute the VQ parameters
    %                                       % form the data
    %  RV.plotPdf                           % Plot the pdf
    %
    %   See also: prtRv, prtRvMvn, prtRvGmm, prtRvMultinomial,
    %   prtRvUniform, prtRvUniformImproper

    properties (SetAccess = private)
        name = 'Vector Quantization Random Variable'
        nameAbbreviation = 'RVVQ';
    end

    properties (SetAccess = protected)
        isSupervised = false;
        isCrossValidateValid = true;
    end

    properties (Dependent = true)
        probabilities   % The probabilities
        means           % The means
        nCategories     % The number of categories
    end

    properties (Dependent = true, Hidden=true)
        InternalKMeansPrototypes
        InternalDiscrete
        nDimensions
    end

    properties (SetAccess = 'private', GetAccess = 'private', Hidden=true)
        %InternalKMeansPrototypesDepHelp = prtClassKmeansPrototypes('kMeansHandleEmptyClusters','random');
        meanDepHelper = [];
        InternalDiscreteDepHelp = prtRvDiscrete();
        nCategoriesDepHelp = 2;
    end

    methods
        % The Constructor
        function R = prtRvVq(varargin)
            R = constructorInputParse(R,varargin{:});
        end
        function val = get.means(R)
            val = R.meanDepHelper;
        end
        function val = get.probabilities(R)
            val = R.InternalDiscreteDepHelp.probabilities;
        end
        function val = get.nCategories(R)
            val = R.nCategoriesDepHelp;
        end

        function val = get.InternalDiscrete(R)
            val = R.InternalDiscreteDepHelp;
        end

        function R = set.InternalDiscrete(R,val)
            R.InternalDiscreteDepHelp = val;
        end

        function R = set.InternalDiscreteDepHelp(R,val)
            assert(isa(val,'prtRvDiscrete'),'InternalDiscrete must be a prtRvDiscrete.')
            R.InternalDiscreteDepHelp = val;
        end

        function R = set.nCategories(R,val)
            assert(numel(val)==1 && val==floor(val) && val > 0,'nCategories must be a scalar positive integer.');

            R.nCategoriesDepHelp = val;
        end

        function R = set.probabilities(R,val)
            assert(isnumeric(val) && isvector(val),'probabilities must be numer vector whose values sum to one.');

            if ~isempty(R.InternalDiscreteDepHelp.symbols)
                assert(size(R.InternalDiscreteDepHelp.symbols,1) == numel(val),'size mismatch between probabilities and means.')
            end
            R.InternalDiscreteDepHelp.probabilities = val(:);
            R.nCategories = numel(val);
        end

        function R = set.means(R,val)
            assert(ndims(val)==2 && isnumeric(val),'means must be a 2D numeric matrix.')

            if ~isempty(R.InternalDiscreteDepHelp.probabilities)
                if  numel(R.InternalDiscreteDepHelp.probabilities) ~= size(val,1)
                    if isvector(val)
                        error('prt:prtRvVq','means must be an NxD matrix where D is the dimensionality and N is the number of components. You may need to transpose the supplied value.')
                    else
                        error('prt:prtRvVq','size mismatch between probabilities and means.')
                    end
                end
            end

            R.nCategories = size(val,1);

            R.InternalDiscrete.symbols = val;
            R.meanDepHelper = val;
        end

        function val = get.nDimensions(R)
            if ~isempty(R.means)
                val = size(R.means,2);
            else
                val = [];
            end
        end

        function R = mle(R,X)
            X = R.dataInputParse(X); % Basic error checking etc
            assert(isnumeric(X) && ndims(X)==2,'X must be a 2D numeric array.');

            R.means = prtUtilKmeans(X,R.nCategories,'handleEmptyClusters','random');

            trainingOutput = R.data2ClosestMeanInd(X);

            R.InternalDiscrete = prtRvDiscrete('symbols',R.means,'probabilities',histc(trainingOutput,1:R.nCategories)/size(X,1));
        end

        function vals = pdf(R,X)
            [isValid, reasonStr] = R.isValid;
            assert(isValid,'PDF cannot yet be evaluated. This RV is not yet valid %s.',reasonStr);

            X = R.dataInputParse(X); % Basic error checking etc
            assert(size(X,2) == R.nDimensions,'Data, RV dimensionality missmatch. Input data, X, has dimensionality %d and this RV has dimensionality %d.', size(X,2), R.nDimensions)
            assert(isnumeric(X) && ndims(X)==2,'X must be a 2D numeric array.');

            trainingOutput = R.data2ClosestMeanInd(X);
            vals = R.probabilities(trainingOutput);
            vals = vals(:);
        end

        function vals = logPdf(R,X)
            [isValid, reasonStr] = R.isValid;
            assert(isValid,'LOGPDF cannot yet be evaluated. This RV is not yet valid %s.',reasonStr);

            vals = log(pdf(R,X));
        end

        function vals = draw(R,N)
            if nargin < 2 || isempty(N)
                N = 1;
            end

            [isValid, reasonStr] = R.isValid;
            assert(isValid,'DRAW cannot yet be evaluated. This RV is not yet valid %s.',reasonStr);

            assert(numel(N)==1 && N==floor(N) && N > 0,'N must be a positive integer scalar.')

            vals = R.InternalDiscrete.draw(N);
        end

        function varargout = plotPdf(R,varargin)
            h = plotPdf(R.InternalDiscrete);

            varargout = {};
            if nargout
                varargout = {h};
            end
        end

        function varargout = plotCdf(R,varargin)
            h = plotCdf(R.InternalDiscrete);

            varargout = {};
            if nargout
                varargout = {h};
            end
        end

        function quantizedData = vq(R,X)
            X = R.dataInputParse(X); % Basic error checking etc
            quantizedData = data2ClosestMeanInd(R,X);
        end
    end

    methods (Hidden = true)
        function [val, reasonStr] = isValid(R)
            if numel(R) > 1
                val = false(size(R));
                for iR = 1:numel(R)
                    [val(iR), reasonStr] = isValid(R(iR));
                end
                return
            end

            [val, reasonStr] = isValid(R.InternalDiscrete);
            reasonStr = strrep(reasonStr,'symbols','means');
        end

        function val = plotLimits(R)
            val = plotLimits(R.InternalDiscrete);
        end

        function val = isPlottable(R)
            val = isPlottable(R.InternalDiscrete);
        end
    end

    methods (Hidden = true, Access=protected)
        function closestMeanInds = data2ClosestMeanInd(R,X)
            distance = prtDistanceEuclidean(X,R.means);
            [dontNeed, closestMeanInds] = min(distance,[],2); %#ok<ASGLU>
        end
    end

end


function [ mHC ] = CircularExtension2D( mH, numRows, numCols )

kernelRadiusV = floor(size(mH, 1) / 2); %<! Vertical Radius
kernelRadiusH = floor(size(mH, 2) / 2); %<! Horizontal Radius

mHC = mH;
mHC(numRows, numCols) = 0;
mHC = circshift(mHC, [-kernelRadiusV, -kernelRadiusH]);

end


function [X,Zf] = filter_fast(B,A,X,Zi,dim)
% Like filter(), but faster when both the filter and the signal are long.
% [Y,Zf] = filter_fast(B,A,X,Zi,Dim)
%
% Uses FFT convolution. The function is faster than filter when approx. length(B)>256 and
% size(X,Dim)>1024, otherwise slower (due size-testing overhead).
%
% See also:
%   filter, fftfilt
%
%                           Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                           2010-07-09
%
%                           contains fftfilt.m from Octave:
%                           Copyright (C) 1996-1997 John W. Eaton

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

if nargin <= 4
    dim = find(size(X)~=1,1); end
if nargin <= 3
    Zi = []; end

lenx = size(X,dim);
lenb = length(B);
if lenx == 0
    % empty X
    Zf = Zi;
elseif lenb < 256 || lenx<1024 || lenx <= lenb || lenx*lenb < 4000000 || ~isequal(A,1)
    % use the regular filter
    if nargout > 1
        [X,Zf] = filter(B,A,X,Zi,dim);
    else
        X = filter(B,A,X,Zi,dim);
    end
else
    % fftfilt can be used, determine which algorithm to use
    try
        fftfilt(1,1);
        do_fftfilt = @fftfilt;
    catch
        do_fftfilt = @oct_fftfilt;
    end
    was_single = isa(X,'single');

    if isempty(Zi)
        % no initial conditions to take care of
        if nargout < 2
            % and no final ones
            X = unflip(do_fftfilt(B,flip(double(X),dim)),dim);
        else
            % final conditions needed
            X = flip(X,dim);
            [dummy,Zf] = filter(B,1,X(end-length(B)+1:end,:),Zi,1); %#ok<ASGLU>
            X = do_fftfilt(B,double(X));
            X = unflip(X,dim);
        end
    else
        % initial conditions available
        X = flip(X,dim);
        % get a Zi-informed piece
        tmp = filter(B,1,X(1:length(B),:),Zi,1);
        if nargout > 1
            % also need final conditions
            [dummy,Zf] = filter(B,1,X(end-length(B)+1:end,:),Zi,1); %#ok<ASGLU>
        end
        X = do_fftfilt(B,double(X));
        % incorporate the piece
        X(1:length(B),:) = tmp;
        X = unflip(X,dim);
    end
    if was_single
        X = single(X); end
end

function X = flip(X,dim)
if dim ~= 1
    order = 1:ndims(X);
    order = order([dim 1]);
    X = permute(X,order);
end

function X = unflip(X,dim)
if dim ~= 1
    order = 1:ndims(X);
    order = order([dim 1]);
    X = ipermute(X,order);
end

function y = oct_fftfilt(b, x, N)
% Copyright (C) 1996, 1997 John W. Eaton
%
% This file is part of Octave.
%
% Octave is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2, or (at your option)
% any later version.
%
% Octave 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 Octave; see the file COPYING.  If not, write to the Free
% Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
% 02110-1301, USA.
%
% -*- texinfo -*-
% @deftypefn {Function File} {} fftfilt (@var{b}, @var{x}, @var{n})
%
% With two arguments, @code{fftfilt} filters @var{x} with the FIR filter
% @var{b} using the FFT.
%
% Given the optional third argument, @var{n}, @code{fftfilt} uses the
% overlap-add method to filter @var{x} with @var{b} using an N-point FFT.
%
% If @var{x} is a matrix, filter each column of the matrix.
% @end deftypefn
%
% Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
% Created: 3 September 1994
% Adapted-By: jwe

% If N is not specified explicitly, we do not use the overlap-add
% method at all because loops are really slow.  Otherwise, we only
% ensure that the number of points in the FFT is the smallest power
% of two larger than N and length(b).  This could result in length
% one blocks, but if the user knows better ...
transpose = (size(x,1) == 1);

if transpose
    x = x.'; end

[r_x,c_x] = size(x);
[r_b,c_b] = size(b);
if min([r_b, c_b]) ~= 1
    error('octave:fftfilt','fftfilt: b should be a vector'); end

l_b = r_b*c_b;
b = reshape(b,l_b,1);

if nargin == 2
    % Use FFT with the smallest power of 2 which is >= length (x) +
    % length (b) - 1 as number of points ...
    N = 2^(ceil(log(r_x+l_b-1)/log(2)));
    B = fft(b,N);
    y = ifft(fft(x,N).*B(:,ones(1,c_x)));
else
    % Use overlap-add method ...
    if ~isscalar(N)
        error ('octave:fftfilt','fftfilt: N has to be a scalar'); end
    N = 2^(ceil(log(max([N,l_b]))/log(2)));
    L = N - l_b + 1;
    B = fft(b, N);
    B = B(:,ones(c_x,1));
    R = ceil(r_x / L);
    y = zeros(r_x, c_x);
    for r = 1:R
        lo = (r - 1) * L + 1;
        hi = min(r * L, r_x);
        tmp = zeros(N, c_x);
        tmp(1:(hi-lo+1),:) = x(lo:hi,:);
        tmp = ifft(fft(tmp).*B);
        hi = min(lo+N-1, r_x);
        y(lo:hi,:) = y(lo:hi,:) + tmp(1:(hi-lo+1),:);
    end
end

y = y(1:r_x,:);
if transpose
    y = y.'; end

% Final cleanups: if both x and b are real respectively integer, y
% should also be
if isreal(b) && isreal(x)
    y = real(y); end
if ~any(b - round(b))
    idx = ~any(x - round(x));
    y(:,idx) = round(y(:,idx));
end


function brand()
    % brand draws x random samples of size N from the current dataset and computes the b-value
    % sw, last modifies 9/2001
    % turned into function by Celso G Reyes 2017

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    ar2 = [];
    arm2 = [];
    br2 = [];
    brm2 = [];

    sdlg.prompt='Minimum number of events per sample ?'; sdlg.value=50;
    sdlg(2).prompt='Step width in events ? '; sdlg(2).value=10;
    sdlg(3).prompt='Maximum number of events per sample?'; sdlg(3).value=200;
    sdlg(4).prompt='Number of samples drawn ?'; sdlg(4).value=100;

    [~,~,n1,ns,n2,nr]=smart_inputdlg('Random b-value calculation', sdlg);

    %n1 = str2double(prmptdlg('Minimum number of events per sample','50'));
    %ns = str2double(prmptdlg('Step width in events','10'));
    %n2 = str2double(prmptdlg('Maximum number of events per sample','200'));
    %nr = str2double(prmptdlg('Numer of samples drawn ','100'));
    tic
    niv = n1:ns:n2;

    globalcatalog=ZG.primeCatalog;

    for ni = n1:ns:n2
        ni
        ar = [];
        arm = [];
        br = [];
        brm = [];
        for i = 1:nr
            l = ceil(rand([ni 1])*globalcatalog.Count);
            %[bv magco stan,  av] =  bvalca3(newa(l,:), McAutoEstimate.manual);
            %br = [br bv];
            %ar = [ar av];
            [bv2 stan av2 ] = calc_bmemag(globalcatalog.Magnitude(l),0.1);
            brm = [brm bv2];
            arm = [arm av2];
        end
        %br2 = [br2 ; br];
        brm2 = [brm2 ; brm];
        %ar2 = [ar2 ; ar];
        arm2 = [arm2 ; arm];
    end

    figure
    pl1 =plot(niv,prctile2(brm2',50),'k')
    set(pl1,'LineWidth',2.0)
    set(gca,'NextPlot','add')
    pl2=plot(niv,prctile2(brm2',95),'r--');
    set(pl2,'LineWidth',1.0,'color',[0.3 0.3 0.3])
    pl3=plot(niv,prctile2(brm2',5),'r-.');
    set(pl3,'LineWidth',1.0,'color',[0.3 0.3 0.3])

    legend([pl1 pl2 pl3],'mean','95%','5%');

    set(gca,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2)
    xlabel('Number of eqs')
    ylabel('Range of b-value')

    figure

    pl1=plot(niv,prctile2(arm2',50),'k');
    set(pl1,'LineWidth',2.0)
    set(gca,'NextPlot','add')
    pl2=plot(niv,prctile2(arm2',95),'r--');
    set(pl2,'LineWidth',1.0,'color',[0.3 0.3 0.3])
    pl3=plot(niv,prctile2(arm2',5),'r-.');
    set(pl3,'LineWidth',1.0,'color',[0.3 0.3 0.3])
    legend([pl1 pl2 pl3],'mean','95%','5%');

    set(gca,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2)
    xlabel('Number of eqs')
    ylabel('Range of a-value')
    grid

    toc
    %
    return

    % experimental code ...

    A = [];
    for i = 1:1:99
        i
        A = [A ; niv' prctile2(brm2',i)' niv'*0+i];
    end
    % l = A(:,3)>50; A(l,3) = 100 - A(l,3);
    [ X, Y ] = meshgrid(n1:ns:n2,0.5:0.01:1.5);

    Z = griddata(A(:,1),A(:,2),A(:,3),X,Y);

    figure
    contourf(X,Y,Z,[1 5 10 50 90 95 99]);

    g = gray(6);
    g = g(11:-1:2,:);
    colormap(g);
end


function cS = anorthite
% (Plagioclase feldspar)

cs_An = crystalSymmetry('-1',[8.1797 12.8748 14.1721], [93.13,115.89,91.24]*degree);
N = Miller({0,1,0},{0,0,1},{1,1,0},{1,-1,0},{1,1,-1},{1,-1,-1},{2,0,-1},cs_An);
dist = [0.65, 0.5, 1.25, 1.2, 1.2, 1.05, 0.95];
cS = crystalShape(N./dist);


function ind = inpolygon(ebsd,xy)
% checks which ebsd data are within given polygon
%
% Syntax
%   ind = inpolygon(ebsd,[xmin,ymin,dx,dy]) % select indices by rectangle
%   ind = inpolygon(ebsd,[x1 y1; x2 y2; x3 y3; x4 y4]) % select indices by poylgon
%   ebsd = ebsd(ind) % select EBSD data by indices
%
% Input
%  ebsd    - @EBSD
%  xmin, xmax - lower left corner of a rectangle
%  dx, dy - extend of a rectangle
%  x, y  - vertices of a polygon
%
% Output
%  ind - logical
%
% See also
% inpolygon

% shortcut for simple rectangles
if numel(xy)==4

  xy(3:4) = xy(1:2) + xy(3:4);
  corners = [1 2; 3 2; 3 4; 1 4; 1 2];
  xy = xy(corners);

end

% check for inside
if ~getMTEXpref('insidepoly')
  ind = inpolygon(ebsd.prop.x,ebsd.prop.y,xy(:,1),xy(:,2));
else
  ind = insidepoly(ebsd.prop.x,ebsd.prop.y,xy(:,1),xy(:,2));
end

end