function done = mission2(occupiers, player)

captured = zeros(1,6);
for i = 1:6
    captured(i) = all(occupiers{i} == player);
end

done = captured(3) && captured(5) && sum(captured) > 2;


function [L,a,b] = rgb2lab(R,G,B)
% function [L, a, b] = RGB2Lab(R, G, B)
% RGB2Lab takes matrices corresponding to Red, Green, and Blue, and
% transforms them into CIELab.  This transform is based on ITU-R
% Recommendation  BT.709 using the D65 white point reference.
% The error in transforming RGB -> Lab -> RGB is approximately
% 10^-5.  RGB values can be either between 0 and 1 or between 0 and 255.
% By Mark Ruzon from C code by Yossi Rubner, 23 September 1997.
% Updated for MATLAB 5 28 January 1998.

if (nargin == 1)
  B = double(R(:,:,3));
  G = double(R(:,:,2));
  R = double(R(:,:,1));
end

if ((max(max(R)) > 1.0) | (max(max(G)) > 1.0) | (max(max(B)) > 1.0))
  R = R/255;
  G = G/255;
  B = B/255;
end

[M, N] = size(R);
s = M*N;

% Set a threshold
T = 0.008856;

RGB = [reshape(R,1,s); reshape(G,1,s); reshape(B,1,s)];

% RGB to XYZ
MAT = [0.412453 0.357580 0.180423;
       0.212671 0.715160 0.072169;
       0.019334 0.119193 0.950227];
XYZ = MAT * RGB;

X = XYZ(1,:) / 0.950456;
Y = XYZ(2,:);
Z = XYZ(3,:) / 1.088754;

XT = X > T;
YT = Y > T;
ZT = Z > T;

fX = XT .* X.^(1/3) + (~XT) .* (7.787 .* X + 16/116);

% Compute L
Y3 = Y.^(1/3);
fY = YT .* Y3 + (~YT) .* (7.787 .* Y + 16/116);
L  = YT .* (116 * Y3 - 16.0) + (~YT) .* (903.3 * Y);

fZ = ZT .* Z.^(1/3) + (~ZT) .* (7.787 .* Z + 16/116);

% Compute a and b
a = 500 * (fX - fY);
b = 200 * (fY - fZ);

L = reshape(L, M, N);
a = reshape(a, M, N);
b = reshape(b, M, N);

if ((nargout == 1) | (nargout == 0))
  L = cat(3,L,a,b);
end


function [total_time, ts, X] = TrajectoryPlanning(path, decomp, time_allocation)
    speed   = time_allocation.avg_speed;
    acc     = time_allocation.acc;

    disp(['The planned speed is : ', num2str(speed)]);
    tic
    if strcmp(time_allocation.type, 'averageSpeed')
        [ts, total_time] = averageSpeed_ta(path0, speed);
    elseif strcmp(time_allocation.type, 'trapzoidSpeed')
        [ts, total_time] = trapezoidalSpeed_ta(path, speed, acc);
    end
    disp('TimeAllocation time is :');
    toc
    disp(['time management: total_time is ', num2str(total_time), 'seconds']);
    disp(['Split time is : ', num2str(ts)]);

    tic
    %  use Ax=b get Trajectory planning. ===========================
    %  X = Ax_equal_b(path, total_time, ts);

    % use 'Quadratic Programming' and SFC(which make by Ax < b) get Trajectory planning. ========================
    % use SFC make Inequality constraints
    X = QPbyUseSFC(path, ts, decomp);

    disp('generator trajectory time is :');
    toc
end


function [Msig1,Msig2,MLong]=afi_blochsim(alpha, T1, T2, TE, TR1, TR2, crushFlag, partialDephasingFlag, partialDephasing, df, Nex, inc)
%IR_BLOCHSIM Bloch simulations of the GRE-AFI pulse sequence.
% Simulates 100 spins params.Nex repetitions of the AFI pulse
% sequences.
%
% params: Struct with the following fields:
%   alpha: Excitation pulse flip angle in radians.
%   TR1: Repetition time 1 (ms).
%   TR2: Repetition time 2 (ms).
%   TE: Echo time (ms).
%   T1: Longitudinal relaxation time (ms).
%   T2: Transverse relaxation time (ms).
%   Nex: Number of excitations
%   df: Off-resonance frequency of spins relative to excitation pulse (in Hz)
%   crushFlag: Numeric flag for perfect spoiling (1) or partial spoiling (2).
%   partialDephasing: Partial dephasing fraction (between [0, 1]). 1 = no dephasing, 0 = complete dephasing (sele
%   inc: Phase spoiling increment in degrees.
%
% Outputs:
%   MLong: Longitudinal magnetization at time TI (prior to excitation pulse).
%   Msig: Complex signal produced by the transverse magnetization at time TE after excitation.
%

%% Set up spin properties
%

Nf = 100;

if partialDephasingFlag
    phi = ((1-Nf/2):Nf/2)/Nf*2*pi*partialDephasing; % Radian phase vector going from 2Pi/Nf to 2Pi in 2Pi/Nf increments.
end

%% Calculate free-precession matrices
%

%"A" is decay and phase gained due to off resonance, "B" is regrowth

% Magnetization decayed (A) and regrowth (B) between the alpha pulse and measurement.
[Ate,Bte] = free_precess(TE,T1,T2,df);

% Magnetization decayed (A) and regrowth (B) between the measurement and the next TR.
[Atr1,Btr1] = free_precess(TR1-TE,T1,T2,df);

% Magnetization decayed (A) and regrowth (B) between the measurement and the next TR.
[Atr2,Btr2] = free_precess(TR2-TE,T1,T2,df);

%% Bloch Simulation
%

M = [zeros(2,Nf);ones(1,Nf)]; % Sets initial magnetization for every spin [0;0;1]
on = ones(1,Nf); % Vector to ensure size of matrices in further calculations

Rfph = 0;       % Rf phase
Rfinc = inc;

for n=1:Nex

    %Signal 1
    MLong = mean(M(3,:)); % Longitudinal magnetization just before excitation pulse

	A = Ate * th_rot(alpha, Rfph);
	B = Bte;

	M = A*M+B*on; % M is rotated, then decayed for TE. Regrowth factor is added.

	Msig1 = sum( squeeze(M(1,:)+1i*M(2,:)) ) / Nf; % Complex signal 1 by adding up all the spins

	M=Atr1*M+Btr1*on; % Relaxation during rest of TR1 after TE

    if crushFlag
        % To make sure spoiling is ideal
        M(1:2, :) = 0;
    elseif partialDephasing
        for k=1:Nf
            M(:,k) = z_rot(phi(k))*M(:,k);  % Dephase spins.
        end
    end

    Rfph = Rfph+Rfinc; % Calculate the next RF phase
    Rfinc = Rfinc+inc; % Calculate the next RF increment

%     Msig2 = Msig1;

    %Signal 2
    MLong = mean(M(3,:)); % Longitudinal magnetization after signal 1

	A = Ate * th_rot(alpha, Rfph);
	B = Bte;

	M = A*M+B*on; % M is rotated, then decayed for TE. Regrowth factor is added.

	Msig2 = sum( squeeze(M(1,:)+1i*M(2,:)) ) / Nf; % Complex signal by adding up all the spins

	M=Atr2*M+Btr2*on; % Relaxation during rest of TR1 after TE

    if crushFlag
        % To make sure spoiling is ideal
        M(1:2, :) = 0;
    elseif partialDephasing
        for k=1:Nf
            M(:,k) = z_rot(phi(k))*M(:,k);  % Dephase spins.
        end
    end

    Rfph = Rfph+Rfinc; % Calculate the next RF phase
    Rfinc = Rfinc+inc; % Calculate the next RF increment

end


function YESNONA = isconvex(p)
%ISCONVEX Tries to determine if a scalar expression is convex
%
% T = isconvex(p)
%
% p: scalar SDPVAR object
% T: The result (1: convex, 0: concave, NaN: cannot be determined)
%
% NOTE : Under development. Do not trust if you have monomials in your model
%
% Example
% sdpvar x y
% isconvex(x+y) will return 1
% isconvex(x+y^2) will return 1
% isconvex(exp(x+y)) will return 1
% isconvex(-exp(x+y)) will return 0
% isconvex(max(x,exp(x+y))) will return 1
% isconvex(-max(x,exp(x+y))) will return 0
% isconvex(max(x,min(x,-x))) will return NaN

YESNONA = NaN;
[F,failure,cause] = expandmodel([],p,sdpsettings('allownonconvex',0,'allowmilp',0));
if failure == 0
    YESNONA = true;
else
    [F,failure,cause] = expandmodel([],-p,sdpsettings('allownonconvex',0));
    if failure == 0
        % p is nonconvex
        YESNONA = false;
    end
end


function cS = garnet(varargin)
% simple morphology
%

if nargin == 0 || ~isa(varargin{1},'symmetry')
  cs = crystalSymmetry('m3m','mineral','garnet');
else
  cs = varargin{1};
end

if check_option(varargin,'simple')

  N= Miller({1,0,0},{2,1,1},cs);
  dist = [0.45, 1];
  cS = crystalShape(N./dist);

  %N = Miller({1,1,0},{2,1,1},cs);
  %cS = crystalShape(N,1.5);

else

  N = Miller({1,0,0},{1,1,0},{4,3,1},{3,1,1},cs);
  dist = [0.92, 1.02, 3.93, 2.93];
  cS = crystalShape(N./dist);

end


function value = calculateValue(s0,price,inFlow,turbFlow,spillFlow,C2A,n)
% Calculate the revenue generated at each time step for given turbine and
% spill flows.
%
% Copyright (c) 2012, MathWorks, Inc.
%%
% Initialize Value
value = zeros(n,1);

% Intialize Storage Vector
s = zeros(n,1);
s(1) = s0;

% Loop through time, calculate storage at each time step and calculate
% revenue from storage and turbine flow
for ii = 2:n
    s(ii) = s(ii-1)+(inFlow(ii-1) - turbFlow(ii-1) - spillFlow(ii-1))*C2A;
    value(ii) = price(ii)*turbFlow(ii)*(0.00001*(s(ii)+s(ii-1))/2+10)/1000;
end


% MatrixUser, a multi-dimensional matrix analysis software package
% https://sourceforge.net/projects/matrixuser/
%
% The MatrixUser is a matrix analysis software package developed under Matlab
% Graphical User Interface Developing Environment (GUIDE). It features
% functions that are designed and optimized for working with multi-dimensional
% matrix under Matlab. These functions typically includes functions for
% multi-dimensional matrix display, matrix (image stack) analysis and matrix
% processing.
%
% Author:
%   Fang Liu <leoliuf@gmail.com>
%   University of Wisconsin-Madison
%   Aug-30-2014

function MU_funcPolygonSeg(Temp,Event,handles)
handles = guidata(handles.MU_matrix_display);

handles.V.Color_map='Gray';
set(handles.Color_map_popmenu,'Value',1);
handles=MU_update_image(handles.Matrix_display_axes,{handles.TMatrix,handles.Mask},handles,0);
MU_enable('off',[],handles);
Seg_h=impoly;
wait(Seg_h);
if ~isvalid(Seg_h) % detect when main display is deleted
    return;
end
handles.V.Segs{end+1,1}='impoly';
handles.V.Segs{end,2}=handles.V.Slice;
handles.V.Segs{end,3}=1;
handles.V.Segs{end,4}=getPosition(Seg_h);
MU_enable('on',{'Color_map_popmenu'},handles);
BW=createMask(Seg_h);
Temp=handles.Mask;
Temp2=Temp(:,:,handles.V.Slice);
Temp2(BW~=0)=1;
Temp(:,:,handles.V.Slice)=Temp2;
handles.Mask=Temp;
handles=MU_update_image(handles.Matrix_display_axes,{handles.TMatrix,handles.Mask},handles,0);
handles.V.ROI=struct(...
                     'ROI_flag', 8,...
                     'ROI_mov',[],...  % ROI movement track
                     'ROI_Stat_h', [],...
                     'ROI_h', Seg_h ...
                     );
guidata(handles.MU_matrix_display, handles);

end


% demo of v_windows
close all;
wty=[1:5 7:15]; % list of window types to plot
for i=wty
    figure(i);
    v_windows(i,2520,'usw');
end
wty=[2,3,8,11]; % list of square root window types to plot
for i=wty
    figure(i+100);
    v_windows(i,2520,'usqw');
    title(['sqrt ' get(get(gca,'Title'),'String')]);
end
tilefigs;


%% subCurve
% Below is a demonstration of the features of the |subCurve| function

%% Syntax
% |[VN]=subCurve(Vt,np,closeLoopOpt);|

%% Description
% The |subCurve| function can be used to increase the point density of the
% input curve by adding evenly spaced points between each of the curve
% segments.

%% Examples

clear; close all; clc;

%%
% PLOT SETTINGS
fontSize=15;
markerSize1=45;
lineWidth1=2;
lineWidth2=5;
lineWidth3=2;
faceAlpha=0.5;

%% Example: Linearly upsample an open ended curve with intermediate points

%%
% Simulating a curve
Vt=[0 0 0; 10 0 0; 5 10 0; 10 0 10; 0 10 10; ];

%%
% Upsampling the curve
np=3; %Number of desired intermediate points to be added
[VN]=subCurve(Vt,np); %Using subcurve to upsample curve

%%
% Plotting results
hf1=cFigure;
title('A linearly upsampled curve','FontSize',fontSize);
xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize); zlabel('Z','FontSize',fontSize);
hold on;

plotV(Vt,'k.-.','lineWidth',lineWidth1,'MarkerSize',markerSize1);
plotV(VN,'r.-','lineWidth',lineWidth1/2,'MarkerSize',markerSize1/2);

axis equal; view(3); axis tight;  grid on;  set(gca,'FontSize',fontSize);
drawnow;

%% Example: Linearly upsample a closed curve with intermediate points

%%
% Upsampling the curve
np=3; %Number of desired intermediate points to be added
closeLoopOpt=1; %Enable closed loop option
[VN]=subCurve(Vt,np,closeLoopOpt); %Using subcurve to upsample curve

%%
% Plotting results
hf1=cFigure;
title('A linearly upsampled curve with closed end condition','FontSize',fontSize);
xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize); zlabel('Z','FontSize',fontSize);
hold on;

plotV(Vt,'k.-.','lineWidth',lineWidth1,'MarkerSize',markerSize1);
plotV(VN,'r.-','lineWidth',lineWidth1/2,'MarkerSize',markerSize1/2);

axis equal; view(3); axis tight;  grid on;  set(gca,'FontSize',fontSize);
drawnow;

%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>

%%
% _*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/>.


% Run file to produce the Poisson experiment from the paper
%   S. Dolgov, D. Savostyanov,
%   "Alternating minimal energy methods for linear systems in higher
%   dimensions"

try
    maxNumCompThreads(1);
catch
    % Just skip. Sometimes if you specify -singleCompThread in the command
    % line, MATLAB will fail at maxNumCompThreads with scary, so tell him
    % it's okay.
end;

d = 16;
L = 6;

%!!! Last run: on dx360-11, E5-2670 0 @ 2.60GHz  !!!!!!!

tol = 1e-6;
nswp = 5;
kickrank = 4;

tol_gmres = 1e-3; % I would not set anything lower

% Matrix, RHS
A = tt_qlaplace_dd(L*ones(1,d))*(2^L+1)^2;
A = tt_reshape(A, 2^L*ones(d,2));
f = tt_ones(2^L, d);

% Reference solution
u_ex = amen_solve2(A, f, 1e-10, 'nswp', 30, 'max_full_size', 1500);

% Compare the solvers
% testdata format: {d,swp}
[u_svd,sd_svd] = amen_solve2(A, f, tol, 'x0', f, 'verb', 4, 'kicktype', 'svd', 'kickrank', kickrank, 'nswp', nswp, 'max_full_size', 50, 'trunc_norm', 'fro', 'ismex', true);
[u_als,sd_als] = amen_solve2(A, f, tol, 'x0', f, 'verb', 4, 'kicktype', 'als', 'kickrank', kickrank, 'nswp', nswp, 'max_full_size', 50, 'trunc_norm', 'fro', 'ismex', true);
[u_alstpz,sd_alstpz] = alstpz_solve(A,f,tol, 'x0',f, 'verb', 4, 'max_full_size', 50, 'kickrank', kickrank, 'nswp', nswp, 'kicktype', 'svd', 'symm', false, 'ismex', true);
[u_dmrg,sd_dmrg] = dmrg_solve3(A, f, tol, 'x0', f, 'kickrank', 0, 'min_dpow', 0.5, 'step_dpow', 0, 'step_drank', 0, 'max_full_size', 50, 'nswp', nswp, 'verb', 4, 'ismex', true, 'trunc_norm', 'fro', 'dirfilter', 1);
[U_gmres,td_gmres] = tt_gmres(core(A), core(f), tol_gmres, 4, 15, tol_gmres, tol_gmres, [], [], [], [], 3);

% Measure the A-errors
err0 = sqrt(dot(u_ex, A*u_ex));
errs_svd = zeros(d,nswp);
errs_als = zeros(d,nswp);
errs_alstpz = zeros(d,nswp);
errs_dmrg = zeros(d-1,nswp);
for i=1:nswp
    for j=1:d
        errs_svd(j,i) = sqrt(dot(sd_svd{2}{j,i}-u_ex, A*(sd_svd{2}{j,i}-u_ex)))/err0;
        errs_als(j,i) = sqrt(dot(sd_als{2}{j,i}-u_ex, A*(sd_als{2}{j,i}-u_ex)))/err0;
        errs_alstpz(j,i) = sqrt(dot(sd_alstpz{2}{j,i}-u_ex, A*(sd_alstpz{2}{j,i}-u_ex)))/err0;
        if (j<d)
            errs_dmrg(j,i) = sqrt(dot(sd_dmrg{2}{j,2*i-1}-u_ex, A*(sd_dmrg{2}{j,2*i-1}-u_ex)))/err0;
        end;
    end;
end;

% Prepare the data in the TikZ-readable form
%   1       2       3       4       5       6       7
% iter, t_alstpz, e_alstpz, t_svd, e_svd, t_als, e_als
dat_amens = [(1/d:1/d:nswp)', sd_alstpz{1}(:), errs_alstpz(:), sd_svd{1}(:), errs_svd(:), sd_als{1}(:), errs_als(:)];
dat_dmrg = [(1/(d-1):1/(d-1):nswp)', reshape(sd_dmrg{1}(1:d-1,1:2:nswp*2), [],1), errs_dmrg(:)];

% Process the GMRES output. It is different...
if (~isempty(whos('td_gmres')))
    iter_gmres = min([find(td_gmres{1}==0, 1), numel(td_gmres{1})+1])-1;
    err_gmres = zeros(iter_gmres, 1);
    for i=1:iter_gmres
        err_gmres(i) = sqrt(dot(tt_tensor(td_gmres{2}{i})-u_ex, A*(tt_tensor(td_gmres{2}{i})-u_ex)))/err0;
    end;
    dat_gmres = [(1:iter_gmres)', td_gmres{1}(1:iter_gmres)', err_gmres];
end;

% Draw 'em for humans
% iter
figure(1);
semilogy(dat_amens(:,1), dat_amens(:,[3,5,7]), dat_dmrg(:,1), dat_dmrg(:,3), dat_gmres(1:min(iter_gmres,nswp),1), dat_gmres(1:min(iter_gmres,nswp),3));
legend('alstpz', 'amen-svd', 'amen-als', 'dmrg', 'gmres');
% time
figure(2);
loglog(dat_amens(:,2), dat_amens(:,3), dat_amens(:,4), dat_amens(:,5), dat_amens(:,6), dat_amens(:,7), dat_dmrg(:,2), dat_dmrg(:,3), dat_gmres(:,2), dat_gmres(:,3));

% % Uncomment this if you want to draw the data elsewhere
% save('conv_lp16_amens.dat', '-ascii', 'dat_amens');
% save('conv_lp16_dmrg.dat', '-ascii', 'dat_dmrg');
% save('conv_lp16_gmres.dat', '-ascii', 'dat_gmres');


function check = fisk_check ( a, b, c )

%*****************************************************************************80
%
%% FISK_CHECK checks the parameters of the Fisk PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, C, the parameters of the PDF.
%    0.0 < B,
%    0.0 < C.
%
%    Output, logical CHECK, is true if the parameters are legal.
%
  if ( b <= 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FISK_CHECK - Fatal error!\n' );
    fprintf ( 1, '  B <= 0.\n' );
    check = 0;
    return
  end

  if ( c <= 0.0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'FISK_CHECK - Fatal error!\n' );
    fprintf ( 1, '  C <= 0.\n' );
    check = 0;
    return
  end

  check = 1;

  return
end


function issym = optiIsSymmetric(H)
%Returns true if a matrix is symmetric, using MATLAB routine if available

%Check if MATLAB version is available (>= R2014a)
if(~isempty(which('issymetric')))
    issym = issymmetric(H);
else %jc method
    if(nnz(triu(H,1) - tril(H,-1).') == 0)
        issym = true;
    else
        issym = false;
    end
end


function dpixc = makeavg(dpixc_ind, blinkmat, offset, avg)
% dpixc = makeavg(dpixc_ind, blinkmat, offset, avg)
% avg = 0 -> noise free image
if size(blinkmat,2) == 1 %one slice only
    dpixc_nonoise = dpixc_ind'*blinkmat + offset;
else
    dpixc_nonoise = array2im(dpixc_ind'*blinkmat + offset);
end
dpixc_dip = newim(dpixc_nonoise);
for ii=1:avg
    dpixc_dip = dpixc_dip + noise(dpixc_nonoise,'poisson');
end
if avg==0
    dpixc_dip = dpixc_nonoise;
end
navg=max(1,avg);
dpixc = double(dpixc_dip/navg);


function pass = test_max3(pref)
% Test @chebfun3/max3 command.

if ( nargin < 1 )
    pref = chebfunpref;
end
tol = 100*pref.cheb3Prefs.chebfun3eps;

% Check the MAX3 function for a cosine function
f = chebfun3(@(x,y,z) cos(x.*y.*z));
g = chebfun(@(x,y,z) 1 + 0*x);
h1 = max3(f);
pass(1) = norm(h1-g) < tol;

% Check the MAX function for a sine function
f = chebfun3(@(x,y,z) sin(x+y+z));
h2 = max3(f);
pass(2) = norm(h2-g) < tol;

end


classdef SuperEllipseRhoBoundsComputer < handle

    properties (Access = private)
       q
       txi
       mxMax
       myMax
       mxMin
       myMin
       superEllipse
    end

    methods (Access = public)

        function obj = SuperEllipseRhoBoundsComputer(cParams)
            obj.init(cParams);
        end

        function [rhoMin,rhoMax] = compute(obj)
            rhoMin = obj.computeRhoMin();
            rhoMax = obj.computeRhoMax();
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.q = cParams.q;
            obj.txi = cParams.txi;
            obj.mxMin = cParams.mxMin;
            obj.myMin = cParams.myMin;
            obj.mxMax = cParams.mxMax;
            obj.myMax = cParams.myMax;
            obj.superEllipse = SuperEllipseParamsRelator;
        end

        function rhoMin = computeRhoMin(obj)
            rhoMinMx = obj.rhoFromMx(obj.mxMax);
            rhoMinMy = obj.rhoFromMy(obj.myMax);
            rhoMin = max(rhoMinMx,rhoMinMy);
        end

        function rhoMax = computeRhoMax(obj)
            rhoMaxMx = obj.rhoFromMx(obj.mxMin);
            rhoMaxMy = obj.rhoFromMy(obj.myMin);
            rhoMax = min(rhoMaxMx,rhoMaxMy);
        end

        function rho = rhoFromMx(obj,mx)
            rho = obj.superEllipse.rhoFromMxAndTxi(mx,obj.txi,obj.q);
        end

        function rho = rhoFromMy(obj,my)
            rho = obj.superEllipse.rhoFromMyAndTxi(my,obj.txi,obj.q);
        end

    end

end


function d = dot_outer(g1,g2,varargin)
% outer inner product between two quaternions
%
% Input
%  g1, g2 - @quaternion
%
% Output
%  d - double
%
% Description
% cos angle(g1,g2)/2 = dot(g1,g2)

if ~isempty(g1) && ~isempty(g2)

  q1 = [g1.a(:) g1.b(:) g1.c(:) g1.d(:)];
  q2 = [g2.a(:) g2.b(:) g2.c(:) g2.d(:)];

  d = q1 * q2.';

else
    d = [];
end


%%
 %  Copyright (c) 2014, Facebook, Inc.
 %  All rights reserved.
 %
 %  This source code is licensed under the BSD-style license found in the
 %  LICENSE file in the root directory of this source tree. An additional grant
 %  of patent rights can be found in the PATENTS file in the same directory.
 %
 %%

function [ap,rec,prec] = get_precision_recall(scores,labels,num_truths)
if nargin==2
    num_truths=sum(labels==1);
end
[srt1,srtd]=sort(scores,'descend');
fp=cumsum(labels(srtd)==-1);
tp=cumsum(labels(srtd)==1);
rec=tp/num_truths;
prec=tp./(fp+tp);

%print_precrec(srt1,prec,rec);

mrec=[0 ; rec ; 1];
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
    mpre(i)=max(mpre(i),mpre(i+1));
end
i=find(mrec(2:end)~=mrec(1:end-1))+1;
ap=sum((mrec(i)-mrec(i-1)).*mpre(i));

end

function print_precrec(score,prec,rec)

for rc=0.1:0.1:0.9
    t = find(rec>rc,1);
    fprintf('recall: %4.2f  precision: %4.2f  score: %4.2f\n',rec(t),prec(t),score(t));
end

end


function tr = multitrace(A)
% Computes the traces of the 2D slices in a 3D matrix.
%
% function tr = multitrace(A)
%
% For a 3-dimensional matrix A of size n-by-n-by-N, returns a column vector
% tr of length N such that tr(k) = trace(A(:, :, k));
%
% See also: multiprod multitransp multiscale

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

    assert(ndims(A) <= 3, ...
           ['multitrace is only well defined for matrix arrays of 3 ' ...
            'or less dimensions.']);

	tr = diagsum(A, 1, 2);

end


function y2 = discrim_plot(discf,y,varargin)
% y2 = discrim_plot(discf,y,[new figure],[column to do partial corr plot of])
%
% Plots correlation or partial correlation
% Color codes by median split of y
%
% see also:
% cluster_discrim
% cluster_discrim_montage

dofig = 1; dopr = 0;
if length(varargin) > 0, dofig = varargin{1};,end
if length(varargin) > 1, dopr = varargin{2};,end

y2 = mediansplit(y);

if dopr
    [discf(:,1),y,r,p,rrob,prob] = partialcor(discf,y,dopr);
    fprintf(1,'\nCalculating partial correlation.\n')
end

if dofig, figure('Color','w');,end

plot_correlation_samefig(discf(:,1),y,[],'ko',0,1);
wh = find(y2>0); wh2 = find(y2<0);
hold on; plot(discf(wh2,1),y(wh2),'bo','MarkerSize',10,'LineWidth',2);
hold on; plot(discf(wh,1),y(wh),'ro','MarkerSize',10,'LineWidth',2);
xlabel('Discriminant function'); ylabel('Behavior');

return


%--------------------------------------------------------------------------------------------------------
% The system is created based on the principles described in the following papers
% [1] Li Xu, Jimmy SJ. Ren, Qiong Yan, Renjie Liao, Jiaya Jia, "Deep Edge-Aware Filters",
% The 32nd International Conference on Machine Learning (ICML 2015). Lille, France, July 6-11, 2015
% [2] Jimmy SJ. Ren and Li Xu, "On Vectorization of Deep Convolutional Neural Networks for Vision Tasks",
% The 29th AAAI Conference on Artificial Intelligence (AAAI-15). Austin, Texas, USA, January 25-30, 2015
%--------------------------------------------------------------------------------------------------------

addpath applications/deep_edge_aware_filters/
addpath applications/deep_edge_aware_filters/utility/
addpath applications/deep_edge_aware_filters/models/
addpath applications/deep_edge_aware_filters/images/
addpath utils/
addpath cuda/
addpath mem/
addpath layers/
addpath layers_adapters/
addpath pipeline/

global config;
% load the image you like
I = im2double(imread('applications/deep_edge_aware_filters/images/1.png'));

% to switch among filters, just comment out the previous 'model_path' and 'beta' and
% uncomment the new ones

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% L0 smooth filter, lambda = 0.02, kappa default
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
model_path = 'applications/deep_edge_aware_filters/models/L0_smooth.mat';
beta = 8.388608e+03 / 2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% bilateral filter, sigma_s = 7, sigma_r = 0.1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/bilateral.mat';
% beta = 8.388608e+02 / 7;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Region cov filter, radius = 10, ps = 4, sigma = 0.2, model = 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/regcov.mat';
% beta = 8.388608e+02 / 5;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% photoshop facet filter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/ps-facet.mat';
% beta = 8.388608e+02 / 5;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% shock filter, dt=0.1; h=1; iter=30; 'org'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/shock.mat';
% beta = 8.388608e+02 / 5;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% tsmooth filter, lambda=0.01, sigma=3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/tsmooth.mat';
% beta = 8.388608e+02 / 5;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% iterative bilateral filter, sigma_s = 7, sigma_r = 0.1, iter = 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/iterative_bilateral.mat';
% beta = 8.388608e+02 / 5;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% local laplacian filter, delta = 0.4, alpha = 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/local_lap_smooth.mat';
% beta = 8.388608e+03 / 2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% local laplacian filter, delta = 0.4, alpha = 0.25
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/local_lap_enhance.mat';
% beta = 8.388608e+03 / 2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% weighted median filter, 10, 25.5, 256, 256, 1, 'exp'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/wmf.mat';
% beta = 8.388608e+03 / 2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% WLS, default parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/wls.mat';
% beta = 8.388608e+02 / 5;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rolling guidance filter, default parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% model_path = 'applications/deep_edge_aware_filters/models/rolling.mat';
% beta = 8.388608e+03 / 2;

fprintf('preparing the network...\n');
prepare_net_filter(size(I, 1), size(I, 2), model_path);

fprintf('filtering the image...\n');
tic
S = I;

h_input = [diff(S,1,2), S(:,1,:) - S(:,end,:)];
v_input = [diff(S,1,1); S(1,:,:) - S(end,:,:)];
h_input = h_input * 2;
v_input = v_input * 2;
v_input = config.NEW_MEM(v_input);
h_input = config.NEW_MEM(h_input);

out = apply_net_filter(v_input, h_input);

v = out(:,:,:,1);
h = out(:,:,:,2);
v = v / 2;
h = h / 2;
h(:, end, :) = S(:,1,:) - S(:,end,:);
v(end, :, :) = S(1,:,:) - S(end,:,:);

filtered = grad_process(S, v, h, beta);
toc

figure;
imshow([I, filtered]); drawnow();


function varargout=var(varargin)
%VAR (overloaded)
%
% V = var(x)

x = varargin{1};

if nargin > 1 | min(size(x))>1
    error('SDPVAR/VAR only supports simple 1-D variance'),
end

switch length(x)
    case 1
        varargout{1} = x;
    otherwise
        x = reshape(x,length(x),1);
        m = sum(x)/length(x);
        varargout{1} = ((x-m)'*(x-m)) / (length(x) - 1);
end


%RG_ADDTICKS Label spectral locus
%
% RG_ADDTICKS() adds wavelength ticks to the spectral locus.
%
% See also XYCOLOURSPACE.

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

function rg_addticks(lam1, lam2, lamd)

    % well spaced points around the locus
    lambda = [460:10:540];
    lambda = [lambda 560:20:600];

    rgb = cmfrgb(lambda*1e-9);
    r = rgb(:,1)./sum(rgb')';
    g = rgb(:,2)./sum(rgb')';
    hold on
    plot(r,g, 'ko', 'MarkerFaceColor', 'k', 'MarkerSize', 6)
    hold off

    for i=1:numcols(lambda)
        text(r(i), g(i), sprintf('  %d', lambda(i)));
    end


function [FIT MCMC_LastState]=stat_ubsplsm(varargin)
% univariate b-spline smoothing with fPCA

% Y = cell array of [numChans x numChans x T] connectivities for each subject
% K = number of knots
% Q = number of fpca basis functions

% output:
% fit_distrib: cell array of [numChans x numChans x T x iterations]
%              posterior distribution for each subject

% Author: Tim Mullen and Wes Thompson, 2010-12, SCCN/INC, UCSD.
% Email:  tim@sccn.ucsd.edu

% This function is part of the Source Information Flow Toolbox (SIFT)
%
% 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, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

arg_define([0 1],varargin, ...
    arg_norep({'Y','TSData'},mandatory,[],sprintf(['Cell array of data to smooth.\n' ...
              'Generally, Y is a cell array where Y{i} is the T x 1 vector of time-varying (or freq-varying) connectivity for the kth channel pair of the sth subject.\n' ...
              'e.g. Y = {s1(1,1) s1(1,2) s1(1,3) ... s1(N,1) s1(N,2) s1(N,3) ... \n' ...
              '          s2(1,1) s2(1,2) s2(1,3) ... } \n'])), ...
    arg({'smoothingLayout','MatrixElementsToSmooth'},{'diagonals','off-diagonals'},{'diagonals','off-diagonals'},'Which parts of the matrix to smooth. Diagonals (e.g. auto-connectivity) and off-diagonals (e.g. cross-connectivity) will be smoothed separately','type','logical'), ...
    arg_sub({'mcmc_opts','MCMC'},{}, ...
    {...
        arg_sub({'mcmc_init','InitMCMC'},{},@stat_ubsplsm_init,'Initialize MCMC','suppress','verb') ...
        arg_sub({'mcmc_run','RunMCMC'},{},@stat_ubsplsm_mcmc,'MCMC runtime options','suppress','verb') ...
    },'Perform Markov Chain Monte Carlo estimation'), ...
    arg_norep({'MCMC_InitState'},struct([]),[],'Object containing initial state of Gibbs sampler. If supplied, this overrides mcmc_init'), ...
    arg({'verb','VerbosityLevel'},2,{int32(0) int32(1) int32(2)},'Verbosity level. 0 = no output, 1 = text, 2 = graphical') ...
    );

% initialize some vars
init_mcmc = isempty(g.MCMC_InitState);
nsubj=length(Y);

% determine the number of variables for each subject
m_i=zeros(nsubj,1);
for i=1:nsubj
    m_i(i)=size(Y{i},1);
end

% determining smoothing layout
smoothDiags     = ismember_bc('diagonals',g.smoothingLayout);
smoothOffDiags  = ismember_bc('off-diagonals',g.smoothingLayout);

%% get smoothed time-varying connectivity coefficients

% Diagonals and off-diagonals often have different variances, so we smooth
% them separately

% smooth diagonals
% -------------------------------------------------------------------------
if smoothDiags
    if verb==2
        multiWaitbar('Smoothing Diagonals','Reset', ...
                     hlp_getNextUniqueColor('reset'));
    end

    % extract self-connectivity for each subject
    CPairs=cell(sum(m_i),1);
    ind=0;
    for i=1:nsubj
        for j=1:m_i(i)
            ind=ind+1;
            CPairs{ind}=squeeze(Y{i}(j,j,:));
        end
    end

    % initialize MCMC
    if init_mcmc
        MCMC_InitState = stat_ubsplsm_init('Y',mcmc_opts.mcmc_init,'verb',verb);
    end

    % perform the smoothing
    [fit_diag MCMC_LastState.diag]=stat_ubsplsm_mcmc('Y',CPairs,mcmc_opts.mcmc_run, ...
                                        'verb',verb,'MCMC_InitState',MCMC_InitState.diag);
end

% smooth off-diagonals
% -------------------------------------------------------------------------
if smoothOffDiags
    if verb
        multiWaitbar('Smoothing Off-Diagonals',1/3);
    end

    % count the total number of pairs
    m_offdiag=sum(m_i.^2-m_i);

    % extract cross-connectivity off-diagonal
    % elements for each subject
    CPairs=cell(m_offdiag,1);
    ind=0;
    for i=1:nsubj
        for j1=1:m_i(i)
            for j2=1:m_i(i)
                if j1~=j2
                    ind=ind+1;
                    CPairs{ind}=squeeze(Y{i}(j1,j2,:));
                end
            end
        end
    end

    % initialize MCMC
    if init_mcmc
        MCMC_InitState = stat_ubsplsm_init('Y',mcmc_opts.mcmc_init,'verb',verb);
    end

    % perform the smoothing
    [fit_offdiag MCMC_LastState.offdiag]=stat_ubsplsm_mcmc('Y',CPairs,mcmc_opts.mcmc_run, ...
                                         'verb',verb,'MCMC_InitState',MCMC_InitState.offdiag);
end

% store data in [nchs x nchs x time x distribution]
if verb
    multiwaitbar('Creating final data matrices...',2/3);
end
FIT = cell(1,nsubj);
ind=0;
ind_diag = 0;
for i=1:nsubj
    FIT{i} = zeros(m_i(i),m_i(i),size(fit_offdiag,1),niterToKeep);

    for j1=1:m_i(i)
        for j2=1:m_i(i)
            if j1~=j2
                ind=ind+1;
                FIT{i}(j1,j2,:,:)=squeeze(fit_offdiag(:,ind,:));
            elseif niters~=0
                ind_diag = ind_diag+1;
                FIT{i}(j1,j2,:,:)=squeeze(fit_diag(:,ind_diag,:));
            end
        end
    end
end

if verb
    multiWaitbar('CloseAll');
    pause(0.1);
end


function [clust_num temp auto_sort] = find_temp(tree,clu,par) %,spikes,ipermut)

min_clus = par.min_clus;

c_ov = par.c_ov;
elbow_min = par.elbow_min;
clu = clu(1:end-1,3:end)+1; %first dim temp

y = tree(1:end,5);
maxdiff = max(diff(tree(1:end,6:end)),[],2);
maxdiff(maxdiff<0)=0;
prop = (y(2:end)+maxdiff.*(maxdiff>0))./y(1:end-1);
aux = find(prop<elbow_min,1,'first')+1; %percentaje of the rest

% The next if removes the particular case where just a class is found at the
% lowest temperature and with just a small change the rest appears
% all together at the next temperature
if ~isempty(aux) && par.mintemp==0 && aux==2
    aux = find(prop(2:end)<elbow_min,1,'first')+2; %percentaje of the rest
end

tree = tree(1:end-1,5:end);
clus = zeros(size(tree));
clus(tree(:,:) >= min_clus)=1; %only check the ones that cross the thr

dt = diff(tree);
clus = clus & [ones(size(clus(1,:)));dt(1:end,:)>min_clus];

for ii = 1:size(clus,1)
    detect = find(clus(ii,:),1,'last');
    if ~isempty(detect)
        clus(ii,1:detect)=1;
    end
end

auto_sort.elbow = size(tree,1);
if ~isempty(aux)
    clus(aux:end,1:end)=0;
    auto_sort.elbow = aux;
end
auto_sort.peaks = clus;

for ti = size(clus,1):-1:1
    detect = find(clus(ti,:));
    for ci = 1:length(detect) %the clusters removed aren't detected
        cl = (clu(ti,:) == detect(ci));
        for tj = ti-1:-1:1
            toremove = find(clus(tj,:));
            for j = 1:length(toremove)
                totest = (clu(tj,:) == toremove(j));
                if nnz(cl & totest)/min(nnz(totest),nnz(cl)) >= c_ov
                    clus(tj,toremove(j))=0;
                end
            end
        end
    end
end

[temp clust_num]=find(clus);


function out = EN_wentropy(y,whaten,p)
% EN_wentropy   Entropy of time series using wavelets.
%
% Uses the wentropy function from Matlab's Wavelet toolbox.
%
%--INPUTS:
% y, the input time series
% whaten, the entropy type:
%               'shannon',
%               'logenergy',
%               'threshold' (with a given threshold),
%               'sure' (with a given parameter).
%               (see the wentropy documentaiton for information)
% p, the additional parameter needed for threshold and sure entropies
%
%---NOTE:
% It seems likely that this implementation of wentropy is nonsense.

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This function 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/>.
% ------------------------------------------------------------------------------

% ------------------------------------------------------------------------------
%% Check that a Wavelet Toolbox license is available:
% ------------------------------------------------------------------------------
BF_CheckToolbox('wavelet_toolbox')

% ------------------------------------------------------------------------------
% Check inputs
% ------------------------------------------------------------------------------
if nargin < 2 || isempty(whaten)
    whaten = 'shannon'; % default
end

N = length(y); % time-series length

switch whaten
	case 'shannon' % Shannon entropy
		out = wentropy(y,'shannon')/N; % scales with N for large N

	case 'logenergy' % Log Energy entropy
		out = wentropy(y,'log energy')/N; % scales with N for large N

    case 'threshold' % Magnitude of the signal greater than some value
        out = wentropy(y,'threshold',p)/N;

    case 'sure'
        % Equivalent to threshold entropy?
        out = wentropy(y,'sure',p)/N;

    otherwise
        error('Unknown entropy type ''%s''', whaten);
end

end


function stackOut = ComputeLDRStackHistogram(stack)
%
%       stackOut = ComputeLDRStackHistogram(stack)
%
%
%        Input:
%           -dir_name: the folder name where the stack is stored as a
%           series of LDR images.
%           -format: an LDR format for reading LDR images in the current directory
%
%        Output:
%           -stackOut: a stack of LDR image histograms
%
%     Copyright (C) 2013  Francesco Banterle
%
%     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/>.
%

[~, ~, col, n] = size(stack);

stackOut = zeros(256, col, n);

for i=1:n
    %store in the stack
    for j=1:col

        tmp = stack(:,:,j,i);

        if(isa(tmp, 'double') || isa(tmp, 'single'))
            tmp = uint8(ClampImg(round(tmp * 255), 0.0, 255.0));
        end

        if(isa(tmp, 'uint16'))
            tmp = uint8(ClampImg(round(tmp / 255), 0, 255));
            warning('Is this a 16-bit image? The maximum is set to 65535.');
        end

        stackOut(:,j,i) = imhist(tmp);
    end
end

end


function sphere_llt_grid_line_count_test ( )

%*****************************************************************************80
%
%% SPHERE_LLT_GRID_LINE_COUNT_TEST tests SPHERE_LLT_GRID_LINE_COUNT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 April 2015
%
%  Author:
%
%    John Burkardt
%
  lat_num = 3;
  long_num = 4;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'SPHERE_LLT_GRID_LINE_COUNT_TEST\n' );
  fprintf ( 1, '  SPHERE_LLT_GRID_LINE_COUNT counts the lines used for a\n' );
  fprintf ( 1, '  grid based on triangles defined by latitude and longitude\n' );
  fprintf ( 1, '  lines on a sphere in 3D.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '     LAT_NUM    LONG_NUM   LINE_NUM\n' );
  for lat_num = 1 : 2 : 17
    fprintf ( 1, '\n' );
    long_num = 1;
    for long_log = 1 : 4
      long_num = long_num * 2;
      line_num = sphere_llt_grid_line_count ( lat_num, long_num );
      fprintf ( 1, '  %8d  %8d  %8d\n', lat_num, long_num, line_num );
    end
  end

  return
end


function indx = i4vec_search_binary_d ( n, a, b )

%*****************************************************************************80
%
%% I4VEC_SEARCH_BINARY_D searches a descending sorted I4VEC.
%
%  Discussion:
%
%    Binary search is used.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Algorithm 1.9,
%    Donald Kreher and Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998, page 26.
%
%  Parameters:
%
%    Input, integer N, the number of elements in the vector.
%
%    Input, integer A(N), the array to be searched.  A must
%    be sorted in descending order.
%
%    Input, integer B, the value to be searched for.
%
%    Output, integer INDX, the result of the search.
%    -1, B does not occur in A.
%    I, A(I) = B.
%
  indx = -1;

  low = 1;
  high = n;

  while ( low <= high )

    mid = floor ( ( low + high ) / 2 );

    if ( a(mid) == b )
      indx = mid;
      break
    elseif ( b < a(mid) )
      low = mid + 1;
    elseif ( a(mid) < b )
      high = mid - 1;
    end

  end

  return
end


function [Jul1,Jul2]=UTC2GPS(Jul1,Jul2)
%%UTC2TCG Convert from universal coordinated time (UTC) given as a two-
%         part pseudo-Julian date to the timescale used by the Global
%         Positioning System (GPS), represented as a two-part Julian date.
%
%INPUTS: Jul1, Jul2 Two parts of a pseudo-Julian date given in UTC. The
%                   units of the date are days. The full date is the sum of
%                   both terms. The date is broken into two parts to
%                   provide more bits of precision. It does not matter how
%                   the date is split.
%
%OUTPUTS: Jul1, Jul2 The time as a Julian date in GPS Time.
%
%The UTC date is only pseudo-Julian, because there is not a fixed number
%of seconds in a Julian day. The convention used in the IAU standard is
%that the Julian day matches the UTC day regardless of whether the UTC day
%is 86399, 86400 or 86401 SI seconds (depending on the presence of leap
%seconds).
%
%UTC began at 1960 January 1.0 (JD 2436934.5) and this function should not
%be called with an earlier date.
%
%Many temporal coordinate systems standards are compared in [1].
%
%REFERENCES:
%[1] D. F. Crouse, "An Overview of Major Terrestrial, Celestial, and
%    Temporal Coordinate Systems for Target Tracking," Formal Report, Naval
%    Research Laboratory, no. NRL/FR/5344--16-10,279, 10 Aug. 2016, 173
%    pages.
%
%October 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

[Jul1,Jul2]=UTC2TAI(Jul1,Jul2);
[Jul1,Jul2]=TAI2GPS(Jul1,Jul2);
end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


classdef S2VectorFieldTri < S2VectorField
% a class represeneting a function on the sphere

  properties
    tri       % S2Triangulation
    values = vector3d  % function values
  end

  properties (Dependent = true)
    vertices
    antipodal
  end

  methods

    function sVF = S2VectorFieldTri(nodes,values)
      % initialize a spherical vector field

      if nargin == 0, return; end

      if isa(nodes,'function_handle')
        n = equispacedS2Grid('resolution',1.5*degree);
        values = nodes(n);
        nodes = n;
      end

      if isa(nodes,'S2Triangulation')
        sVF.tri = nodes;
      else
        sVF.tri = S2Triangulation(nodes);
      end

      sVF.values = values;

    end

    function v = get.vertices(S2F)
      v = S2F.tri.vertices;
    end

    function v = get.antipodal(S2F)
      v = S2F.tri.antipodal;
    end

    function S2F = set.vertices(S2F,v)
      if ~isempty(S2F.values), S2F.values = S2F.eval(v); end
      S2F.tri.vertices = v;
      S2F.tri.update;
    end

  end

end


function t = toeplitz( c, r )

%   Disciplined convex/geometric programming information for TOEPLITZ:
%      TOEPLITZ imposes no convexity restrictions on its arguments.
%      Instead of using the TOEPLITZ function, however, consider
%      creating a matrix variable using the 'toeplitz' keyword; e.g.
%          variable X(5,5) toeplitz;

%
% Check arguments
%

narginchk(1,2);
if nargin < 2,
    c    = vec( c );
    m    = length( c );
    p    = m;
    x    = [ cvx_subsref( c, p : -1 : 1 ) ; conj( cvx_subsref( c, 2 : p ) ) ];
else
    temp = cvx_subsref( r, 1 ) - cvx_subsref( c, 1 );
    if ~cvx_isconstant( temp ) || cvx_constant( temp ) ~= 0,
        warning('MATLAB:toeplitz:DiagonalConflict',['First element of ' ...
               'input column does not match first element of input row. ' ...
               '\n         Column wins diagonal conflict.'])
    end
    r = vec( r );
    c = vec( c );
    p = length( r );
    m = length( c );
    x = [ cvx_subsref( r, p : -1 : 2 ) ; c ];
end

%
% Construct matrix
%

cidx = ( 0 : m - 1 )';
ridx = p : -1 : 1;
t    = cidx( :, ones( p, 1 ) ) + ridx( ones( m, 1 ) , : );
t    = reshape( cvx_subsref( x, t ), size( t ) );

% Copyright 2005-2016 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function normal_ms_cdf_test ( )

%*****************************************************************************80
%
%% NORMAL_MS_CDF_TEST tests NORMAL_MS_CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 March 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'NORMAL_MS_CDF_TEST\n' );
  fprintf ( 1, '  NORMAL_MS_CDF evaluates the CDF\n' );
  fprintf ( 1, '  for the Normal MS distribution.\n' );

  mu = 100.0;
  sigma = 15.0;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PDF parameter MU =    %14f\n', mu );
  fprintf ( 1, '  PDF parameter SIGMA = %14f\n', sigma );

  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, '       X            CDF      CDF_INV\n' );
  fprintf ( 1, '\n' );

  for i = -20 : 20
    x = mu + sigma * i / 10.0;
    cdf = normal_ms_cdf ( x, mu, sigma );
    x2 = normal_ms_cdf_inv ( cdf, mu, sigma );
    fprintf ( 1, '  %14g  %14g  %14g\n', x, cdf, x2 );
  end

  return
end


% SUMMARY:  Update p_start, A
%           This is common for multinominal-HMM, Gauss-HMM, GMM-HMM, etc.
% AUTHOR:   QIUQIANG KONG
% Created:  14-11-2015
% Modified: 17-11-2015 Add annotation
% -----------------------------------------------------------
% input:
%   Gamma   p(zn|X^{r})
%   Ksi     p(zn-1,zn|X^{r})
% output:
%   p_start p(z1)
%   A       p(zn|zn-1)
% ===========================================================
function [p_start, A] = M_step_common(Gamma, Ksi)
    obj_num = length(Gamma);
    Q = size(Gamma{1},2);

    % calculate p_start
    p_start_numer = zeros(1,Q);
    for r = 1:obj_num
        p_start_numer = p_start_numer + Gamma{r}(1,:);
    end
    p_start = p_start_numer / sum(p_start_numer);

    % calculate A
    A_numer = zeros(Q,Q);
    for r = 1:obj_num
        A_numer = A_numer + reshape(sum(Ksi{r},1), Q, Q);
    end
    A = bsxfun(@rdivide, A_numer, sum(A_numer,2));
end


 function sls = de_ftab_sls(varargin)
%function sls = de_ftab_sls(varargin)
%|
%| Determine structure that characterizes the "s" limits for polyenergetic CT,
%| where s_l is a line integral through the lth material type, l=1...L.
%| L is the number of material components.
%|
%| in
%| option
%|	'sl'	cell{LL} sample thicknesses for each of LL materials
%|	'n'	[L,1]	number of samples of lth material integrals
%|			default: [50 30] or [length(sl{ll})]
%|	'max'	[L,1]	maximum material density line integrals, units: g/cm^2
%|			default: [45 43] or [max(sl{ll})]
%|	'min'	[L,1]	minimum material density line integrals, units: g/cm^2
%|			default: [0] or [min(sl{ll})]
%|
%| out
%|	sls	strum
%|		data:
%|		sls.sl,n,max,min	see above
%|		methods:
%|		.sll			[n1,n2,...,nL,L] ndgrid of sl{*} values
%|
%| Copyright 2008-6-15, Jeff Fessler, University of Michigan

if nargin == 1 && streq(varargin{1}, 'test')
	de_ftab_sls_test
return
end
if ~nargout, ir_usage, end

sls.sl = {};
sls.n = [];
sls.min = [];
sls.max = [];

sls = vararg_pair(sls, varargin);

[sls.sl sls.n sls.min sls.max] = ...
	de_ftab_sls_do(sls.sl, sls.n, sls.min, sls.max);

sls = strum(sls, {'sll', @de_ftab_sls_sll, '()'});

% de_ftab_sls_sll()
function out = de_ftab_sls_sll(sls, varargin)
sll = ndgrid_jf('mat', sls.sl);
out = sll(varargin{:});

% de_ftab_sls_do()
function [sl, s_n, s_min, s_max] = de_ftab_sls_do(sl, s_n, s_min, s_max)

% number of samples of the material integrals "s"
if isempty(s_n)
	if isempty(sl)
		s_n = [45 43];
%		s_n = [51 31]; % makes plot_jac look nice
	else
		for ll=1:length(sl)
			s_n(1,ll) = length(sl{ll});
		end
	end
end

% minimum material "integrals"
if isempty(s_min)
	if isempty(sl)
		s_min = [0 0];
	else
		for ll=1:length(sl)
			s_min(1,ll) = min(sl{ll});
		end
	end
end

% maximum material "integrals"
if isempty(s_max)
	if isempty(sl)
		% soft max: 50cm * 1g/cc
		% bone max: 15cm * 2g/cc (for now)
		s_max = [50 30];
	else
		for ll=1:length(sl)
			s_max(1,ll) = max(sl{ll});
		end
	end
end

if isempty(sl)
	for ll=1:length(s_n)
		sl{ll} = linspace(s_min(ll), s_max(ll), s_n(ll))';
	end
end

% de_ftab_sls_test
function de_ftab_sls_test
sls = de_ftab_sls;
pr 'size(sls.sll)'
pr 'size(sls.sll(:,:,1))'


function img = flowToColor(flow, varargin)

%  flowToColor(flow, maxFlow) flowToColor color codes flow field, normalize
%  based on specified value,
%
%  flowToColor(flow) flowToColor color codes flow field, normalize
%  based on maximum flow present otherwise

%   According to the c++ source code of Daniel Scharstein
%   Contact: schar@middlebury.edu

%   Author: Deqing Sun, Department of Computer Science, Brown University
%   Contact: dqsun@cs.brown.edu
%   $Date: 2007-10-31 18:33:30 (Wed, 31 Oct 2006) $

% Copyright 2007, Deqing Sun.
%
%                         All Rights Reserved
%
% Permission to use, copy, modify, and distribute this software and its
% documentation for any purpose other than its incorporation into a
% commercial product is hereby granted without fee, provided that the
% above copyright notice appear in all copies and that both that
% copyright notice and this permission notice appear in supporting
% documentation, and that the name of the author and Brown University not be used in
% advertising or publicity pertaining to distribution of the software
% without specific, written prior permission.
%
% THE AUTHOR AND BROWN UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
% INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY
% PARTICULAR PURPOSE.  IN NO EVENT SHALL THE AUTHOR OR BROWN UNIVERSITY BE LIABLE FOR
% ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

UNKNOWN_FLOW_THRESH = 1e9;
UNKNOWN_FLOW = 1e10;            %

[height widht nBands] = size(flow);

if nBands ~= 2
    error('flowToColor: image must have two bands');
end;

u = flow(:,:,1);
v = flow(:,:,2);

maxu = -999;
maxv = -999;

minu = 999;
minv = 999;
maxrad = -1;

% fix unknown flow
idxUnknown = (abs(u)> UNKNOWN_FLOW_THRESH) | (abs(v)> UNKNOWN_FLOW_THRESH) ;
u(idxUnknown) = 0;
v(idxUnknown) = 0;

maxu = max(maxu, max(u(:)));
minu = min(minu, min(u(:)));

maxv = max(maxv, max(v(:)));
minv = min(minv, min(v(:)));

rad = sqrt(u.^2+v.^2);
maxrad = max(maxrad, max(rad(:)));

fprintf('max flow: %.4f flow range: u = %.3f .. %.3f; v = %.3f .. %.3f\n', maxrad, minu, maxu, minv, maxv);

if isempty(varargin) ==0
    maxFlow = varargin{1};
    if maxFlow > 0
        maxrad = maxFlow;
    end;
end;

u = u/(maxrad+eps);
v = v/(maxrad+eps);

% compute color

img = computeColor(u, v);

% unknown flow
IDX = repmat(idxUnknown, [1 1 3]);
img(IDX) = 0;


function vTrunc= util_trunc(v, digits, policy)
%vTrunc= util_trunc(v, <digits=4, policy>)
%
% Truncates the number v, digits gives the amount of digits after the
% comma.
%
% policy is 'floor', 'ceil', or 'round'

if ~exist('digits', 'var'), digits=4; end
if ~exist('policy','var'), policy='round'; end

a= 10^digits;
vTrunc= feval(policy, a*v)/a;


function example ( n )

%*****************************************************************************80
%
%% EXAMPLE is a small example of the return problem.
%
%  Discussion:
%
%    POTENTIAL1 and POTENTIAL2 are identical, except that POTENTIAL1
%    includes a RETURN statement.
%
%    Both functions are called many times.  Somehow, the overhead of
%    the RETURN statement dominates the computation time.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'Call potential1:\n' );
  fprintf ( 1, '\n' );

  tic
  for ii = 1 : n
    vx = potential1 ( 1, 1, 0.5, 0.5 );
  end
  toc

  fprintf ( 1, '\n' );
  fprintf ( 1, 'Call potential2:\n' );
  fprintf ( 1, '\n' );

  tic
  for ii = 1 : n
    vx = potential2 ( 1, 1, 0.5, 0.5 );
  end
  toc

  return
end

function v = potential1 ( a, b, x, y )

%*****************************************************************************80
%
%% POTENTIAL1 evaluates the potential function V(X,Y).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 August 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the parameters that define the ellipse.
%
%    Input, real X, Y, the coordinates of the point.
%
%    Output, real V, the value of the potential function.
%
  v = 2.0 * ( ( x / a^2 )^2 + ( y / b^2 )^2 ) + 1.0 / a^2 + 1.0 / b^2;

  return
end

function v = potential2 ( a, b, x, y )

%*****************************************************************************80
%
%% POTENTIAL2 evaluates the potential function V(X,Y).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 August 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A, B, the parameters that define the ellipse.
%
%    Input, real X, Y, the coordinates of the point.
%
%    Output, real V, the value of the potential function.
%
  v = 2.0 * ( ( x / a^2 )^2 + ( y / b^2 )^2 ) + 1.0 / a^2 + 1.0 / b^2;

% return
end


% Plot all time series variables that have a certain
% 'standard_name' in a specified bounding box and time period

open_url='http://geoport.whoi.edu/gi-cat/services/opensearch';
var='sea_water_temperature'; %free text search string
time_var='time'; %time coordinate variable
bbox =[-180 180 0 90];  % [lon_min lon_max lat_min lat_max]
start=[1990 1 1 0 0 0]; %start
stop =[2000 1 1 0 0 0];  %stop

% OpenSearch query
q.endpoint = open_url
q.bbox = sprintf('%d,%d,%d,%d',bbox([1 3 2 4]));
q.time_start=datestr(start,'yyyy-mm-ddTHH:MM:SSZ')% convert to ISO
q.time_end=datestr(stop,'yyyy-mm-ddTHH:MM:SSZ')% convert to ISO
q.string_text=var;
[links,params]=opensearch(q);   % make the query

dap=links2dap(links); % find only the OPeNDAP links

for i=1:length(dap);
    figure(i);
    nc=cfdataset(dap{i});
    vars=nc.variables;
    for j=1:length(vars); %loop through variables to find standard_names
        std_name=value4key(nc.attributes(vars{j}),'standard_name');
        if strcmp(std_name,var),
            vart=nc.variable(vars{j});
            jd=nc.time(time_var);
            ii=date_index(jd,start,stop);  % find indices of dates between start/stop
            jd=jd(ii);
            t=vart.data(ii);  %extact these indices from dataset
            plot(jd,t);
            ylabel(sprintf('%s [%s]',var,value4key(vart.attributes,'units')),...
                'interpreter','none');
            datetick
            grid;
            title(value4key(nc.attributes,'title'))
        end
    end
end


function [points, pos, faceInds] = intersectEdgeMesh3d(edge, varargin)
%INTERSECTEDGEMESH3D Intersection points of a 3D edge with a mesh.
%
%   INTERS = intersectEdgeMesh3d(EDGE, VERTICES, FACES)
%   Compute the intersection points between a 3D edge and a 3D mesh defined
%   by vertices and faces.
%
%   [INTERS, POS, INDS] = intersectEdgeMesh3d(EDGE, VERTICES, FACES)
%   Also returns the position of each intersection point on the input edge,
%   and the index of the intersected faces.
%   For edges, the values of POS are expected to be comprised between 0 and
%   1.
%
%   Example
%     [V, F] = createCube;
%     edge = [-1 0.5 0.5  +3 0.5 0.5];
%     pts = intersectEdgeMesh3d(edge, V, F)
%     pts =
%         1.0000    0.5000    0.5000
%              0    0.5000    0.5000
%
%   See also
%     meshes3d, interesectLineMesh3d, triangulateFaces
%

% ------
% Author: David Legland
% E-mail: david.legland@inrae.fr
% Created: 2021-02-24, using Matlab 9.9.0.1570001 (R2020b) Update 4
% Copyright 2021-2022 INRA - Cepia Software Platform

% perform computation on supporting line
line = edgeToLine3d(edge);
[points, pos, faceInds] = intersectLineMesh3d(line, varargin{:});

% identifies intersection points within parameterization bounds
inds = pos >= 0 & pos <= 1;

% select relevant results
points = points(inds, :);


function [samples, energies, diagn] = metrop(f, x, options, gradf, varargin)
%METROP	Markov Chain Monte Carlo sampling with Metropolis algorithm.
%
%	Description
%	 SAMPLES = METROP(F, X, OPTIONS) uses the Metropolis algorithm to
%	sample from the distribution P ~ EXP(-F), where F is the first
%	argument to METROP.   The Markov chain starts at the point X and each
%	candidate state is picked from a Gaussian proposal distribution and
%	accepted or rejected according to the Metropolis criterion.
%
%	SAMPLES = METROP(F, X, OPTIONS, [], P1, P2, ...) allows additional
%	arguments to be passed to F().  The fourth argument is ignored, but
%	is included for compatibility with HMC and the optimisers.
%
%	[SAMPLES, ENERGIES, DIAGN] = METROP(F, X, OPTIONS) also returns a log
%	of the energy values (i.e. negative log probabilities) for the
%	samples in ENERGIES and DIAGN, a structure containing diagnostic
%	information (position and acceptance threshold) for each step of the
%	chain in DIAGN.POS and DIAGN.ACC respectively.  All candidate states
%	(including rejected ones) are stored in DIAGN.POS.
%
%	S = METROP('STATE') returns a state structure that contains the state
%	of the two random number generators RAND and RANDN. These are
%	contained in fields randstate,  randnstate.
%
%	METROP('STATE', S) resets the state to S.  If S is an integer, then
%	it is passed to RAND and RANDN. If S is a structure returned by
%	METROP('STATE') then it resets the generator to exactly the same
%	state.
%
%	The optional parameters in the OPTIONS vector have the following
%	interpretations.
%
%	OPTIONS(1) is set to 1 to display the energy values and rejection
%	threshold at each step of the Markov chain. If the value is 2, then
%	the position vectors at each step are also displayed.
%
%	OPTIONS(14) is the number of samples retained from the Markov chain;
%	default 100.
%
%	OPTIONS(15) is the number of samples omitted from the start of the
%	chain; default 0.
%
%	OPTIONS(18) is the variance of the proposal distribution; default 1.
%
%	See also
%	HMC
%

%	Copyright (c) Ian T Nabney (1996-2001)

if nargin <= 2
  if ~strcmp(f, 'state')
    error('Unknown argument to metrop');
  end
  switch nargin
    case 1
      % Return state of sampler
      samples = get_state(f);	% Function defined in this module
      return;
    case 2
      % Set the state of the sampler
      set_state(f, x);		% Function defined in this module
      return;
  end
end

if 0
seed = 42;
randn('state', seed);
rand('state', seed)
end

display = options(1);
if options(14) > 0
  nsamples = options(14);
else
  nsamples = 100;
end
if options(15) >= 0
  nomit = options(15);
else
  nomit = 0;
end
if options(18) > 0.0
  std_dev = sqrt(options(18));
else
  std_dev = 1.0;   % default
end
nparams = length(x);

% Set up string for evaluating potential function.
f = fcnchk(f, length(varargin));

samples = zeros(nsamples, nparams);		% Matrix of returned samples.
if nargout >= 2
  en_save = 1;
  energies = zeros(nsamples, 1);
else
  en_save = 0;
end
if nargout >= 3
  diagnostics = 1;
  diagn_pos = zeros(nsamples, nparams);
  diagn_acc = zeros(nsamples, 1);
else
  diagnostics = 0;
end

% Main loop.
n = - nomit + 1;
Eold = feval(f, x, varargin{:});	% Evaluate starting energy.
nreject = 0;				% Initialise count of rejected states.
while n <= nsamples

  xold = x;
  % Sample a new point from the proposal distribution
  x = xold + randn(1, nparams)*std_dev;
  %fprintf('netlab propose: xold = %5.3f,%5.3f, xnew = %5.3f,%5.3f\n',...
  %	xold(1), xold(2), x(1), x(2));

  % Now apply Metropolis algorithm.
  Enew = feval(f, x, varargin{:});	% Evaluate new energy.
  a = exp(Eold - Enew);			% Acceptance threshold.
  if (diagnostics & n > 0)
    diagn_pos(n,:) = x;
    diagn_acc(n,:) = a;
  end
  if (display > 1)
    fprintf(1, 'New position is\n');
    disp(x);
  end

  r = rand(1);
  %fprintf('netlab: n=%d, a=%f/%f=%5.3f (%5.3f), r=%5.3f\n',...
  %	  n, exp(-Enew), exp(-Eold), a, exp(-Enew)/exp(-Eold), r);
  if a > r	% Accept the new state.
    Eold = Enew;
    if (display > 0)
      fprintf(1, 'Finished step %4d  Threshold: %g\n', n, a);
    end
  else			% Reject the new state
    if n > 0
      nreject = nreject + 1;
    end
    x = xold;	% Reset position
    if (display > 0)
      fprintf(1, '  Sample rejected %4d.  Threshold: %g\n', n, a);
    end
  end
  if n > 0
    samples(n,:) = x;			% Store sample.
    if en_save
      energies(n) = Eold;		% Store energy.
    end
  end
  n = n + 1;
end

if (display > 0)
  fprintf(1, '\nFraction of samples rejected:  %g\n', ...
          nreject/(nsamples));
end

if diagnostics
  diagn.pos = diagn_pos;
  diagn.acc = diagn_acc;
end

% Return complete state of the sampler.
function state = get_state(f)

state.randstate = rand('state');
state.randnstate = randn('state');
return

% Set state of sampler, either from full state, or with an integer
function set_state(f, x)

if isnumeric(x)
  rand('state', x);
  randn('state', x);
else
  if ~isstruct(x)
    error('Second argument to metrop must be number or state structure');
  end
  if (~isfield(x, 'randstate') | ~isfield(x, 'randnstate'))
    error('Second argument to metrop must contain correct fields')
  end
  rand('state', x.randstate);
  randn('state', x.randnstate);
end
return


function ll = gpsimMapLogLikelihood(model, df)

% GPSIMMAPLOGLIKELIHOOD Compute the log likelihood of a GPSIMMAP model.
% FORMAT
% DESC computes the log likelihood of the given Gaussian process
% for use in a single input motif protein network.
% ARG model : the model for which the log likelihood is computed.
% RETURN ll : the log likelihood of the data set.
%
% SEEALSO : gpsimMapCreate, gpsimMapLogLikeGradient, gpsimMapObjective
%
% COPYRIGHT : Neil D. Lawrence, 2006
%
% MODIFIED : Pei Gao, 2008

% SHEFFIELDML

numData = length(model.t);

% ll = model.f'*model.invK*model.f ...
%       + log(det(eye(size(model.W))+model.K*model.W));
ll = model.f'*model.invK*model.f ...
    - model.logDetCovf + model.logDetK;

if isfield(model, 'includeNoise') && model.includeNoise
  noiseMat = ones(length(model.t), 1)*model.noiseVar;
  yvar = model.yvar + noiseMat;
else
  yvar = model.yvar;
end

for i = 1:numData
  for j = 1:model.numGenes
    ind = i + (j-1)*numData;
    beta_ij = 1/yvar(ind);
    factor = (model.ypred(model.times_index(i), j)...
              - model.y(ind));
    ll = ll + factor*factor*beta_ij - log(beta_ij);
  end
end

ll = ll + numData*model.numGenes*log(2*pi);

ll = -.5*ll;


function fmridat = rescale(fmridat, meth, varargin)
% Rescales data in an fmri_data object
% Data is observations x images, so operating on the columns operates on
% images, and operating on the rows operates on voxels (or variables more
% generally) across images.
%
% :Usage:
% ::
%
%    fmridat = rescale(fmridat, meth)
%
% :Inputs:
%
%   **Methods:**
%     Rescaling of voxels
%     - centervoxels        subtract voxel means
%     - zscorevoxels        subtract voxel means, divide by voxel std. dev
%     - rankvoxels          replace values in each voxel with rank across images
%
%                           *Note: these methods must exclude invalid (0 or
%                           NaN) voxels image-wise. Some images (but not others) in an
%                           object may be missing some voxels.
%
%     Rescaling of images
%     - centerimages        subtract image means
%     - zscoreimages        subtract image means, divide by image std. dev
%
%                           *Note: these methods must exclude invalid (0 or
%                           NaN) voxels image-wise. Some images (but not others) in an
%                           object may be missing some voxels.
%
%     - l2norm_images       divide each image by its l2 norm, multiply by sqrt(n valid voxels)
%     - divide_by_csf_l2norm  divide each image by CSF l2 norm. requires MNI space images for ok results!
%     - rankimages          rank voxels within image;
%     - csf_mean_var        Subtract mean CSF signal from image and divide by CSF variance. (Useful for PE
%                               maps where CSF mean and var should be 0).
%
%     Other procedures
%     - windsorizevoxels    Winsorize extreme values to 3 SD for each image (separately) using trimts
%     - percentchange       Scale each voxel (column) to percent signal change with a mean of 100
%                           based on smoothed mean values across space (cols), using iimg_smooth_3d
%     - tanh                Rescale variables by hyperbolic tangent function
%                           this will shrink the tails (and outliers) towards the mean,
%                           making subsequent algorithms more robust to
%                           outliers. Affects normality of distribution.
%
% Appropriate for multi-session (time series) only:
%     - session_global_percent_change
%     - session_global_z
%     - session_multiplicative
%
% See also fmri_data.preprocess

switch meth

    case 'centervoxels'

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        fmridat.dat(ismissing) = NaN;

        m = nanmean(fmridat.dat');
        fmridat.dat = (fmridat.dat' - m)';  % Note: Sizes are wrong without repmat, but Matlab 2020b at least figures this out.

        % Old - this does not handle different missing voxels in different images
        fmridat.dat = scale(fmridat.dat', 1)';

        fmridat.dat(ismissing) = 0;  % Replace with 0 for compatibility with image format

        fmridat.history{end+1} = 'Centered voxels (rows) across images';

    case 'zscorevoxels'

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        fmridat.dat(ismissing) = NaN;

        m = nanmean(fmridat.dat');
        s = nanstd(fmridat.dat');
        fmridat.dat = ((fmridat.dat' - m) ./ s)';  % Note: Sizes are wrong without repmat, but Matlab 2020b at least figures this out.

        fmridat.dat(ismissing) = 0;  % Replace with 0 for compatibility with image format

        % Old - this does not handle different missing voxels in different images
        %         fmridat.dat = scale(fmridat.dat')';

        fmridat.history{end+1} = 'Z-scored voxels (rows) across images';

    case 'rankvoxels'
        for i = 1:size(fmridat.dat, 1) % for each voxel

            d = fmridat.dat(i, :)';

            % Consider missing voxels, and exclude case-wise (image-wise)
            ismissing = d == 0 | isnan(d);
            d(ismissing) = NaN;

            if ~all(d == 0)
                fmridat.dat(i, ~ismissing) = rankdata(d(~ismissing))';
            end

        end

        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        fmridat.dat(ismissing) = 0; % Replace with 0 for compatibility with image format

        fmridat.history{end+1} = 'Ranked voxels (rows) across images';

    case 'rankimages'
        dat = zeros(size(fmridat.dat));

        parfor i = 1:size(fmridat.dat, 2)

            d = fmridat.dat(:,i);

            % Consider missing voxels, and exclude case-wise (image-wise)
            ismissing = d == 0 | isnan(d);
            d(ismissing) = NaN;

            if ~all(d == 0)
                d(~ismissing, i) = rankdata(d(~ismissing));
            end

            dat(:, i) = d;

        end

        dat(isnan(dat)) = 0; % Replace with 0 for compatibility with image format

        fmridat.dat = dat;

        fmridat.history{end+1} = 'Ranked images (columns) across voxels';

    case 'centerimages'

        % center images (observations)

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        fmridat.dat(ismissing) = NaN;

        m = nanmean(fmridat.dat);
        fmridat.dat = (fmridat.dat - m);  % Note: Sizes are wrong without repmat, but Matlab 2020b at least figures this out.

        fmridat.dat(ismissing) = 0;  % Replace with 0 for compatibility with image format

        % Old - this does not handle different missing voxels in different images
        % fmridat.dat = scale(fmridat.dat, 1);

        fmridat.history{end+1} = 'Centered images (columns) across voxels';

    case 'zscoreimages'

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        fmridat.dat(ismissing) = NaN;

        m = nanmean(fmridat.dat);
        s = nanstd(fmridat.dat);
        fmridat.dat = (fmridat.dat - m) ./ s;  % Note: Sizes are wrong without repmat, but Matlab 2020b at least figures this out.

        fmridat.dat(ismissing) = 0;  % Replace with 0 for compatibility with image format

        % Old - this does not handle different missing voxels in different images
        %         fmridat.dat = scale(fmridat.dat);

        fmridat.history{end+1} = 'Z-scored each image (columns) across voxels, excluding missing values (0 or NaN) for the image';

    case 'doublecenter'

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        fmridat.dat(ismissing) = NaN;

        imagemeans = nanmean(fmridat.dat);
        [v, n] = size(fmridat.dat);
        imagemeanmatrix = repmat(imagemeans, v, 1);
        dat_doublecent = fmridat.dat - imagemeanmatrix;

        voxelmeans = nanmean(dat_doublecent, 2);
        voxelmeanmatrix = repmat(voxelmeans, 1, n);
        dat_doublecent = dat_doublecent - voxelmeanmatrix;
        fmridat.dat = dat_doublecent;

        fmridat.dat(ismissing) = 0;  % Replace with 0 for compatibility with image format

        fmridat.history{end+1} = 'Double-centered data matrix across images and voxels';

    case 'l1norm_images'

        % Vector L1 norm of vector
        % divide by this value to normalize image

%         wh = x ~= 0 & ~isnan(x);  % valid values
%         nvalid = sum(wh);
%         l1norm = double(sum(abs(x(wh))))
%         normalized_x = x .* nvalid ./ l1norm;  % divides each voxel x in image by the mean valid voxel value.

        normfun = @(x) sum(abs(x));

        x = fmridat.dat;

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        x(ismissing) = NaN;

        for i = 1:size(x, 2)
            % remove nans, 0s
            xx = x(~ismissing(:, i), i);
            % divides each voxel xx in image by the mean valid voxel value.
            n(i) = normfun(xx);
            xx = xx.* length(xx) ./ n(i);
            x(~ismissing(:, i), i) = xx;
        end

        x(ismissing) = 0;  % Replace with 0 for compatibility with image format

        fmridat.dat = x;

    case 'l2norm_images'

        % Vector L2 norm / sqrt(length) of vector
        % divide by this value to normalize image

        normfun = @(x) sum(x .^ 2) .^ .5;

        x = fmridat.dat;

        % Consider missing voxels, and exclude case-wise (image-wise)
        ismissing = fmridat.dat == 0 | isnan(fmridat.dat);
        x(ismissing) = NaN;

        for i = 1:size(x, 2)

            % remove nans, 0s
            xx = x(~ismissing(:, i), i);
            %             isbad = xx == 0 | isnan(xx);
            %             xx(isbad) = [];

            % divide by sqrt(length) so number of elements will not change scaling
            n(i) = normfun(xx) ./ sqrt(length(xx));

            xx = xx ./ n(i);

            %             x(:, i) = zeroinsert(isbad, xx);

            x(~ismissing(:, i), i) = xx;
        end

        x(ismissing) = 0;  % Replace with 0 for compatibility with image format

        fmridat.dat = x;

    case 'divide_by_csf_l2norm'

        [~, ~, ~, l2norms] = extract_gray_white_csf(fmridat);

        % divide each column image by its respective ventricle l2norm
        fmridat.dat = bsxfun(@rdivide, fmridat.dat, l2norms(:, 3)') ;

    case 'session_global_percent_change'

        nscan = fmridat.images_per_session;  % num images per session
        I = intercept_model(nscan);
        for i = 1:size(I, 2)

            wh = find(I(:, i));
            y = fmridat.dat(:, wh)';   % y is images x voxels
            gm = mean(y); % mean at each voxel, 1 x voxels

            % subtract mean at each vox, divide by global session mean
            y = (y - repmat(gm, size(y, 1), 1)) ./ std(y(:));
            fmridat.dat(:, wh) = y;
        end

    case 'session_spm_style'
        % SPM's default method of global mean scaling
        % useful for replicating SPM analyses or comparing SPM's scaling to
        % other methods.
        % not implemented yet because tor decided to use spm_global on images for comparison; this could be done though...
        % see help spm_global
        %         nscan = fmridat.images_per_session;  % num images per session
        %         I = intercept_model(nscan);
        %         for i = 1:size(I, 2)
        %
        %             wh = find(I(:, i));
        %             y = fmridat.dat(:, wh)';   % y is images x voxels
        %             gm = mean(y); % mean at each voxel, 1 x voxels
        %
        %             % subtract mean at each vox, divide by global session mean
        %             y = (y - repmat(gm, size(y, 1), 1)) ./ std(y(:));
        %             fmridat.dat(:, wh) = y;
        %         end

    case 'session_global_z'

        % scale each session so that global brain mean and global brain std
        % across time are the same for each session

        % underlying model:
        % session-specific shifts in mean signal and scaling exist and are
        % independent

        % minus global (whole-brain) mean / global (whole-brain) std.
        % across time

        nscan = fmridat.images_per_session;  % num images per session
        I = intercept_model(nscan);
        for i = 1:size(I, 2)

            wh = find(I(:, i));
            y = fmridat.dat(:, wh);
            gm = mean(y); % mean at each time point

            % subtract mean at each vox, divide by session global std
            y = (y - repmat(gm, size(y, 1), 1)) ./ std(y(:));
            fmridat.dat(:, wh) = y;
        end

    case 'session_multiplicative'

        % scale - multiplicative
        % underlying model:
        % a is a process constant across time, but different for each voxel
        % (T2 contrast as a function of voxel properties)
        % b is a process constant across voxels, but different at each time
        % point within a session
        % (overall scaling, which varies across time)
        % these interact multiplicatively to create variation in both
        % global mean and std deviation jointly, which is why global mean
        % and global std are intercorrelated correlated.
        %
        % image std scales with b, and so does image mean.
        % model assumes a linear relationship between mean and std with
        % slope = 1

        gm = mean(fmridat.dat, 1); % mean across brain, obs series
        gs = std(fmridat.dat, 1);

        create_figure('global mean vs std', 1, 2);
        plot(gm, gs, 'k.')
        xlabel('Image mean');
        ylabel('Image std');
        title('Mean vs. std, before scaling, each dot is 1 image')
        drawnow

        %         if length(varargin) == 0 || isempty(varargin{1})
        %             error('Must enter number of images in each session as input argument');
        %         end

        if isempty(fmridat.images_per_session)
            fmridat.images_per_session = size(fmridat.dat, 2);
        end

        nscan = fmridat.images_per_session;  % num images per session
        I = intercept_model(nscan);

        for i = 1:size(I, 2)

            wh = find(I(:, i));
            y = fmridat.dat(:, wh);
            y(y < 0) = 0;  % images should be all positive-valued

            a = mean(y')';  % mean across time, for each voxel
            b = mean(y);    % mean across voxels, for each time point

            % ystar is reconstruction based on marginal means
            ystar = a*b ./ (mean(a));

            fmridat.dat(:, wh) = y ./ (ystar + .05*mean(ystar(:)));  % like m-estimator; avoid dividing by zero by adding a constant

            % fmridat.dat(:, wh) = y ./ repmat(b, size(y, 1), 1);  % intensity normalization
        end

        gm = mean(fmridat.dat, 1); % mean across brain, obs series
        gs = std(fmridat.dat, 1);

        subplot(1, 2, 2)
        plot(gm, gs, 'k.')
        xlabel('Image mean');
        ylabel('Image std');
        title('After scaling')
        drawnow

    case 'windsorizevoxels'

        whbad = all(fmridat.dat == 0, 2);
        nok = sum(~whbad);

        fprintf('windsorizing %3.0f voxels to 3 std: %05d', 0);
        for i = 1:nok
            if mod(i, 100) == 0, fprintf('\b\b\b\b\b%05d', i); end
            fmridat.dat(i, :) = trimts(fmridat.dat(i, :)', 3, [])';
        end

        fmridat.history{end+1} = 'Windsorized each voxel data series to 3 sd';

    case 'tanh'
        % rescale variables by hyperbolic tangent function
        % this will shrink the tails (and outliers) towards the mean,
        % making subsequent algorithms more robust to outliers.
        % However, it also truncates and flattens the distribution
        % (non-normal)

        fmridat.dat = tanh(zscore(fmridat.dat'))';

    case 'percentchange'
        % scale each voxel (column) to percent signal change with a mean of 100
        % based on smoothed mean values across space (cols), using iimg_smooth_3d

        m = mean(fmridat.dat',1)'; % mean at each voxel, voxels x 1

        sfwhm = 16;
        ms = iimg_smooth_3d(m, fmridat.volInfo, sfwhm, fmridat.removed_voxels);

        % subtract mean at each vox, divide by global session mean
        fmridat.dat = 100 + 100 .* (fmridat.dat - repmat(m, 1, size(fmridat.dat, 2))) ./ repmat(ms, 1, size(fmridat.dat, 2));

        fmridat.history{end+1} = 'Rescaled to mean 100, voxelwise % signal change with 16 mm fwhm smoothing of divisor mean';

    case 'correly'

        % correl with y
        % provides implicit feature selection when using algorithms that
        % are scale-dependent (e.g., SVM, PCA)

    case 'csf_mean_var'

        [~,~,tissues] = extract_gray_white_csf(fmridat);
        csfStd = nanstd(tissues{3}.dat);
        csfMean = nanmean(tissues{3}.dat);

        fmridat = fmridat.remove_empty;
        dat = fmridat.dat;

        dat = bsxfun(@minus,dat,csfMean);
        dat = bsxfun(@rdivide,dat,csfStd);

        fmridat.dat = dat;
        fmridat = fmridat.replace_empty;

    otherwise
        error('Unknown scaling method.')

end

end


function [fMedianMc, fMeanMc, fMc_org, v1Sigma, fStd_Mc, vMc] = calc_BstMc(mCatalog, fBinning, nSample, nMethod)
% function [fMedianMc, fMeanMc, fMc_org, v1Sigma, fStd_Mc, vMc] = calc_BstMc(mCatalog, fBinning, nSample, nMethod)
%---------------------------------------------------------------------------------------------------------
% Bootstrap EQ catalog and determine Mc choosing a specific method
%
% Incoming variables:
% mCatalog   : EQ catalog
% fBinning   : Magnitude binning interval
% nSample    : Number of bootstrap samples
% nMethod    : Method to determine the magnitude of completeness
%               1: Maximum curvature
%               2: Fixed Mc = minimum magnitude (Mmin)
%               3: Mc90 (90% probability)
%               4: Mc95 (95% probability)
%               5: Best combination (Mc95 - Mc90 - maximum curvature)
%               6: Mc using EMR-method
%               7: Mc due b using Shi & Bolt uncertainty
%               8: Mc due b using bootstrap uncertainty
%               9: Mc due b Cao-criterion
%
% Outgoing variables:
% fMedianMc  : Median (50 percentile) of vMc using nSample bootstraps
% fMeanMc    : Mean of Mc using nSample bootstraps
% fMc_org    : Mc estimate from original dataset
% v1Sigma    : [16 84] percentiles, according to standard deviation for normal distribution
% fStd_Mc    : Second moment of empirical Mc distribution (assuming normal distribution)
% vMc        : Mc estimates from bootstrap samples (empirical distribution)
%
% J. Woessner: woessner@seismo.ifg.ethz.ch
% last update: 28.05.03

% Check input
if nargin == 0, error('No catalog input'); end
if nargin == 1, fBinning = 0.1, nSample = 200, disp('Default Bin size 0.1, Default 200 bootstrap samples');end
if nargin == 2, nSample = 200, disp('Default 200 bootstrap samples'); end
if nargin == 3, nMethod = 6, disp('Default method: EMR-method'); end
if nargin > 4, error('Too many arguments!'); end

% Initialize
vMc = [];

% Get magnitudes
vMags = mCatalog(:,6);

% Create bootstrap samples using bootstrap matlab toolbox
mMag_bstsamp = bootrsp(vMags,nSample);
% Calculate Mc of original catalog
fMc_org = calc_Mc(mCatalog, nMethod);
% Determine Mc uncertainty
for nSamp=1:nSample
    mCatalog(:,6) = mMag_bstsamp(:,nSamp);
    fMc = calc_Mc(mCatalog, nMethod);
    vMc =  [vMc; fMc];
end

% Check for Nan and create output
vSel = isnan(vMc);
vNoNanMc = vMc(~vSel,:);
if ~isempty(vNoNanMc)
    fStd_Mc = calc_StdDev(vNoNanMc);
    fMeanMc = mean(vNoNanMc);
    fMedianMc = median(vNoNanMc);
else
    fStd_Mc = NaN;
    fMeanMc = NaN;
    fMedianMc = NaN;
end

if (~isempty(vNoNanMc) & length(vNoNanMc) > 1)
    v1Sigma = prctile(vNoNanMc,[16 84]);
elseif (~isempty(vNoNanMc)  &&  length(vNoNanMc) == 1)
    v1Sigma = prctile(vNoNanMc,[16 84]);
    v1Sigma = v1Sigma';
else
    v1Sigma = [NaN NaN];
end


function SNR = svargplvmSNR(model)

% SVARGPLVMSNR A small utility to display the Signal to Noise ratio of an optimised svargplvm model
% DESC The signal to noise ratio is defined for every modality, and it is shows the amount of  true signal
% vs the amount of "noise" which is assumed to have generated the data.
% SEEALSO : svargplvmOptimiseModel
%
% COPYRIGHT : Andreas C. Damianou, 2012

% VARGPLVM

for i=1:model.numModels
    if model.comp{i}.DgtN && isfield(model.comp{i}, 'mOrig') && ~isempty(model.comp{i}.mOrig)
        varData = var(model.comp{i}.mOrig(:));
    else
        varData = var(model.comp{i}.m(:));
    end
    SNR{i} = varData/(1/model.comp{i}.beta);
end


%-------------------------------------------------------------------------------------------------------------------%
%
% IB2d is an Immersed Boundary Code (IB) for solving fully coupled non-linear
% 	fluid-structure interaction models. This version of the code is based off of
%	Peskin's Immersed Boundary Method Paper in Acta Numerica, 2002.
%
% Author: Nicholas A. Battista
% Email:  nick.battista@unc.edu
% Date Created: May 27th, 2015
% Institution: UNC-CH
%
% This code is capable of creating Lagrangian Structures using:
% 	1. Springs
% 	2. Beams (*torsional springs)
% 	3. Target Points
%	4. Muscle-Model (combined Force-Length-Velocity model, "HIll+(Length-Tension)")
%
% One is able to update those Lagrangian Structure parameters, e.g., spring constants, resting %%	lengths, etc
%
% There are a number of built in Examples, mostly used for teaching purposes.
%
% If you would like us %to add a specific muscle model, please let Nick (nickabattista@gmail.com) know.
%
%--------------------------------------------------------------------------------------------------------------------%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: Models the force interaction that is user-defined.
%
%           Note:
%                   1. User has complete control for artibtrary input file
%                      format and number of parameters
%                   2. Those parameters get passed to the matrix called
%                      "general_force"
%                   3. User gets options of including other things into
%                      force function outside of inputted parameters, e.g.,
%                      current_time, dt, previous location of Lag. Pts, etc.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [fx_genForce, fy_genForce] = give_Me_General_User_Defined_Force_Densities(ds,Nb,xLag,yLag,xLag_P,yLag_P,dt,current_time,general_force)

    %
    % INPUTS:
    %         ds: Lagragian spacing (defined by ds = 0.5*dx)
    %         Nb: # of Lagrangian Pts.
    %         xLag: current x-Lagrangian coordinate positions
    %         yLag: current y-Lagrangian coordinate positions
    %         xLag_P: previous x-Lagrangian coordinate positions
    %         yLag_P: previous y-Lagrangian coordinate positions
    %         dt: time-step value
    %         current_time: current time in simulation
    %         general_force: matrix containing all data from input file
    %

    %
    % NOTE: THIS EXAMPLE CREATES A USER-DEFINED FORCE THAT IS JUST AN
    % ORDINARY LINEAR SPRING
    %

    Nsprings = length(general_force(:,1));  % # of Springs
    sp_1 = general_force(:,1);              % Initialize storage for MASTER NODE Spring Connection
    sp_2 = general_force(:,2);              % Initialize storage for SLAVE NODE Spring Connection
    K_Vec = general_force(:,3);             % Stores spring stiffness associated with each spring
    RL_Vec = general_force(:,4);            % Stores spring resting length associated with each spring

    fx = zeros(Nb,1);                 % Initialize storage for x-forces
    fy = fx;                          % Initialize storage for y-forces

    %
    % Loops over all the master-nodes of the springs to compute forces
    %
    for i=1:Nsprings

        id_Master = sp_1(i);          % Master Node index
        id_Slave = sp_2(i);           % Slave Node index
        k_Spring = K_Vec(i);          % Spring stiffness of i-th spring
        L_r = RL_Vec(i);              % Resting length of i-th spring

        dx = xLag(id_Slave) - xLag(id_Master); % x-Distance btwn slave and master node
        dy = yLag(id_Slave) - yLag(id_Master); % y-Distance btwn slave and master node

        sF_x =  k_Spring * ( sqrt( dx^2 + dy^2 ) - L_r ) * ( dx / sqrt(dx^2+dy^2) ); % Compute x-Force
        sF_y =  k_Spring * ( sqrt( dx^2 + dy^2 ) - L_r ) * ( dy / sqrt(dx^2+dy^2) ); % Compute y-Force

        fx(id_Master,1) = fx(id_Master,1) + sF_x;  % Sum total forces for node, i in x-direction (this is MASTER node for this spring)
        fy(id_Master,1) = fy(id_Master,1) + sF_y;  % Sum total forces for node, i in y-direction (this is MASTER node for this spring)

        fx(id_Slave,1) = fx(id_Slave,1) - sF_x;    % Sum total forces for node, i in x-direction (this is SLAVE node for this spring)
        fy(id_Slave,1) = fy(id_Slave,1) - sF_y;    % Sum total forces for node, i in y-direction (this is SLAVE node for this spring)

    end

    % Store forces from artibrary force function onto desired Lagrangian Pts.
    fx_genForce = fx;
    fy_genForce = fy;


function bvec_to_i4_test ( )

%*****************************************************************************80
%
%% BVEC_TO_I4_TEST tests BVEC_TO_I4;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  n = 10;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'BVEC_TO_I4_TEST\n' );
  fprintf ( 1, '  BVEC_TO_I4 converts a signed binary vector\n' );
  fprintf ( 1, '  to an integer;\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  I --> BVEC  -->  I\n' );
  fprintf ( 1, '\n' );

  for i = -3 : 10
    bvec = i4_to_bvec ( i, n );
    i2 = bvec_to_i4 ( n, bvec );
    fprintf ( 1, '  %2d  ', i );
    for j = 1 : n
      fprintf ( 1, '%1d', bvec(j) );
    end
    fprintf ( 1, '  %2d\n', i2 );
  end

  return
end


function [val,vec,info] = syev(jobz,uplo,a)
%SYEV   Computing eigen information.
%   [VAL,VEC,INFO] = SYEV(JOBZ,UPLO,A) computes eigenvalues and,
%	optionally, eigenvectors of a symmetric matrix A.
%
%	JOBZ allows the user to choose if eigenvectors are to be computed.
%	JOBZ
%          = 'N':  Compute eigenvalues only;
%          = 'V':  Compute eigenvalues and eigenvectors.
%
%	UPLO allows the user to choose which part of the matrix will be referenced.
%	UPLO
%          = 'U':  Upper triangle of A is stored;
%          = 'L':  Lower triangle of A is stored.
%
%   If only eigenvalues are desired, the QR algorithm is used.
%
%	No input parameter are optional. If you want an easy to use interface,
%	see SYEV_DRIVER.

    vec = [];
	val = [];
	info = [];

	if (nargin~=3),
		disp('Wrong number of input parameters.');
		return;
	end;

	    %Do all the boring checking
	if (~isnumeric(a)),
		disp('The matrix is not composed of numeric values.');
		return;
	elseif (isinteger(a)),
		a=double(a);
	end;

    if (size(a,1)~=size(a,2)),
        disp('The matrix must be square.');
        return;
	end;
	n=int32(size(a,1));
	lda=int32(n);

	if (isComplex(a)),
		if (isDouble(a))

			w=zeros(double(n),1);
			work=complex(zeros(1));
			lrwork=int32(max(1,3*n-2));
			rwork=zeros(double(lrwork),1);
			lwork=int32(-1);
			info=int32(-1);
			[jobz, uplo, n, vec, lda, val, work, lwork, rwork,info]=lapack_zheev(jobz, uplo, n, a, lda, w, work, lwork, rwork,info);
			lwork=int32(work(1));
			work=complex(zeros(double(lwork),1));
			[jobz, uplo, n, vec, lda, val, work, lwork, rwork,info]=lapack_zheev(jobz, uplo, n, a, lda, w, work, lwork, rwork,info);
		else
			w=single(zeros(double(n),1));
			work=single(complex(zeros(1,1)));
			work(1)=sqrt(-1)+1;
			lrwork=int32(single(max(1,3*n-2)));
			rwork=single(zeros(double(lrwork),1));
			lwork=int32(single(-1));
			info=int32(single(-1));
			[jobz, uplo, n, vec, lda, val, work, lwork, rwork,info]=lapack_cheev(jobz, uplo, n, a, lda, w, work, lwork, rwork,info);
			lwork=int32(work(1));
			work=single(complex(zeros(double(lwork),1)));
			[jobz, uplo, n, vec, lda, val, work, lwork, rwork,info]=lapack_cheev(jobz, uplo, n, a, lda, w, work, lwork, rwork,info);

		end;
	else
		if (isDouble(a)),
			w=zeros(double(n),1);
			work=zeros(1);
			lwork=int32(-1);
			info=int32(-1);
			[jobz, uplo, n, vec, lda, val, work, lwork, info]=lapack_dsyev(jobz, uplo, n, a, lda, w, work, lwork, info);
			lwork=int32(work(1));
			work=zeros(double(lwork),1);
			[jobz, uplo, n, vec, lda, val, work, lwork, info]=lapack_dsyev(jobz, uplo, n, a, lda, w, work, lwork, info);
		else
			w=single(zeros(double(n),1));
			work=single(zeros(1));
			lwork=int32(-1);
			info=int32(-1);
			[jobz, uplo, n, vec, lda, val, work, lwork, info]=lapack_ssyev(jobz, uplo, n, a, lda, w, work, lwork, info);
			lwork=int32(work(1));
			work=single(zeros(double(lwork),1));
			[jobz, uplo, n, vec, lda, val, work, lwork, info]=lapack_ssyev(jobz, uplo, n, a, lda, w, work, lwork, info);
		end;
	end;


function [w, state] = adam(w, state, grad, opts, lr)
%SGD
%   Example SGD solver, with momentum, for use with CNN_TRAIN and
%   CNN_TRAIN_DAG.
%
%   The convergence of SGD depends heavily on the learning rate (set in the
%   options for CNN_TRAIN and CNN_TRAIN_DAG).
%
%   If called without any input argument, returns the default options
%   structure.
%
%   Solver options: (opts.train.solverOpts)
%
%   `momentum`:: 0.9
%      Parameter for Momentum SGD; set to 0 for standard SGD.
%
%   Note: for backwards compatibility, the parameter can also be set in
%   opts.train.momentum.

% Copyright (C) 2016 Joao F. Henriques.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

if nargin == 0 % Return the default solver options
  w = struct('momentum', 0.9);
  return;
end
if isempty(state)
  state.m = 0;
  state.v = 0;
  state.momentum1t = 1;
  state.momentum2t = 1;
%   momentum = 0 ;
end

opts.momentum1 = 0.9;
opts.momentum2 = 0.999;

state.momentum1t = state.momentum1t*opts.momentum1;
state.momentum2t = state.momentum2t*opts.momentum2;
state.m = opts.momentum1*state.m + (1-opts.momentum1)*grad;
state.v = opts.momentum2*state.v + (1-opts.momentum2)*grad.^2;

momentum = - state.m/(1-state.momentum1t);
momentum = momentum ./ (sqrt(state.v/(1-state.momentum2t)) + 10^(-8));
w = w + lr * momentum ;