%% Example using rbb3select

% This part from MATLAB(R)'s SCATTER3 example
[x,y,z] = sphere(16);
X = [x(:)*.5 x(:)*.75 x(:)];
Y = [y(:)*.5 y(:)*.75 y(:)];
Z = [z(:)*.5 z(:)*.75 z(:)];
S = repmat([1 .75 .5]*10,prod(size(x)),1);
C = repmat([1 2 3],prod(size(x)),1);
scatter3(X(:),Y(:),Z(:),S(:),C(:),'filled'), view(-60,60)

% Draw red circles around selected points
SS=rbb3select(X,Y,Z);
hold on
scatter3(X(find(SS)),Y(find(SS)),Z(find(SS)),'o','r')
hold off


function [ diag, off, seed ] = r8sr_random ( n, nz, row, col, seed )

%*****************************************************************************80
%
%% R8SR_RANDOM randomizes a R8SR matrix.
%
%  Discussion:
%
%    The R8SR storage format stores the diagonal of a sparse matrix in DIAG.
%    The off-diagonal entries of row I are stored in entries ROW(I)
%    through ROW(I+1)-1 of OFF.  COL(J) records the column index
%    of the entry in A(J).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, integer NZ, the number of offdiagonal nonzero elements in A.
%
%    Input, integer ROW(N+1).  The nonzero offdiagonal elements of row I of A
%    are contained in A(ROW(I)) through A(ROW(I+1)-1).
%
%    Input, integer COL(NZ), contains the column index of the element
%    in the corresponding position in A.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real DIAG(N), the diagonal elements of A.
%
%    Output, real OFF(NZ), the off-diagonal elements of A.
%
%    Output, integer SEED, an updated seed for the random number generator.
%
  for i = 1 : n
    [ diag(i), seed ] = r8_uniform_01 ( seed );
    for j = row(i) : row(i+1)-1
      [ off(j), seed ] = r8_uniform_01 ( seed );
    end
  end

  return
end


filename='Cantileverbeam_Tetrahedra_Linear_Structured_SYM';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance'};
weights = [1];
constraint = {'volume'};
optimizer = 'MMA';
incrementFactor = 1;
designVariable = 'Density';
filterType = 'P1';
showBC = true;

nsteps = 10;
Vfrac_final = 0.1;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

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


function T=Entropy_Kapur(X,Trange);
hg=hist(X,Trange);
pg=hg./sum(hg);
Ti=0;
TrangeSpan=Trange(pg>0);
JT=zeros(length(TrangeSpan),1);
for Tk=TrangeSpan
    Ti=Ti+1;
    PT=sum(pg(Trange<=Tk));
    H=-pg./PT.*log10(pg./PT);
    isnanind=~isnan(H);
    Hf=sum(H(Trange<=Tk&isnanind));
    Hb=sum(H(Trange>Tk&isnanind));
    JT(Ti)=Hf+Hb;
end
[~,Tind]=max(JT);
T=TrangeSpan(Tind);
end


function signal_mat = focus(kgrid, input_signal, source_mask, focus_position, sound_speed)
%FOCUS    Create input signal based on source mask and focus position.
%
% DESCRIPTION:
%       focus takes a single input signal and a source mask and creates an
%       input signal matrix (with one input signal for each source point).
%       The appropriate time delays required to focus the signals at a
%       given position in Cartesian space are automatically added based on
%       the user inputs for focus_position and sound_speed.
%
% USAGE:
%       input_signal_mat = focus(kgrid, input_signal, source_mask, focus_position, sound_speed)
%
% INPUTS:
%       kgrid           - k-Wave grid structure returned by makeGrid
%       input_signal    - single time series input
%       source_mask     - matrix specifying the positions of the time
%                         varying source distribution (i.e., source.p_mask
%                         or source.u_mask)
%       focus_position  - position of the focus in Cartesian coordinates
%       sound_speed     - scalar sound speed
%
% OUTPUTS:
%       input_signal_mat - matrix of time series following the source
%                         points using MATLAB's column-wise linear index
%                         ordering
%
% ABOUT:
%       author          - Bradley Treeby
%       date            - 21st February 2012
%       last update     - 25th July 2013
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2014 Bradley Treeby and Ben Cox

% This file is part of k-Wave. k-Wave 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.
%
% k-Wave 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 Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>.

% check that kgrid.t_array is defined
if strcmp(kgrid.t_array, 'auto')
    error('kgrid.t_array must be defined');
end

% check that the input sound speed is scalar
if numel(sound_speed) ~= 1
    error('sound_speed input must be scalar');
end

% calculate the distance from every point in the source mask to the focus
% position
switch kgrid.dim
    case 1
        dist = abs(kgrid.x(source_mask == 1) - focus_position(1));
    case 2
        dist = sqrt( (kgrid.x(source_mask == 1) - focus_position(1)).^2 + ...
            (kgrid.y(source_mask == 1) - focus_position(2)).^2 );
    case 3
        dist = sqrt( (kgrid.x(source_mask == 1) - focus_position(1)).^2 + ...
            (kgrid.y(source_mask == 1) - focus_position(2)).^2 + ...
            (kgrid.z(source_mask == 1) - focus_position(3)).^2 );
end

% convert the distance to units of time points
dist = round(dist./(kgrid.dt*sound_speed));

% convert time points to relative delays
dist = -(dist - max(dist(:)));
max_delay = max(dist(:));

% create an input matrix
signal_mat = zeros(length(dist), length(input_signal) + max_delay);

% assign the input signal
for source_index = 1:length(dist)
    delay = dist(source_index);
    signal_mat(source_index, :) = [zeros(1, delay), input_signal, zeros(1, max_delay - delay)];
end


filename='Cantileverbeam_Tetrahedra_Linear_Structured_SYM';
 ptype = 'MACRO';
method = 'SIMPALL';
materialType = 'ISOTROPIC';
initial_case = 'full';
cost = {'compliance','perimeter'};
weights = [1 0.1];
constraint = {'volume'};
optimizer = 'MMA';
incrementFactor = 1;
filterType = 'P1';
designVariable = 'Density';
constraint_case = 'INEQUALITY';
line_search_initiator = 'INCREASING LAST STEP';
showBC = true;

nsteps = 1;
Vfrac_final = 0.1;
Perimeter_target = 1;
optimality_final = 1e-3;
constr_final =1e-3;

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


function [g1, g2, g3] = sdlfmaXsdlfmKernGradientBlock(lfmKern1, lfmKern2, ...
    t1, t2, kyy, kyv, kvy, kvv, i, j, generalConst, generalConstGrad, ...
    covGrad)

% SDLFMAXSDLFMKERNGRADIENTBLOCK Gradients of the parameters in block i,j
% FORMAT
% DESC computes the kernel parameters gradients for the SDLFM kernel
% function in the block specified at indeces i,j. It assumes the
% computation for functions that system 1 describes an acceleration and
% system 2 describes a position.
% ARG lfmKern1 : structure containing parameters for the system 1
% ARG lfmKern2 : structure containing parameters for the system 2
% ARG t1 : times at which the system 1 is evaluated
% ARG t2 : times at which the system 2 is evaluated
% ARG kyy : covariance for the initial conditions between position 1 and
% position 2 at block i,j
% ARG kyv : covariance for the initial conditions between position 1 and
% velocity 2 at block i,j
% ARG kvy : covariance for the initial conditions between velocity 1 and
% position 2 at block i,j
% ARG kvv : covariance for the initial conditions between velocity 1 and
% velocity 2 at block i,j
% ARG i : interval to be evaluated for system 1
% ARG j : interval to be evaluated for system 2
% ARG generalConstant : constants evaluated with sdlfmKernComputeConstant.m
% ARG generalConstGrad : derivatives of the constants computed with
% sdlfmKernGradientConstant.m
% ARG covGrad : partial derivatives of the objective function wrt portion
% of the kernel matrix in block i,j
% RETURN g1 : gradients of parameters for the system 1
% RETURN g2 : gradients of parameters for the system 2
% RETURN g3 : gradients of switching points
%
% COPYRIGHT : Mauricio A. Alvarez, 2010.

% KERN

if nargin<11
    j = i;
    generalConst = [];
end

g3 = [];

% Compute derivatives of the mean terms with respect to the parameters

[g1Mean, g2Mean, gsp1Mean, gsp2Mean] = sdlfmKernGradientMean(lfmKern1(1), ...
    lfmKern2(1), t1, t2, kyy, kyv, kvy, kvv, covGrad, {'sdlfma','sdlfm'}, ...
    {'sdlfmj', 'sdlfmv'});

if i==j
    [g1, g2, g3t] = sdlfmaXsdlfmKernGradientBlockIEJ(lfmKern1, lfmKern2, t1, ...
        t2, covGrad, g1Mean, g2Mean, gsp1Mean, gsp2Mean, {'lfma', 'lfm'}, ...
        {'lfmj', 'lfm'}, {'lfma', 'lfmv'});
    g3(i) = g3t;
else
    if i>j
        [g1, g2, g3] = sdlfmXsdlfmKernGradientBlockIGJ(lfmKern1, lfmKern2, ...
            t1, t2, i, j, generalConst, generalConstGrad, covGrad, g1Mean, ...
            g2Mean, gsp1Mean, gsp2Mean, 'sdlfma', 'sdlfmj', 'lfmXlfm', ...
            'lfmvXlfm', {'lfmvXlfm', 'lfmvXlfm'}, {'lfmaXlfm', 'lfmvXlfmv'});
    else
        [g1, g2, g3] = sdlfmaXsdlfmKernGradientBlockILJ(lfmKern1, lfmKern2, ...
            t1, t2, i, j, generalConst, generalConstGrad, covGrad, g1Mean, ...
            g2Mean, gsp1Mean, gsp2Mean, 'sdlfm', 'sdlfmv', 'lfmaXlfm', ...
            'lfmaXlfmv',{'lfmjXlfm', 'lfmaXlfmv'}, {'lfmjXlfmv', 'lfmaXlfma'});
    end
end


function [M0,M1,L,X,q0] = spm_mfa(M,x,u)
% Jacobian for mean field approximations
% FORMAT [M0,M1,L,X,q0] = spm_mfa(M,x,u)
%--------------------------------------------------------------------------
% M   - model specification structure
% Required fields:
%    M.f   - dx/dt    = f(x,u,P)                     {function string or m-file}
%    M.g   - y(t)     = g(x,u,P)                     {function string or m-file}
%    M.m   - m inputs
%    M.n   - n states
%    M.l   - l ouputs
%    M.x   - (n x 1) = x(0) = expansion point
%    M.W   - (n x n) - covariance matrix of deterministic noise
% x    - cell array of vectors specifying evaluation grid
% u    - expansion point for inputs (c.f. background activity);
%
% M0   - 1st order Bilinear matrix dq/dt = M0*q + u*M1*q,  q = p(X);
% M1   - 2nd order Bilinear matrix
% L    - output matrix                 <y> = L*q;
% X    - evaluation points of state space
% q0   - stable mode M0*q0 = 0
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_mfa.m 4936 2012-09-18 19:47:55Z karl $

% default expansion point for inputs
%--------------------------------------------------------------------------
if nargin < 3
    u0 = zeros(M.m,1);
else
    u0 = u;
end

% create X - coordinates of evaluation grid
%--------------------------------------------------------------------------
n     = length(x);
for i = 1:n
    q     = 1;
    for j = 1:n
        q = kron(x{j}(:).^(i == j),q);
    end
    X(:,i) = q;
end

% f(x,0)
%--------------------------------------------------------------------------
N     = length(X);
f     = sparse(n,N);
for i = 1:N
    f(:,i) = feval(M.f,X(i,:)',u0,M.pE);
end

% Jacobian J - M0
%==========================================================================
for i = 1:n
    d(i)  = length(x{i});
    dx(i) = x{i}(2) - x{i}(1);
    I{i}  = speye(d(i),d(i));
end
J     = sparse(N,N);

% cycle over dimensions of state space
%--------------------------------------------------------------------------
for i = 1:length(x)

    % differential operators (for positive and negative flows)
    %----------------------------------------------------------------------
    j          = find(f(i,:) < 0);
    u          = sparse(j,1,f(i,j),N,1);
    j          = find(f(i,:) > 0);
    v          = sparse(j,1,f(i,j),N,1);

    dp         = spdiags(ones(d(i),1)*[1 -1],[ 0;1],d(i),d(i))/dx(i);
    dp(:,1)    = 0;
    dq         = spdiags(ones(d(i),1)*[1 -1],[-1;0],d(i),d(i))/dx(i);
    dq(:,end)  = 0;

    % Kronecker tensor products
    %----------------------------------------------------------------------
    Dp         = 1;
    Dq         = 1;
    for j = 1:(i - 1)
        Dp = kron(I{j},Dp);
        Dq = kron(I{j},Dq);
    end
    Dp    = kron(dp,Dp);
    Dq    = kron(dq,Dq);
    for j = (i + 1):n
        Dp = kron(I{j},Dp);
        Dq = kron(I{j},Dq);
    end
    DP{i} = Dp;

    % augment Jacobian
    %----------------------------------------------------------------------
    J     = J + Dp*spdiags(u,0,N,N) + Dq*spdiags(v,0,N,N);

end

% dispersion
%--------------------------------------------------------------------------
for i = 1:n
    for j = 1:n
        if M.W(i,j)
            J  = J - M.W(i,j)*DP{i}*DP{j}'/2;
        end

    end
end

% return if only M0 is required
%--------------------------------------------------------------------------
M0  = J;
if nargout == 1,  return,  end

% input induced changes to Jacobian dJ/du - M1
%==========================================================================
du    = 1e-6;
M1    = {};
for i = 1:M.m
    u     = u0;
    u(i)  = du;
    Mu    = spm_mfa(M,x,u);
    M1{i} = (Mu - M0)/du;
end

% return if only M0, M1 are required
%--------------------------------------------------------------------------
if nargout == 2,  return,  end

% Output matrix L - M1
%==========================================================================

% l(x,0)
%--------------------------------------------------------------------------
L     = sparse(M.l,N);
for i = 1:N
    L(:,i) = feval(M.g,X(i,:)',u,M.pE);
end

% equilibrium mode
%--------------------------------------------------------------------------
if nargout == 5

    % stable mode - stochastic iteration
    %----------------------------------------------------------------------
    q   = ones(N,1)/N;
    for i = 1:1024
        dq = M0*q;
        q  = q + dq/N;
        q  = q/sum(q);
    end
    q0  = q;

    % analytic solution (not implemented)
    %----------------------------------------------------------------------
    % q   = length(M0);
    % J   = [M0; ones(1,q)];
    % q0  = sum(inv(J'*J),2);

end


function convBconv_last()
    global config mem;
    curr_layer_idx = config.misc.current_layer;
    mem.deltas{curr_layer_idx+1} = reshape(accumarray(mem.convBconv{curr_layer_idx+2}, mem.deltas{curr_layer_idx+1}(:)), ...
                                            mem.orig_activation_size{curr_layer_idx+1}(2), mem.orig_activation_size{curr_layer_idx+1}(1))';
                                           %size(mem.layer_inputs{curr_layer_idx+1}, 1), size(mem.layer_inputs{curr_layer_idx+1}, 2));
end


function results = vl_test_ihashsum(varargin)
% VL_TEST_IHASHSUM
vl_test_init ;

function s = setup()
rand('state',0) ;
s.data = uint8(round(16*rand(2,100))) ;
sel = find(all(s.data==0)) ;
s.data(1,sel)=1 ;

function test_hash(s)
D = size(s.data,1) ;
K = 5 ;
h = zeros(1,K,'uint32') ;
id = zeros(D,K,'uint8');
next = zeros(1,K,'uint32') ;
[h,id,next] = vl_ihashsum(h,id,next,K,s.data) ;

sel = vl_ihashfind(id,next,K,s.data) ;
count = double(h(sel)) ;

[drop,i,j] = unique(s.data','rows') ;
for k=1:size(s.data,2)
  count_(k) = sum(j == j(k)) ;
end
vl_assert_equal(count,count_) ;


%
% Usage:   gstruct =mexGroupStructOfString(s)
%
% Name: mexGroupStructOfString
%
% Description: decode a multi-line string describing "simply" the structure of groups
%    of variables needed by mexProximalGraph, mexProximalTree, mexFistaGraph,
%    mexFistaTree and mexStructTrainDL and builds the corresponding group structure.
%    Each line describes a group of variables as a node of a tree.
%    It has up to 4 fields separated by spaces:
%        node-id node-weight [variables-list] -> children-list
%    Let's define Ng = number of groups, and Nv = number of variables.
%    node-id must be in the range (0 - Ng-1), and there must be Ng nodes
%    weight is a float
%    variables-list : a space separated list of integers, maybe empty,
%         but '[' and '] must be present. Numbers in the range (0 - Nv-1)
%    children-list : a space separated list of node-id's
%        If the list is empty, '->' may be omitted.
%    The data must obey some rules :
%        - A group contains the variables of the corresponding node and of the whole subtree.
%        - Variables attached to a node are those that are not int the subtree.
%        - If the data destination is a Graph, there may be several independant trees,
%          and a varibale may appear in several trees.
%    If the destination is a Tree, there must be only one tree, the root node
%    must have id == 0 and each variable must appear only once.
%
% Inputs: s:  the multi-lines string
%
% Output: groups: cell array, one element for each node
%                an element is itsel a 4 elements cell array:
%	          nodeid (int >= 0), weight (double), array of vars of the node,
%                array of children (nodeid's)
%
% Author: Jean-Paul CHIEZE, 2012


function pd1 = FitNPV(NPV)
%CREATEFIT    Create plot of datasets and fits
%   PD1 = CREATEFIT(NPV)
%   Creates a plot, similar to the plot in the main distribution fitting
%   window, using the data that you provide as input.  You can
%   apply this function to the same data you used with dfittool
%   or with different data.  You may want to edit the function to
%   customize the code and this help message.
%
%   Number of datasets:  1
%   Number of fits:  1
%
%   See also FITDIST.

% This function was automatically generated on 12-Sep-2012 17:35:05

% Output fitted probablility distribution: PD1

% Data from dataset "NPV data":
%    Y = NPV

% Force all inputs to be column vectors
NPV = NPV(:);

% Prepare figure
clf;
hold on;
LegHandles = []; LegText = {};

% --- Plot data originally in dataset "NPV data"
[CdfF,CdfX] = ecdf(NPV,'Function','cdf');  % compute empirical cdf
BinInfo.rule = 1;
[~,BinEdge] = internal.stats.histbins(NPV,[],[],BinInfo,CdfF,CdfX);
[BinHeight,BinCenter] = ecdfhist(CdfF,CdfX,'edges',BinEdge);
hLine = bar(BinCenter,BinHeight,'hist');
set(hLine,'FaceColor','none','EdgeColor',[0.333333 0 0.666667],...
    'LineStyle','-', 'LineWidth',1);
xlabel('Data');
ylabel('Density')
LegHandles(end+1) = hLine;
LegText{end+1} = 'NPV data';

% Create grid where function will be computed
XLim = get(gca,'XLim');
XLim = XLim + [-1 1] * 0.01 * diff(XLim);
XGrid = linspace(XLim(1),XLim(2),100);

% --- Create fit "fit 1"

% Fit this distribution to get parameter values
% To use parameter estimates from the original fit:
%     pd1 = ProbDistUnivParam('normal',[ 3887789.069562, 1315866.846527])
pd1 = fitdist(NPV, 'normal');
YPlot = pdf(pd1,XGrid);
hLine = plot(XGrid,YPlot,'Color',[1 0 0],...
    'LineStyle','-', 'LineWidth',2,...
    'Marker','none', 'MarkerSize',6);
LegHandles(end+1) = hLine;
LegText{end+1} = 'fit 1';

% Adjust figure
box on;
hold off;

% Create legend from accumulated handles and labels
hLegend = legend(LegHandles,LegText,'Orientation', 'vertical', 'Location', 'NorthEast');
set(hLegend,'Interpreter','none');


function b = legcoeffs(f, n)
%LEGCOEFFS   Compute Legendre series coefficients of a CHEBTECH object.
%   B = LEGCOEFFS(F) returns the Legendre series coefficients of CHEBTECH F, so
%   that F = B(1)*P_0 + ... + B(N)*P_(N-1), where P_k is the kth Legendre
%   polynomial. B is a vector of the same length as that of F.
%
%   B = LEGCOEFFS(F, N) returns the first N coefficients. If length(F) < N
%   then the additional entries of B are padded with zeros.
%
%   If F is an array-valued CHEBTECH, then a matrix of coefficients is returned
%   so that F(:,k) = B(1,k)*P_0 + ... + B(N,k)*P_(N-1).
%
% See also CHEBCOEFFS.

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

b = cheb2leg(f.coeffs);

if ( nargin > 1 )
    s = size(b);
    if ( s(1) > n )
        b = b(1:n, :);
    else
        b = [b; zeros(n-s(1), s(2))];
    end
end

end


% tutorial2
%   This exercise deals with the a small glycolysis model in RAVEN
%   compatible Excel format and shows the most basic aspects of the
%   stoichiometric modelling. It is shown how to build a simple model from
%   scratch, set parameters and perform simple simulations.
%   See Tutorial 2 in "RAVEN tutorials.docx" for more details.

%Import the Excel model into a RAVEN model structure
smallModel=importExcelModel('empty.xlsx');

%This solves the linear programming problem.
%NOTE: if sol.f is equal to zero then the problem is not solvable. Ensure
%that uptake and excretion of all necessary stuff are added to the model
%and run the solveLP again.
sol=solveLP(smallModel);

%Print the resulting exchange fluxes
printFluxes(smallModel,sol.x,true);

%Print all fluxes
printFluxes(smallModel,sol.x,false,10^-5,[],'%rxnID (%rxnName):\n\t%eqn\n\t%flux\n');


function k = findrows(A,b)
%FINDROWS finds a row vector within a matrix.
%
%   Usage: idx = findrows(A,b)
%
%   Input parameters:
%       A       - matrix
%       b       - vector to find in A
%
%   Output parameters:
%       idx     - indices of found columns in A
%
%   FINDROWS(A,b) returns a column vector with the indices of the rows
%   in the matrix A that are identical to the row vector b.  If no rows
%   in A are identical to b, an empty vector is returned.
%
%   See also: find, findcols

%*****************************************************************************
% The MIT License (MIT)                                                      *
%                                                                            *
% Copyright (c) 2010-2019 SFS Toolbox Developers                             *
%                                                                            *
% Permission is hereby granted,  free of charge,  to any person  obtaining a *
% copy of this software and associated documentation files (the "Software"), *
% to deal in the Software without  restriction, including without limitation *
% the rights  to use, copy, modify, merge,  publish, distribute, sublicense, *
% and/or  sell copies of  the Software,  and to permit  persons to whom  the *
% Software is furnished to do so, subject to the following conditions:       *
%                                                                            *
% The above copyright notice and this permission notice shall be included in *
% all copies or substantial portions of the Software.                        *
%                                                                            *
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
% IMPLIED, INCLUDING BUT  NOT LIMITED TO THE  WARRANTIES OF MERCHANTABILITY, *
% FITNESS  FOR A PARTICULAR  PURPOSE AND  NONINFRINGEMENT. IN NO EVENT SHALL *
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
% LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT  OR OTHERWISE, ARISING *
% FROM,  OUT OF  OR IN  CONNECTION  WITH THE  SOFTWARE OR  THE USE  OR OTHER *
% DEALINGS IN THE SOFTWARE.                                                  *
%                                                                            *
% The SFS Toolbox  allows to simulate and  investigate sound field synthesis *
% methods like wave field synthesis or higher order ambisonics.              *
%                                                                            *
% https://sfs.readthedocs.io                            sfstoolbox@gmail.com *
%*****************************************************************************

% AUTHOR: Peter John Acklam

%% ===== Checking of input parameters ====================================
nargmin = 2;
nargmax = 2;
narginchk(nargmin,nargmax);

%% ===== Computation =====================================================
k = find( A(:,1)==b(1) );
for jj = 2:size(A,2)
    k = k( A(k,jj)==b(jj) );
    if isempty(k)
        return
    end
end


function [R h] = rmCompareModelsGUI_paramXCorr(M, plotFlag);
% Compute the cross-correlation across parameter estimates for the RM compare
% models GUI.
%
%   [R h] = rmCompareModelsGUI_paramXCorr([M=get from cur figure], [plotFlag=1]);
%
% This correlation matrices, in which the basic pRF parameters
% (x0, y0, sigma, polar angle, eccentricity, and variance
% explained) are correlated across the loaded models. The correlation
% matrices are returned in the matrix R.
%
%
% OUTPUTS:
% R is a 3D matrix of size nModels by nModels by 6. The six slices are
% cross-correlation matrices for, respectively:
%	1) x0
%	2) y0
%	3) sigma major
%	4) polar angle
%	5) eccentricity
%	6) variance explained.
%
% For each cross-correlation matrix, the entry R(m,n) is the Pearson's
% correlation coefficient (R) between the pattern across all voxels of the
% relevant parameter, between model m and model n. The diagonal values
% R(n,n) are all set to 1, since each set of parameters is correlated to
% itself.
%
% INPUTS:
%
% M: compare models GUI data structure. [Default is to get it from the
% current figure.]
%
% plotFlag: indicates whether to show these matrices in a new figure. If 1 or 2,
% will return the handle of the new figure(s) in h.
%	0: don't plot
%	1: plot color-coded images of the correlation matrices
%	2: plot scatter plots for each comparison. (Will create a separate
%	figure for each pRF parameter, with the scatter plots arranged as per
%	the lower quadrant of the cross-correlation matrices.)
%
%
% ras, 04/2009.
if notDefined('M'),		M = get(gcf, 'UserData');			end
if notDefined('plotFlag'),	plotFlag = 1;					end

R = [];
h = [];

%% compute the correlation coefficients
fields = {'x0' 'y0' 'sigma' 'pol' 'ecc' 'varexp'};
for z = 1:6
	f = fields{z};  % field name

	data =  reshape( [M.(f){:}], [M.nVoxels M.nModels] );

	R(:,:,z) = corrcoef(data);
end

%% visualize if selected
if plotFlag==1
	%% plot color-coded images of the X-corr matrices
	nm = sprintf('Cross-Model Correlations %s', M.roi.name);
	h = figure('Color', 'w', 'Name', nm);

	for z = 1:6
		subplot(2, 3, z);

		drawXCorrMatrix( R(:,:,z) );

		% label each entry in the lower-left-hand plot
		if z==4
			axis on
			set(gca, 'Box', 'off', 'XTick', 1:M.nModels, ...
				'YTick', 1:1:M.nModels, 'FontSize', 9)
			xlabel('Model #', 'FontSize', 12);
			ylabel('Model #', 'FontSize', 12);
		end

		title( fields{z}, 'FontSize', 14 );
	end

elseif plotFlag==2
	%% plot multiple figures, with scatter plots for each correlation
	N = M.nModels - 1;  % # rows/columns of subplots in this figure

	for z = 1:6
		f = fields{z};  % field name

		nm = sprintf('Cross-Model Correlations %s', M.roi.name);
		h(z) = figure('Color', 'w', 'Name', nm);

		for x = 1:N
			for y = x+1:N+1
				row = y-1;
				subplot(N, N, [(row-1)*N + x]);
				regressPlot(M.(f){x}, M.(f){y}, 'x=y', 'title');

				if z < 3  % x0 or y0: add x=0 / y=0 line
					AX = axis;
					line(AX(1:2), [0 0], 'Color', [.5 .5 .5]);
					line([0 0], AX(3:4), 'Color', [.5 .5 .5]);
				end

% 				xlabel([M.dtList{x} ' ' f], 'FontSize', 12);
% 				ylabel([M.dtList{y} ' ' f], 'FontSize', 12);
				xlabel([M.params{x}.analysis.pRFmodel ' ' f], 'FontSize', 12);
				ylabel([M.params{y}.analysis.pRFmodel ' ' f], 'FontSize', 12);
            end
		end
	end

end

return


function [timelock, cfg] = freq2timelock(cfg, freq)

% FREQ2TIMELOCK  transform the frequency data into something
% on which the timelocked source reconstruction methods can
% perform their trick.
%
% This function also performs frequency and channel selection, using
%   cfg.frequency
%   cfg.channel
%
% After source reconstruction, you should use TIMELOCK2FREQ.

% Copyright (C) 2005, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip 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.
%
%    FieldTrip 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 FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

if isfield(freq, 'fourierspctrm')
  fprintf('constructing real/imag data representation from single trial fourier representation\n');
  % select the complex amplitude at the frequency of interest
  cdim = dimnum(freq.dimord, 'chan');  % should be 2
  fdim = dimnum(freq.dimord, 'freq');  % should be 3
  for i=1:numel(cfg.frequency)
    fbin(i) = nearest(freq.freq, cfg.frequency(i));
  end
  cfg.frequency = freq.freq(fbin);
  if cdim==2 && fdim==3
    % other dimords are not supported, since they do not occur
    spctrm = dimindex(freq.fourierspctrm, fdim, {fbin});
    spctrm = permute(spctrm, [2 1 3]);
  end
  % select the desired channels in the data
  cfg.channel = ft_channelselection(cfg.channel, freq.label);
  [dum, chansel] = match_str(cfg.channel, freq.label);
  spctrm = spctrm(chansel,:);
  % concatenate the real and imaginary part
  avg = [real(spctrm) imag(spctrm)];
elseif isfield(freq, 'crsspctrm')
  fprintf('constructing real/imag data representation from csd matrix\n');
  % hmmm... I have no idea whether this is correct
  cfg.channel = ft_channelselection(cfg.channel, freq.label);
  % this subfunction also takes care of the channel selection
  [Cf, Cr, Pr, Ntrials, dum] = prepare_freq_matrices(cfg, freq);
  cfg.frequency = dum.frequency;
  cfg.channel   = dum.channel;
  if length(size(Cf))==3
    % average the cross-spectrum over trials
    Cf = squeeze(mean(Cf,1));
  end
  % reconstruct something that spans the same space as the fft of the data, hmmm...
  [u, s, v] = svd(Cf);
  spctrm = u * sqrt(s);
  % concatenate the real and imaginary part
  avg = [real(spctrm) imag(spctrm)];
else
  ft_error('cannot convert this representation of frequency domain data');
end

timelock        = [];
timelock.avg    = avg;
timelock.label  = cfg.channel;
timelock.time   = 1:size(timelock.avg,2);
if isfield(freq, 'cfg'), timelock.cfg = freq.cfg; end
timelock.dimord = 'chan_time';

if isfield(freq, 'grad')
  timelock.grad = freq.grad;
end

if isfield(freq, 'elec')
  timelock.elec = freq.elec;
end


function inpainted_depth = inpaint_depth_with_plane(pixel_coordinates, plane)
%UNTITLED4 Summary of this function goes here
%   Detailed explanation goes here

number_of_pixels = size(pixel_coordinates, 1);

% At each pixel, return the **rectified** interpolation using the plane that is
% assumed to contain all input pixels, in order to always output positive depth
% values.
inpainted_depth = max([pixel_coordinates, ones(number_of_pixels, 1)] * plane,...
    0);

end


%  Copyright (c) 2014, Karen Simonyan
%  All rights reserved.
%  This code is made available under the terms of the BSD license (see COPYING file).

function [res, extra] = eval_best(config, scores, gt)

    % finds an optimal threshold - the threshold which maximises the accuracy

    % threshold scores and get the sign

    res = -Inf;
    extra.bestThresh = [];

    % thresh loop
    for i=1:numel(scores)

        curThresh = scores(i);
        class = 2 * (scores >= curThresh) - 1;

        % class-n accuracy
        acc = mean(class == gt);

        if acc > res

            res = acc;
            extra.bestThresh = curThresh;
        end
    end

    res = res * 100;

end


function mv = mv_removeOutliers(mv,criterion,thresh,plotFlag);
%
% mv = mv_removeOutliers([mv,criterion,thresh,plotFlag]);
%
% Remove outlier voxels, whose extreme values lie
% beyond a certain threshold. This threshold
% can either be a certain # of standard deviations
% away from the mean, or greater/less than a certain
% absolute value.
%
% criterion is 0 (count standard deviations  criterion) or 1
% (use abs value criterion). thresh is the threshold # of S.D.s or
% threshold value to use.. Omitting either brings up a dialog.
%
% after removing voxels, the mv struct is re-initialized.
%
% ras 05/05.
if ieNotDefined('mv')
    mv = get(gcf,'UserData');
end

plotFlag = 0;

if ieNotDefined('thresh') | ieNotDefined('criterion')
	ui(1).string = 'Threshold value:';
	ui(1).fieldName = 'thresh';
	ui(1).style = 'edit';
	ui(1).value = '1';

	ui(2).string = 'Criterion:';
	ui(2).fieldName = 'criterion';
	ui(2).list = {'Standard Deviations from Mean' 'Absolute % Signal'};
	ui(2).style = 'popup';
	ui(2).value = 1;

    ui(3).string = 'Report on response distributions';
    ui(3).fieldName = 'plotFlag';
    ui(3).style = 'checkbox';
    ui(3).value = 0;

	resp = generalDialog(ui,'Remove Outliers');
    thresh = str2num(resp.thresh);
    criterion = cellfind(ui(2).list,resp.criterion)-1;
    plotFlag = resp.plotFlag;
end

amps = mv_amps(mv);

% find outliers, based on specified criterion
switch criterion
    case 0, % remove voxels w/ mean > thresh std. deviations from
        amps = permute(nanmean(amps),[3 2 1]);
        sigma = nanstd(abs(amps(:)));
        mu = nanmean(abs(amps));
        muTotal = nanmean(abs(amps(:))); % overall mean across voxels
        outliers = find(mu>muTotal+thresh*sigma);
    case 1, % tSeries extends greater than thresh pct. signal
        [rows cols] = find(abs(mv.tSeries) > thresh);
        outliers = unique(cols);
end

% first, check that not ALL voxels are outliers...
if length(outliers)==size(mv.roi.coords,2)
    msg = ['Warning: Given the selected criteria, ALL voxels '...
           'were found to be outliers! No action taken.'];
    mrMessage(msg);
    return
end

% report the # and location of outliers found
fprintf('%i Outlier Voxels Found. \n',length(outliers));
% fprintf('Locations: \n ');
% for i = 1:length(outliers)
%     fprintf('\t %s \n', num2str(mv.roi.coords(:,i)));
% end
% fprintf('\n')

% keep only voxels that aren't outliers
keep = setdiff(1:size(mv.tSeries,2),outliers);
mv.tSeries = mv.tSeries(:,keep);

% also set roi coords to reflect only kept voxels
mv.coords = mv.coords(:,keep);
mv.roi.coords = mv.roi.coords(:,keep);

% plot distributions if selected
if plotFlag==1
    h = figure;
    subplot(211);
    if criterion > 0,
        amps = permute(nanmean(mv.voxAmps),[3 2 1]);
    end
    hist(amps(:),100);
    title('Before')
end

% recompute voxData matrix
mv.voxData = er_voxDataMatrix(mv.tSeries,mv.trials,mv.params);

% recompute voxAmps matrix
mv.voxAmps = er_voxAmpsMatrix(mv.voxData,mv.params);

% plot distributions if selected
if plotFlag==1
    figure(h);
    subplot(212);
    newAmps = permute(nanmean(mv.voxAmps),[3 2 1]);
    hist(newAmps(:),100);
    title('After')
    xlabel('Amplitude, % Signal')
    ylabel('# Voxels')

    figure(mv.ui.fig);
end

% if a UI exists, set as user data
if isfield(mv.ui,'fig') & ishandle(mv.ui.fig)
    set(mv.ui.fig,'UserData',mv);
    multiVoxelUI; % refresh UI
end

return


classdef EnergyComputerForVoigt < EnergyComputer

    properties
    end

    methods (Access = public)

        function obj = EnergyComputerForVoigt(C,s)
            obj.init(C,s)
            obj.computeEnergy()
        end
    end

    methods (Access = protected)

        function computeEnergy(obj)
            C = obj.fourthOrder.getValue();
            s = obj.secondOrder.getValue();
            d = obj.secondOrder.getVoigtDimension();
            en = 0;
            for i = 1:d
                for j = 1:d
                    si  = s(i);
                    Cij = C(i,j);
                    sj = s(j);
                    e = si*Cij*sj;
                    en = en + e;
                end
            end
            obj.energy = en;
        end

    end
end


report_this_filefun(mfilename('fullpath'));

figure

l  = get(h1,'XLim');
s1_east = l(2); s2_west = l(1);
l  = get(h1,'YLim');
s3_north = l(2); s4_south = l(1);

cl =  get(h1,'Clim');

m_proj('lambert','long',[s2_west s1_east],'lat',[s4_south s3_north]);

l = re4 >= cl(2);
re4(l) = re4(l)*0+cl(2)-0.01;
l = re4 <= cl(1);
re4(l) = re4(l)*0+cl(1)+0.01;

cstep = abs(cl(2) - cl(1))/5 ;
[m,c] = m_contourf(gx,gy,re4,(cl(1):cstep:cl(2)));
%set(c,'LineColor','r');

hold on

if isempty(coastline) ==  0
    lico = m_line(coastline(:,1),coastline(:,2),'color','k','LineWidth',0.5);
end

if isempty(faults) == 0
    %lifa = m_line(faults(:,1),faults(:,2),'color','k');
end

m_grid('box','on','linestyle','none','tickdir','out','color','k','linewidth',2,...
    'fontsize',10,'fontname','Helveticabold');
hold on
shading flat

caxis([cl(1) cl(2)-cstep])

hold on

%li = m_line(a.Longitude,a.Latitude);
%set(li,'Linestyle','none','Marker',ty1,'MarkerSize',ms6,'color',co)
set(gcf,'Color','w')

vx =  (cl(1):cstep:cl(2));
v = [vx ; vx]; v = v';
rect = [0.93 0.4 0.015 0.25];
axes('position',rect)
pcolor((1:2),vx,v)
shading flat
set(gca,'XTickLabels',[])
set(gca,'FontSize',10,'FontWeight','normal',...
    'LineWidth',1.0,'YAxisLocation','right',...
    'Box','on','SortMethod','childorder','TickDir','out')

g = gray;
g = g(60:-1:1,:);

colormap(g)
brighten(0.2)
caxis([cl(1) cl(2)-cstep])


function score = score_eigenvalues(~,~,D)
%SCORE_EIGENVALUES - Eigenvalues as score

score = diag(D);
score = score(:);


% The COBRAToolbox: testSingleProductionEnvelope.m
%
% Purpose:
%     - test the singleProductionEnvelope function
%
% Authors:
%     - Jacek Wachowiak
global CBTDIR
% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testSingleProductionEnvelope'));
cd(fileDir);

% test variables
model = getDistributedModel('ecoli_core_model.mat');
deletions = model.rxns(21); % 'EX_acald(e)'
deletions2 = model.genes(21);
product = char(model.rxns(20)); % 'EX_ac(e)' - the created and deleted plot has the name of the reaction
biomassRxn = char(model.rxns(22));
refData_y1 = zeros(20,1);
refData_y2 = 20 * ones(20, 1);

% function outputs
% requires Global Optimization Toolbox
% this function's output is a curve, in tested case one of them y=0, the other y=20-2x
[x, y1, y2] = singleProductionEnvelope(model, deletions, product, biomassRxn, 'savePlot', 1);
singleProductionEnvelope(model, deletions2, product, biomassRxn, 'geneDelFlag', 1);

% tests
assert(isequal(refData_y1, y1));
assert(isequal(((refData_y2 - (2 * x') - y2) < 1e-4), ones(20, 1)));

% remove the created plots and the folder - .gitignore for windows because apparently 'rmdir' fails sometimes
if isunix
try
  rmdir([CBTDIR filesep 'tutorials' filesep 'additionalTutorials' filesep 'optKnock' filesep 'Results'], 's');
end
end

% change to old directory
cd(currentDir);


function [res]=convert_mc(ys,k)

% function [res]=convert_mc(ys,[k])
%
%  convert_mc  - converts multi-class labels from examples x classes matrix
%                of {+1,-1}s to examples x 1 matrix of integers, and back
%                can provide optional k to say how many classes
%                there should be (incase some are missing)
%
%  e.g:
%  convert_mc([1 2 2]') returns [1 -1; -1 1 ; -1 1] and vice-versa
%  if you pass a data object instead, it converts the Y component
%  in the same way and returns the data object with converted Ys.

  if nargin==1 k=0; end;

  d=[];
  if isa(ys,'data')
    d=ys;
    ys=d.Y;
  end

  expand=1;
  if size(ys,2)==1 & min(min(ys))>0
    res=-ones(size(ys,1),max(max(ys),k));
    for i=1:size(ys,1) res(i,ys(i))=1; end;
  else
    expand=0;
    if size(ys,2)==1
      res=ys; res(res==-1)=2;
    else
      for i=1:size(ys,1) res(i)=find(ys(i,:)==1); end;
      res=res';
    end
  end

  if ~isempty(d)
    d.Y=res;
    res=d;
  end


function [p,q,r] = btf (A)                                                  %#ok
%BTF permute a square sparse matrix into upper block triangular form
% with a zero-free diagonal, or with a maximum number of nonzeros along the
% diagonal if a zero-free permutation does not exist.
%
% Example:
%       [p,q,r] = btf (A) ;
%       [p,q,r] = btf (A,maxwork) ;
%
% If the matrix has structural full rank, this is essentially identical to
%
%       [p,q,r] = dmperm (A)
%
% except that p, q, and r will differ in trivial ways.  Both return an upper
% block triangular form with a zero-free diagonal, if the matrix is
% structurally non-singular.  The number and sizes of the blocks will be
% identical, but the order of the blocks, and the ordering within the blocks,
% can be different.
%
% If the matrix is structurally singular, the q from btf will contain negative
% entries.  The permuted matrix is C = A(p,abs(q)), and find(q<0) gives a list
% of indices of the diagonal of C that are equal to zero.  This differs from
% dmperm, which does not place the maximum matching along the main diagonal
% of C=A(p,q), but places it above the diagonal instead.
%
% The second input limits the maximum amount of work the function does to
% be maxwork*nnz(A), or no limit at all if maxwork <= 0.  If the function
% terminates early as a result, a maximum matching may not be found, and the
% diagonal of A(p,abs(q)) might not have the maximum number of nonzeros
% possible.  Also, the number of blocks (length(r)-1) may be larger than
% what btf(A) or dmperm(A) would compute.
%
% See also maxtrans, strongcomp, dmperm, sprank

% Copyright 2004-2007, Tim Davis, University of Florida
% with support from Sandia National Laboratories.  All Rights Reserved.

error ('btf mexFunction not found') ;


function kernelS = realign_kernels(kernelS, tmax)

nt = size(kernelS, 1);

isub = linspace(1, nt, (nt-1)*10 + 1);

for j = 1:size(kernelS,2)
   ker = kernelS(:,j);
   kup = interp1(1:1:nt, ker, isub, 'spline');

   [~, imax] = max(kup);
   itmax = isub(imax); % the time of the max in units, needs to be at tmax

   kup = interp1(1:1:nt, ker, isub + itmax - tmax, 'spline', 0);

   kernelS(:,j) = kup(1:10:end);
end


function test_ft_combineplanar

% WALLTIME 00:20:00
% MEM 2gb
% DEPENDENCY ft_combineplanar ft_preprocessing ft_timelockanalysis ft_prepare_neighbours ft_megplanar

% template loading should be modified once template MEG data are available
% (cf.issue #1834)
subjectfilename = dccnpath('/home/common/matlab/fieldtrip/data/ftp/test/ctf/Subject01.ds');

cfg            = [];
cfg.dataset    = subjectfilename;
cfg.channel    = {'MEG', '-MLP31', '-MLO12'};        % read all MEG channels except MLP31 and MLO12
data = ft_preprocessing(cfg);

cfg = [];
data = ft_timelockanalysis(cfg,data);

cfg              = [];
cfg.feedback     = 'no';
cfg.method       = 'template';
cfg.neighbours   = ft_prepare_neighbours(cfg, data);
cfg.planarmethod = 'sincos';
data = ft_megplanar(cfg, data);

cfg = [];
cfg.updatesens = 'no';
dataout = ft_combineplanar(cfg,data);


function a = i4vec_sort_bubble_a ( n, a )

%*****************************************************************************80
%
%% I4VEC_SORT_BUBBLE_A ascending sorts an I4VEC using bubble sort.
%
%  Discussion:
%
%    Bubble sort is simple to program, but inefficient.  It should not
%    be used for large arrays.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of entries in the array.
%
%    Input, integer A(N), an unsorted array.
%
%    Output, integer A(N), the array has been sorted.
%
  for i = 1 : n-1
    for j = i+1 : n
      if ( a(j) < a(i) )
        t    = a(i);
        a(i) = a(j);
        a(j) = t;
      end
    end
  end

  return
end


function coordinates = createCoordinates(bounds, step)
    bounds = abs(bounds);
    coordinates = -bounds + step/2:step: bounds - step/2;
    %due to numerical instability of floating point numbers, somtimes series
    %is missing the last point.
    if(abs(coordinates(end) - (bounds - step/2)) > 1e-10)
        coordinates(end + 1) = bounds;
    end
end


function arpack_test02 ( )

%*****************************************************************************80
%
%% ARPACK_TEST02 tests EIGS for the smallest eigenvalues, using a function.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    09 February 2006
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'ARPACK_TEST02:\n' );
  fprintf ( 1, '  EIGS can compute a few eigenvalues\n' );
  fprintf ( 1, '  of least or greatest magnitude.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  When the matrix A is too large to store explicitly,\n' );
  fprintf ( 1, '  the user may supply a routine which computes A*x,\n' );
  fprintf ( 1, '  or inverse(A)*x.\n' );

  opts.disp = 0;
  opts.issym = 1;

  n = 139;
%
%  In general, n = size ( A, 1 ) where A = delsq ( numgrid('C',15) );
%
  lambda_small = eigs ( @(x)ainv_x(x,'C',15), n, 5, 'SM', opts )

  return
end


%% Copyright (C) 2014, 2016, 2019 Colin B. Macdonald
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy 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 software 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 software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @defmethod @@sym fliplr (@var{A})
%% Flip a symbolic matrix horizontally.
%%
%% Example:
%% @example
%% @group
%% A = sym([1 2 pi; 4 5 6]);
%% fliplr (A)
%%   @result{} (sym 2×3 matrix)
%%       ⎡π  2  1⎤
%%       ⎢       ⎥
%%       ⎣6  5  4⎦
%% @end group
%% @end example
%%
%% @seealso{@@sym/flipud, @@sym/reshape}
%% @end defmethod

function B = fliplr (A)

  cmd = { 'A, = _ins'
          'if A is None or not A.is_Matrix:'
          '    A = sp.Matrix([A])'
          'return A[:, ::-1]' };

  B = pycall_sympy__ (cmd, sym(A));

end

%!test
%! % simple
%! syms x
%! A = [x 2; sym(pi) x];
%! B = [2 x; x sym(pi)];
%! assert (isequal (fliplr(A), B))

%!test
%! % simple, odd # cols
%! syms x
%! A = [x 2 sym(pi); x 1 2];
%! B = [sym(pi) 2 x; 2 1 x];
%! assert (isequal (fliplr(A), B))

%!test
%! % scalar
%! syms x
%! assert (isequal (fliplr(x), x))


function [ Th ] = Threshold( image, t )
h=size(image,1);
w=size(image,2);
Th=zeros(h,w);
parfor i=1:h
    for j=1:w
        if image(i,j)>t
            Th(i,j)=1;
        else
            Th(i,j)=0;
        end
    end
end
end


function A = shiftAnglesFromMinus180To180(InA)

    %dont do anything to angles that are already in range
    %if we leave out this step, we get +180 shifted to -180
    idx = find(InA>180 | InA <-180);
    if(isempty(idx))
        A = InA;
    else
        A = InA;
        A(idx) = mod(InA(idx)+180,2*180)-180;  % input is in degrees
    end

end


%  INTERNAL FUNCTION: creates impact matrix for contemporaneous and future shocks
%
%  ::
%
%    M=stochastic_impact_cumulator(model,y0,nsteps)
%    M=stochastic_impact_cumulator(model,y0,nsteps,y_pos)
%    M=stochastic_impact_cumulator(model,y0,nsteps,y_pos,e_pos)
%    M=stochastic_impact_cumulator(model,y0,nsteps,y_pos,e_pos,states)
%    [M,ufkst,states,PAI,TT,Q]=stochastic_impact_cumulator(...)
%
%  Args:
%
%     - **model** [struct]:
%
%       - **T** [1 x h cell]: solution of the model,
%         T{regime}=[Ty,Tsig,Te_0,...Te_k]
%       - **sstate** [1 x h cell]: steady state in each regime
%       - **state_cols** [vector|{1:ny}]: location of state endogenous
%         variables in y0 (see below).
%       - **k** [scalar]: anticipation horizon (Beyond the current period)
%       - **Qfunc** [empty|function_handle]: endogenous transition matrix
%
%     - **y0** [ny x 1 vector]: initial conditions
%     - **nsteps** [integer]: number of forecast steps
%     - **y_pos** [vector]: location of restricted endogenous variables.
%     - **e_pos** [vector]: location of restricted shocks
%     - **states** [empty|nsteps x 1 vector]: states visited for each forecast
%       step.
%
%  Returns:
%     :
%
%     - **M** [struct]:
%
%       - **R** [matrix]: convoluted restrictions of shocks stemming from the
%         restrictions on endogenous variables
%       - **ufkst** [matrix]: unconditional forecasts for the restricted
%         endogenous variables (Excluding the initial conditions!!!).
%       - **const** [vector]: impact of the constant (steady state + risk) for
%         the restricted endogenous variables.
%       - **S** [matrix]: direct restrictions on shocks
%       - **nshocks** [integer]: number of shocks
%       - **ny** [integer]: number of endogenous variables
%
%     - **ufkst** [ny x (nsteps+1) matrix]: Unconditional forecasts mean (with
%       initial condition at the beginning!!!)
%     - **states** [nsteps x 1 vector]: regimes visited for each forecast step.
%     - **PAI** [h x nsteps matrix]: choice probabilities of regimes for each
%       step
%     - **TT** [matrix]: convolution of autoregressive terms for the
%       restrictions
%     - **Q** [h x h x nsteps array]: Time series of transition matrices
%
%


function [irf_record, D_record, gamma_record, struct_irf_record, irf_estimates, D_estimates, gamma_estimates, strshocks_record, strshocks_estimates]...
    =panel2irf(Ymat,Xmat,beta_gibbs,sigma_gibbs,It,Bu,IRFperiods,IRFband,N,n,m,p,k,T,Y,X,signreslabels,FEVDresperiods,data_exo,const,exo,IRFt,strctident,favar,signrestable,signresperiods)

% because there is only one model, there is no need to loop over units
% hence, estimate the IRFs for the model, as with a standard normal-Wishart
% first run the Gibbs sampler to obtain posterior draws
[irf_record]=bear.irf(beta_gibbs,It,Bu,IRFperiods,n,m,p,k);

% If IRFs have been set to an unrestricted VAR (IRFt=1):
if IRFt==1
% run a pseudo Gibbs sampler to obtain records for D and gamma (for the trivial SVAR)
[D_record, gamma_record]=bear.irfunres(n,It,Bu,sigma_gibbs);
struct_irf_record=[];
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(irf_record,n,IRFperiods,IRFband,IRFt,[],[],favar);

% If IRFs have been set to an SVAR with Choleski identification (IRFt=2):
elseif IRFt==2
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record, D_record, gamma_record]=bear.irfchol(sigma_gibbs,irf_record,It,Bu,IRFperiods,n,favar);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,n,IRFperiods,IRFband,IRFt,D_record,gamma_record,favar);

% If IRFs have been set to an SVAR with triangular factorisation (IRFt=3):
elseif IRFt==3
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record, D_record, gamma_record]=bear.irftrig(sigma_gibbs,irf_record,It,Bu,IRFperiods,n,favar);
% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,n,IRFperiods,IRFband,IRFt,D_record,gamma_record,favar);

% If IRFs have been set to an SVAR with sign restrictions (IRFt=4):
elseif IRFt==4
% run the Gibbs sampler to transform unrestricted draws into orthogonalised draws
[struct_irf_record,D_record,gamma_record]=bear.irfres_old(beta_gibbs,sigma_gibbs,It,Bu,IRFperiods,n,m,p,k,signrestable,signresperiods);
%[struct_irf_record,D_record,gamma_record]=bear.irfsignrespanel(beta_gibbs,sigma_gibbs,It,Bu,IRFperiods,n,p,m,k,signrestable,signresperiods);
%[struct_irf_record,D_record,gamma_record,~,~,~,~]=bear.irfres(beta_gibbs,sigma_gibbs,[],[],IRFperiods,n,m,p,k,T,[],[],signreslabels,FEVDresperiods,data_exo,HD,const,exo,strctident,pref,favar,IRFt,It,Bu);

% compute posterior estimates
[irf_estimates,D_estimates,gamma_estimates]=bear.irfestimates(struct_irf_record,n,IRFperiods,IRFband,IRFt,D_record,gamma_record,favar);

end

% also, if a s structural identification was implemented, compute structural shocks
strshocks_record={};
strshocks_estimates={};
if IRFt~=1
   % because shocks have to be computed for each unit, loop over units
   for ii=1:N
   % run the Gibbs sampler
   strshocks_record(:,:,ii)=bear.strshocks(beta_gibbs,D_record,Ymat(:,:,ii),Xmat(:,:,ii),n,k,It,Bu,favar);
   % obtain point estimates and credibility intervals
   strshocks_estimates(:,:,ii)=bear.strsestimates(strshocks_record(:,:,ii),n,T,IRFband);
   end
end


function fit_gls_brain(imgs, X, arorder, conditionnames, maskimg, varargin)
% Run Generalized Least Squares model with AR-model autoregression (optional)
% at each voxel in a set of images.
%
% :Usage:
% ::
%
%     fit_gls_brain(imgs, X, arorder, conditionnames, maskimg, ['contrasts', contrast_mtx, 'contrastnames', contrastnames], ['weights', weights])
%
% Single trial model to get trial amplitude, width, AUC, etc.
% Take one of those (e.g., AUC) and get a list of trial images
% Pass that into this function.
%
% fit_gls_brain(trial_amp_imgs, eventdesign{1}, contrasts
%
% You must add the intercept to X yourself if you want one!
%
% contrasts can be empty, and if it is, this function will write images
% for statistics on individual predictors.  If you enter contrast values,
% then it will write images for contrasts instead.
%
% conditionnames = column or contrast image names, in cell array
%
% e.g. eventnames{1} = {'high'    'medium'    'low'    'warm'}
%
% :Examples:
%
% This one looks @ significance for betas in X model:
% ::
%
%    load ../Multilev_mediation-try4(resliced)_10k/mediation_SETUP.mat
%    imgs = SETUP.data.M{1};
%    X = eventdesign{1};
%    arorder = 1;
%    contrasts = [];
%    conditionnames = eventnames{1};
%    maskimg = spm_select(1); % try gray matter mask...
%    fit_gls_brain(imgs, X, arorder, contrasts, conditionnames, maskimg)
%
% Now define contrasts and re-run on contrast values:
% ::
%
%    contrasts = [3 1 -1 -3; .25 .25 .25 .25; 1 0 0 -1]'
%    conditionnames = {'Linearpain' 'Average_resp' 'High-Low'};
%    fit_gls_brain(imgs, X, arorder, contrasts, conditionnames, maskimg)

    % ..
    %    Optional inputs
    % ..
    nobs = size(imgs, 1);
    weights = ones(nobs, 1);        % default weights
    contrasts = [];
    contrastnames = {};

    for i = 1:length(varargin)
        if ischar(varargin{i})
            switch varargin{i}
                % functional commands
                case 'contrasts', contrasts = varargin{i+1};

                case 'weights', weights = varargin{i+1};

                case 'contrastnames', contrastnames = varargin{i+1};

                otherwise, warning(['Unknown input string option:' varargin{i}]);
            end
        end
    end

    % Check weights
    wtol = max(sqrt(weights))*eps^(1/3);
    if any(weights == 0) || any(weights < wtol)
        fprintf('Some weights are too low or badly scaled. Setting zero weights to %3.4f\n.', wtol);
        weights(weights < wtol) = wtol;
    end

    W = diag(weights);

    % [t, df, beta/contrast, Phi, sigma,stebeta, F] =
    % fit_gls(y,X,c,p,[PX, equal to pinv(X), for speed])

    % Map mask image into space of imgs, if not already, and write
    % 'mask.img'
    scn_map_image(maskimg, imgs(1, :), 'write', 'mask.img');
    maskimg = 'mask.img';

    % Setup inputs and function handle
    % -------------------------------------------------------------
    wh = intercept(X, 'which');
    if isempty(wh), disp('Warning! No intercept found in model.'); end

    %PX = pinv(X);
    PX = inv(X' * W * X) * X' * W;  % General weighted

    % Check if X is OK
    condx = cond(X);
    fprintf('Condition number of design matrix: %3.2f\n', condx);
    if condx > 10000, error('Design matrix is not estimable!'); end

    fhandle = @(y) fit_gls(y, X, contrasts, arorder, PX, weights);

    % Setup output image names
    % -------------------------------------------------------------
    % [beta, t, pvals, convals, con_t, con_pvals, sigma, Phi, df, stebeta, conste, F]

    %if isempty(contrasts), betaconname = 'beta'; else betaconname = 'contrast'; end

    names = cell(1, 12);
    names{7} = 'sigma.img';
    names{8} = 'phi.img';
    names{9} = 'df.img';
    names{12} = 'omnibus_F.img';

    for i = [1:6 10:11]  % Potential Multi-image outputs
        for j = 1:length(conditionnames)
            switch i
                case 1
                    names{i} = char(names{i}, ['beta_' conditionnames{j} '.img']);
                case 2
                    names{i} = char(names{i}, ['t_' conditionnames{j} '.img']);
                case 3
                    names{i} = char(names{i}, ['p_' conditionnames{j} '.img']);

                case 10
                    names{i} = char(names{i}, ['ste_beta_' conditionnames{j} '.img']);

            end
        end

        for j = 1:length(contrastnames)
            switch i
                case 4
                    names{i} = char(names{i}, ['con_beta_' contrastnames{j} '.img']);
                case 5
                    names{i} = char(names{i}, ['con_t_' contrastnames{j} '.img']);
                case 6
                    names{i} = char(names{i}, ['con_p_' contrastnames{j} '.img']);
                case 11
                    names{i} = char(names{i}, ['ste_con_' contrastnames{j} '.img']);
            end
        end

    end

    for i = [1:6 10:11]
        names{i} = names{i}(2:end, :);
    end

    save fit_gls_brain_SETUP imgs X arorder contrasts names conditionnames contrastnames maskimg

    % Run
    % -------------------------------------------------------------
    [beta, t, pvals, convals, con_t, con_pvals, sigma, Phi, df, stebeta, conste, F] = ...
        image_eval_function(imgs, fhandle, 'mask', maskimg, 'outimagelabels' , names);

    % other optional args: 'outimagelabels' , 'connames'

end

% % %
% % %
% % %             [t, df, beta, Phi, sigma, stebeta] = fit_gls(h, trial2ndX, [], 1, trial2ndpx);
% % %
% % %             conditiont(i(k), j(k), :) = t;
% % %             conditionste(i(k), j(k), :) = stebeta;
% % %             conditionmean(i(k), j(k), :) = beta;
% % %             trialphi(i(k), j(k), :) = Phi;
% % %
% % %             conditionp(i(k), j(k), :) = 2 .* (1 - tcdf(abs(t), df));
% % %
% % %             if ~isempty(c)
% % %                 stecons = diag(c' * diag(stebeta).^2 * c).^.5;
% % %                 con_est = c' * beta;
% % %                 tcons = con_est ./ stecons;
% % %
% % %                 contrastest(i(k), j(k), :) = con_est;
% % %                 contrastt(i(k), j(k), :) = tcons;
% % %                 contrastste(i(k), j(k), :) = stecons;
% % %                 contrastp(i(k), j(k), :) = 2 .* (1 - tcdf(abs(tcons), df));
% % %             end
% % %
% % %
% % %             % 2nd-level estimation of ratings model with AR(1) model
% % %             % use first param, ignore intercept
% % %             % -------------------------------------------------------------
% % %             if exist('ratings','var')
% % %                 [t, df, beta, Phi, sigma, stebeta] = fit_gls(h, ratings, [], 1, ratingspx);
% % %
% % %                 % 1st col. is rating effect
% % %                 ratingsest(i(k), j(k), 1) = beta(1);
% % %                 ratingst(i(k), j(k), 1) = t(1);
% % %                 ratingsste(i(k), j(k), 1) = stebeta(1);
% % %                 ratingsp(i(k), j(k), 1) = 2 .* (1 - tcdf(abs(t(1)), df));
% % %
% % %                 % 2nd column is intercept
% % %                 intcptest(i(k), j(k), 1) = beta(2);
% % %                 intcptt(i(k), j(k), 1) = t(2);
% % %                 intcptste(i(k), j(k), 1) = stebeta(2);
% % %                 intcptp(i(k), j(k), 1) = 2 .* (1 - tcdf(abs(t(2)), df));
% % %
% % %             end
% % %         end
% % %
% % %         if k == 1000, fprintf(1, '%3.0f s per 1000 vox.', etime(clock, et)), end


function f_x = ParFor7(in1)
%PARFOR7
%    F_X = PARFOR7(IN1)

%    This function was generated by the Symbolic Math Toolbox version 8.1.
%    16-Jul-2019 11:57:27

u = in1(:,1);
uxx = in1(:,5);
f_x = (u.*9.981631376631412e-1+uxx.*9.965561702440027+u.*uxx.*1.006065455272619)./(u+9.978905414318433);


function e = dempot(x, mix)
%DEMPOT	Computes the negative log likelihood for a mixture model.
%
%	Description
%	This function computes the negative log of the unconditional data
%	density P(X) for a Gaussian mixture model.  The data structure MIX
%	defines the mixture model, while the matrix X contains the data
%	vectors.
%
%	See also
%	DEMGPOT, DEMHMC1, DEMMET1
%

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

% Computes the potential (negative log likelihood)
e = -log(gmmprob(mix, x));


function f_x = ParFor5(in1)
%PARFOR5
%    F_X = PARFOR5(IN1)

%    This function was generated by the Symbolic Math Toolbox version 8.1.
%    16-Jul-2019 11:57:25

u = in1(:,1);
uxx = in1(:,5);
f_x = (u.*9.981631376631412e-1+uxx.*9.965561702440027+u.*uxx.*1.006065455272619)./(u+9.978905414318433);


function signal = warmStartWithBadChRemoved(signal, pipe)

channel_mask = true(signal.nbchan, 1);
if any(strcmp(pipe.fltorder, 'flt_selchans'))
    mask = ismember({signal.chanlocs.labels}, pipe.pselchans.channels);
    if ~pipe.pselchans.remove_selection
        mask = ~mask; end
    channel_mask(mask) = 0;
end

%{
%% Bad channel detection
% define parameters
min_corr = 0.5;
ignored_quantile = 0.1;
window_len = 2;
max_broken_time = 0.4;
linenoise_aware = true;
rereferenced = false;
protect_channels = [];

% flag channels
if ~exist('removed_channel_mask','var')
    if max_broken_time > 0 && max_broken_time < 1  %#ok<*NODEF>
        max_broken_time = size(signal.data,2)*max_broken_time;
    else
        max_broken_time = signal.srate*max_broken_time;
    end

    [nChs,nPts] = size(signal.data);
    window_len = window_len*signal.srate;
    wnd = 0:window_len-1;
    offsets = round(1:window_len:nPts-window_len);
    W = length(offsets);
    retained = 1:(nChs-ceil(nChs*ignored_quantile));

    % optionally ignore both 50 and 60 Hz spectral components...
    if linenoise_aware && signal.srate > 110
        if signal.srate <= 130
            B = design_fir(500,[2*[0 45 50 55]/signal.srate 1],[1 1 0 1 1]);
        else
            B = design_fir(500,[2*[0 45 50 55 60 65]/signal.srate 1],[1 1 0 1 0 1 1]);
        end
        for c=signal.nbchan:-1:1
            X(:,c) = filtfilt_fast(B,1,signal.data(c,:)'); end
    else
        X = signal.data';
    end

    % optionally subtract common reference from data
    if rereferenced
        X = bsxfun(@minus,X,mean(X,2)); end

    % for each window, flag channels with too low correlation to any other channel (outside the
    % ignored quantile)
    flagged = zeros(nChs,W);
    for o=1:W
        sortcc = sort(abs(corrcoef(X(offsets(o)+wnd,:))));
        flagged(:,o) = all(sortcc(retained,:) < min_corr);
    end

    % mark all channels for removal which have more flagged samples than the maximum number of
    % ignored samples
    removed_channel_mask = sum(flagged,2)*window_len > max_broken_time;
    fprintf('Removing %i channels...',nnz(removed_channel_mask));
    disp({signal.chanlocs(removed_channel_mask==1).labels});

    % remove the channels in the protect list
    if ~isempty(protect_channels)
        removed_channel_mask(set_chanid(signal,protect_channels)) = true; end
end

% annotate the data with what was removed (for visualization)
if ~isfield(signal.etc,'clean_channel_mask')
    signal.etc.clean_channel_mask = true(1,signal.nbchan); end
signal.etc.clean_channel_mask(signal.etc.clean_channel_mask) = ~removed_channel_mask;
signal.etc.badChIndex = find(removed_channel_mask==1);
signal.etc.badChLabels = {signal.chanlocs(signal.etc.badChIndex).labels};
%}

%% Whitening !!! is this being used?
% rowmeans = mean(signal.data(channel_mask, :), 2);
% data = bsxfun(@minus,signal.data(channel_mask, :), rowmeans);
%
% [E,D] = eig ( data * data' / size(data, 2) );
% signal.icasphere = (sqrtm(D)\eye(sum(channel_mask))) * E';

%%


function varargout = coeffs2( f, varargin)
%COEFFS2   componentwise Fourier--Chebyshev coefficients of a DISKFUNV.
%
%   [X, Y] = COEFFS2( F ) returns the coefficients for each component of
%   the DISKFUNV F in the Fourier--Chebyshev bases, where the columns
%   are the Chebyshev coefficients and the rows are Fourier coefficients.
%
%
%   [X, Y] = COEFFS2(F, M, N) returns bivariate coefficients with N Chebyshev
%   coefficients in the radial direction and M Fourier coefficients in
%   angular direction.

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

%empty check
if isempty(f)
    varargout = {};
    return
end

F1 = f.components{1};
F2 = f.components{2};
if isempty(varargin)
    varargout{1} = coeffs2(F1);
    varargout{2} = coeffs2(F2);
else
    varargout{1} = coeffs2(F1, varargin{:});
    varargout{2} = coeffs2(F2, varargin{:});
end

end


function [CV,CT,TV,TT,w,SV,SF] = solid(V,F,varargin)
  % SOLID Clean a mesh using the generalized winding number pipeline with some
  % default settings [Jacobson et al. 2013]: "Shoot for the moon!!!!"
  %
  % [CV,CT] = solid(V,F)
  % [CV,CT] = solid(V,F,'ParameterName',ParameterValue,..)
  %
  % Inputs:
  %   V  #V by 3 input mesh positions
  %   F  #F by 3 list of triangle indices into V
  %   Optional:
  %     'SurfaceOnly' followed by whether to return CF  #CF by 3 list of
  %       surface triangle indices instead of CT, and remove rows unrefernced
  %       by CF from CV. Equivalent to running:
  %           [CV,CT] = winding_number_clean(V,F);
  %           CF = boundary_faces(CT);
  %           [CV,I] = remove_unreferenced(TV,CF)
  %           CF = I(CF);
  %       {false}.
  % Outputs:
  %   CV  #CV by 3 output mesh positions
  %   CT  #CT by 3 list of tet indices into CV
  %   TV  #TV by 3 list of tetrahedral mesh vertex positions
  %   TT  #TT by 3 list of tetrahedral mesh tet indices
  %   w  #TT list of winding numbers
  %   SV  #SV by 3 list of self-intersected "clean", but non-solid mesh indices
  %   SF  #SF by 3 list of triangle indices into SV
  %

  surface_only = false;
  % parse optional input parameters
  % Map of parameter names to variable names
  params_to_variables = containers.Map( {'SurfaceOnly'},{'surface_only'});
  v = 1;
  while v <= numel(varargin)
    param_name = varargin{v};
    if isKey(params_to_variables,param_name)
      assert(v+1<=numel(varargin))
      v = v+1;
      % Trick: use feval on anonymous function to use assignin to this workspace
      feval(@()assignin('caller',params_to_variables(param_name),varargin{v}));
    else
      error('Unsupported parameter: %s',varargin{v});
    end
    v=v+1;
  end

  % shoot for the moon with winding number on default settings
  [SV,SF] = clean(V,F,'Quiet',true,'Single',true);
  tetgen_flags_alts = {'-Y','-Y -T1e-16','','-T1e-16'};
  TT = [];
  for t = 1:numel(tetgen_flags_alts)
    tetgen_flags = tetgen_flags_alts{t};
    try
      [TV,TT] = cdt(SV,SF,'TetgenFlags',tetgen_flags,'Quiet',true);
      fprintf('cdt succeeded with "%s"...\n',tetgen_flags);
      break;
    catch
      fprintf('cdt failed with "%s"...\n',tetgen_flags);
    end
  end
  if isempty(TT)
    error('All tetgen flags alternatives failed');
  end
  w = winding_number(V,F,barycenter(TV,TT));
  vol = volume(TV,TT);
  avg_w = w'*(vol/sum(vol));
  if avg_w < 0
    fprintf('inside out?...\n');
    w = -w;
    avg_w = -avg_w;
  end
  CT = TT(w>avg_w,:);

  if surface_only
    CT = boundary_faces(CT);
  end
  [CV,I] = remove_unreferenced(TV,CT);
  CT = I(CT);

end


function color = get_new_color(i)

N = 8;
TWON = 2^N;

global GETNEWCOLOR___;
if isempty(GETNEWCOLOR___),
  GETNEWCOLOR___ = jet(TWON);
end
i = mod(i-1,TWON)+1;

if i == 1,
  color = GETNEWCOLOR___(1,:);
  return;
end
if i == 2,
  color = GETNEWCOLOR___(end,:);
  return;
end

total = 2;
for j = 1:8,
end

v = floor(linspace(1,256,total));
offset = i - (total - j);
l = v(2*offset);

color = GETNEWCOLOR___(l,:);


% minimum distance from nose of fly to ellipse of any other fly within 30
% degrees
function [data,units] = compute_dnose2ell_anglerange(trx,n,anglerange_str,varargin)

flies = trx.exp2flies{n};
nflies = numel(flies);
data = cell(1,nflies);

% name of closestfly stat
fn = sprintf('closestfly_nose2ell_angle_%sto%s',anglerange_str{:});

% access closestfly to ensure that dnose2ell_anglerange is computed
for i = 1:numel(flies),
  trx(flies(i)).(fn);
end
%compute_closestfly_nose2ell_anglerange(trx,n,anglerange,varargin{:});

% anglerange_deg = round(anglerange*180/pi);
% fn = sprintf('dnose2ell_angle_%dto%d',anglerange_deg(1),anglerange_deg(2));
% fn = strrep(fn,'-','min');

% name of dnose2ell stat
fn = sprintf('dnose2ell_angle_%sto%s',anglerange_str{:});

for i1 = 1:nflies,
  fly1 = flies(i1);
  data{i1} = trx(fly1).(fn);
end
units = parseunits('mm');


classdef testEnergyEquivalenceVoigtAndTensorNotationForIAniTensor ...
        < testEnergyEquivalenceVoigtAndTensorNotation

    methods (Access = public)

        function obj = testEnergyEquivalenceVoigtAndTensorNotationForIAniTensor()
            obj@testEnergyEquivalenceVoigtAndTensorNotation();
        end

    end

    methods

        function generateFourthOrderTensor(obj)
            obj.Ch = Stiffness3DTensor();
            obj.Ch.createRandomTensor();
        end

    end

end


function [ Sim QTot ] = computeAnimSimilarity( anim, method, ...
  varargin )
% Compute similarities between frames of a video sequence
%
% This routine computes:
%  - the pair infimum of CSFM if method = -2
%  - the best 2-view reconstruction in MSFM if method = 2
%  - the best 3-view reconstruction in MSFM if method = 3
%
% USAGE
%  [ Sim QTot ] = computeAnimSimilarity( anim, method, Sim )
%
% INPUTS
%  anim     - anim object (see GENERATETOYANIMATION for details)
%  method   - [2] uses pairs of frames, 3, uses triplets
%  varargin   - list of paramaters in quotes alternating with their values
%    for triadic comparison
%       'Sim2' pairwise similarity computed using method = 2
%       'perc' percentage of triplets to consider
%             ( only for speed purposes )
%
% OUTPUTS
%  Sim      - [ nFrame x nFrame ] or [ nFrame x nFrame x nFrame ]similarity
%             matrix based on total reconstruction error
%  QTot     - [ 4 x nFrame x nFrame ] optimal quaternions for pairwise
%
% EXAMPLE
%
% See also GENERATETOYANIMATION, VIEWANIMSIMILARITY
%
% Vincent's Structure From Motion Toolbox      Version 3.1.1
% Copyright (C) 2008-2011 Vincent Rabaud.  [vrabaud-at-cs.ucsd.edu]
% Please email me if you find bugs, or have suggestions or questions!
% Licensed under the GPL [see external/gpl.txt]

if ~isa(anim,'Animation'); error('anim must be of class Animation'); end
nFrame=anim.nFrame;

if nargin<2; method=2; end

% Compute the similarities
switch abs( method )
  case 2
    anim = anim.centerW();

    [ Sim, QTot ] = computeCsfmInfimum(anim.W);

    if method==2 % Best 2-view reconstruction for MSFM
      Sim = Sim/2;
    end

  case 3
    %%%%%%%% using triplets of frames for MSFM
    [ Sim2 perc ] = getPrmDflt( varargin, { 'Sim2' [] 'perc' 1 } );
    Sim = cell(1,nFrame); for i=1:nFrame; Sim{i}=sparse(nFrame,nFrame); end
    isDone = cell(1,nFrame); for i=1:nFrame; isDone{i}=sparse(nFrame,nFrame); end
    minSpan = 5;

    ticId = ticStatus( 'Triadic Computed' );

    % compute the probability to choose another frame given a frame in the triplet
    % basically, we'll pick one frame, and the 2 other frames according to that
    % probability. This one simply is proportional to the pairwise reconstruction
    % error (3 frames are more likely to be together if, pairwise, they look alike)
    probS = Sim2;

    % remove everything too close to each other
    toep = logical(spdiags(ones(nFrame,2*minSpan+1,-minSpan:minSpan, nFrame,nFrame)));
    probS(toep) = 0;

    % compute the cumulative sum and normalize by one
    probS = cumsum(Sim2,2);
    probS = bsxfun(@rdivide,probS,probS(:,end));

    % create as many triplets as necessary
    nDone = 0;
    while nDone/nFrame^3*100 < perc
      % choose two other frames according to the distribution
      % in probS and far enough from each other
      sample = randSample(nFrame,3);
      i1 = sample(1); i2 = sample(2); i3 = sample(3);
      if isDone{i1}(i2,i3) || min( pdist( sample' ) )<=minSpan; continue; end

      [ disc disc err ] = computeSMFromW( anim.isProj, ...
        anim.W(:,:, [ i1 i2 i3]), 'K', anim.K, 'method',Inf);

      perm = [ i1 i2 i3; i1 i3 i2; i3 i1 i2; i3 i2 i1; i2 i1 i3; ...
        i2 i3 i1 ];
      for l=1:6
        Sim{perm(l,1)}(perm(l,2),perm(l,3)) = err(1);
        isDone{perm(l,1)}(perm(l,2),perm(l,3)) = 1;
        nDone = nDone + 1;
      end
      if rand()>0.99
        tocStatus(ticId,min(perc,100*nDone/nFrame^3) / perc);
      end
    end
end


function [P,E,logw,acc] = spm_mci_ais_single_vl (mcmc,M,U,Y,vl)
% Produce a single independent sample from posterior using AIS
% FORMAT [P,E,logw,acc] = spm_mci_ais_single_vl (mcmc,M,U,Y,vl)
%
% mcmc      Sampling settings
% M         Model structure
% U         Input structure
% Y         Data
% vl        Variational Laplace solution
%               .Ep                 Posterior Mean
%               .Cp                 Posterior Covariance
%
% P         [Np x 1] sample
% E         Negative log joint
% logw      Contribution to model evidence
% acc       acc(j) is acceptance rate at temperature j
%__________________________________________________________________________
% Copyright (C) 2015 Wellcome Trust Centre for Neuroimaging

% Will Penny
% $Id: spm_mci_ais_single_vl.m 6548 2015-09-11 12:39:47Z will $

beta=mcmc.beta;
nprop=mcmc.nprop;
prop=mcmc.prop;
scale=mcmc.scale;

J=length(beta);

% Sample from VL posterior (in subspace)
x(:,1) = spm_normrnd (vl.mr,vl.Cr,1);
[L(1),L2] = spm_mci_joint (x(:,1),M,U,Y);

% Sample in original space
xorg = M.V*x(:,1)+M.vpE;
e = xorg - vl.Ep;
log_pvl = vl.const - 0.5*e'*vl.Lambdap*e;
Lsum = (beta(1)-beta(2))*log_pvl+(beta(2)-beta(1))*L(1);

acc(1) = 1;
for j=2:J,
    xs=x(:,j-1); Ls=L(:,j-1);acc(j)=0;

    % Generate sample at next temperature using
    % Langevin Monte Carlo
    lgv_mcmc.init=xs;
    lgv_mcmc.maxits=nprop;

    [tmp,stats] = spm_mci_lgv_vl (lgv_mcmc,M,U,Y,vl,beta(j));

    xs = stats.P(:,end);
    Ls = -stats.E(:,end);
    L2 = stats.L2(end);
    acc (j) = any(stats.acc(2:end));

    x(:,j)=xs;
    L(j)=Ls;
    if j < J
        xorg = M.V*x(:,j)+M.vpE;
        e = xorg - vl.Ep;
        log_pvl = vl.const - 0.5*e'*vl.Lambdap*e;
        Lsum = Lsum + (beta(j)-beta(j+1))*log_pvl+(beta(j+1)-beta(j))*L(j);
    end
end
logw=Lsum;
P=x(:,J);
E=-L(J);

if mcmc.rec_traj
    nj=size(x,2);
    traj=spm_vec(M.pE)*ones(1,nj)+V*x;
else
    traj=[];
end


function [gammaAngle, betaAngle, alphaAngle] = getAnglesFromInertialBodyAxes_Func(dcm, ut, rVect, vVect, bodyInfo, baseFrame)
    ce = CartesianElementSet(ut, rVect(:), vVect(:), bodyInfo.getBodyCenteredInertialFrame());
    [~, ~, ~, base_frame_2_inertial] = baseFrame.getOffsetsWrtInertialOrigin(ut, ce);

    angles = rotm2eulARH(base_frame_2_inertial' * dcm, 'zyx');

    angles = real(angles);

    gammaAngle = angles(3);
    betaAngle = angles(2);
    alphaAngle = angles(1);
end


function [geph,stat]=decode_geph(ver,sat,toc,data)
global glc gls

geph=gls.geph;
stat=1;

[sys,~]=satsys(sat);
if sys~=glc.SYS_GLO
    stat=0;return;
end

geph.sat=sat;

% toc rounded by 15 min in utc
[week,tow]=time2gpst(toc);
toc=gpst2time(week,floor((tow+450)/900)*900);
dow=fix(floor(tow/86400));

% time of frame in utc
if ver<=2.99
    tod=data(3);
else
    tod=rem(data(3),86400);
end
tof=gpst2time(week,tod+dow*86400);
tof=adjday(tof,toc);

geph.toe=utc2gpst(toc);
geph.tof=utc2gpst(tof);

geph.iode=fix(rem(tow+10800,86400)/900+0.5);

geph.taun=-data(1);
geph.gamn=data(2);

geph.pos=[data(4);data(8);data(12)]*1e3;
geph.vel=[data(5);data(9);data(13)]*1e3;
geph.acc=[data(6);data(10);data(14)]*1e3;

geph.svh=fix(data(7));
geph.frq=fix(data(11));
geph.age=fix(data(15));

% some receiver output >128 for minus frequency number
if geph.frq>128
    geph.frq=geph.frq-256;
end

return


function g = linearOutputGrad(model, X, dim)

% LINEAROUTPUTGRAD Evaluate derivatives of linear model outputs with respect to parameters.
%
% MODIFICATIONS : Carl Henrik Ek, 2009
%
% MLTOOLS

numData = size(X, 1);
if(nargin<=2)
  for i = 1:model.outputDim
    startZeros = zeros(numData, model.inputDim*(i - 1));
    finishZeros = zeros(numData, model.inputDim*(model.outputDim-i));
    startZeros2 = zeros(numData, (i - 1));
    finishZeros2 = zeros(numData, (model.outputDim-i));
    g(:, :, i) = [startZeros X finishZeros startZeros2 ones(numData, 1) finishZeros2];
  end
else
  g(:,:) = [X ones(numData,1)];
end


% This is material illustrating the methods from the book
% Financial Modelling  - Theory, Implementation and Practice with Matlab
% source
% Wiley Finance Series
% ISBN 978-0-470-74489-5
%
% Date: 02.05.2012
%
% Authors:  Joerg Kienitz
%           Daniel Wetterau
%
% Please send comments, suggestions, bugs, code etc. to
% kienitzwetterau_FinModelling@gmx.de
%
% (C) Joerg Kienitz, Daniel Wetterau
%
% Since this piece of code is distributed via the mathworks file-exchange
% it is covered by the BSD license
%
% This code is being provided solely for information and general
% illustrative purposes. The authors will not be responsible for the
% consequences of reliance upon using the code or for numbers produced
% from using the code.

function y = putpayoff(S,Strike)
% payoff of a European put option
    y =  max(Strike - S, 0);
end


function K = kuratowski_subgraph(A,varargin)
% KURATOWSKI_SUBGRAPH Identify a Kuratowski subgraph
%
% K = kuratowski_subgraph(A) is just a wrapper around the
% boyer_myrvold_planarity_test to get the subgraph as the first output
% argument.
%
% K is empty if the graph A is planar.
%
% Example:
%   A = clique_graph([3,3]); % Generate K_3,3
%   K = kuratowski_subgraph(A);
%   isequal(A,K) % K_3,3 is a Kuratowski graph!

% David Gleich
% Copyright, Stanford University, 2008

%% History
%  2007-09-29: Initial coding
%%

[is_planar K] = boyer_myrvold_planarity_test(A,varargin{:});


function [text,AIC,BIC]=egarch_display(parameters,ll,vcv,data,p,o,q,errorType)
% Display parameters, tstats, pvals, log-likelihood and AIC/BIC
% from estimates of a EGARCH(P,O,Q) produced using egarch
%
% USAGE:
%   [TEXT] = egarch_display(PARAMETERS,LL,VCV,DATA,P,O,Q)
%   [TEXT,AIC,BIC] = egarch_display(PARAMETERS,LL,VCV,DATA,P,O,Q,ERRORTYPE)
%
% INPUTS:
%   PARAMETERS    - A 1+p+o+q column vector of parameters with
%                   [omega alpha(1) ... alpha(p) gamma(1) ... gamma(o) beta(1)
%                       ... beta(q) [nu lambda]]'
%   LL            - The log likelihood at the optimum
%   VCV           - Non-robust standard errors (inverse Hessian)
%   DATA          - A column of mean zero data
%   P             - Positive, scalar integer representing the number of
%                   symmetric innovations
%   O             - Non-negative scalar integer representing the number
%                   of asymmetric innovations (0 for symmetric processes)
%   Q             - Non-negative, scalar integer representing the number
%                   of lags of conditional variance (0 for ARCH)
%   ERRORTYPE     - [OPTIONAL] The error distribution used, valid types are:
%                     'NORMAL'    - Gaussian Innovations [DEFAULT]
%                     'STUDENTST' - T distributed errors
%                     'GED'       - Generalized Error Distribution
%                     'SKEWT'     - Skewed T distribution
%
% OUTPUTS:
%   TEXT          - Character matrix with the formatted parameters of the model
%   AIC           - Aikake Information Criteria computed from the LL
%   BIC           - Schwartz/Bayesian Information Criteria computed from the LL
%
%  See also EGARCH

% Copyright: Kevin Sheppard
% kevin.sheppard@economics.ox.ac.uk
% Revision: 3    Date: 9/1/2005

%%%%%%%%%%%%%%%%%%%%%%%%%%
% PARAMETER CHECKING
%%%%%%%%%%%%%%%%%%%%%%%%%%
switch nargin
    case 5
        o=0;
        q=0;
        errorType='NORMAL';
    case 6
        q=0;
        errorType='NORMAL';
    case 7
        errorType='NORMAL';
    case 8
    otherwise
        error('5 to 8 inputs required')
end
if nargin==7
elseif nargin==8
    errorType='NORMAL';
end
if isempty(errorType)
    errorType='NORMAL';
end
% parameters, N by 1, real
if any(~isreal(parameters)) || size(parameters,2)~=1
    error('PARAMETERS must be a column vector.')
end
% LL
if ~isscalar(ll) || ~isreal(ll)
    error('LL must be a scalar.')
end
% VCV
if size(vcv,2)~=size(vcv,1) || any(min(eig(vcv))<=0) || size(vcv,1)~=length(parameters)
    error('VCV must be a square positive definite matrix compatible with PARAMETERS.')
end
% data
if any(~isreal(data)) || size(data,2)~=1
    error('DATA must be a T by 1 column vector.')
end
% p
if ~isscalar(p) || p<1 || floor(p)~=p
    error('P must be a postitive scalar integer')
end
% o
if ~isscalar(o) || o<0 || floor(o)~=o
    error('O must be a non-negative scalar integer')
end
% q
if ~isscalar(q) || q<0 || floor(q)~=q
    error('Q must be a non-negative scalar integer')
end
% errorType
if ~ischar(errorType)
    errorType=[];
end
switch errorType
    case 'NORMAL'
        errorType=1;
        extraP=0;
    case 'STUDENTST'
        errorType=2;
        extraP=1;
    case 'GED'
        errorType=3;
        extraP=1;
    case 'SKEWT'
        errorType=4;
        extraP=2;
    otherwise
        error('ERRORTYPE is not one of the supported distributions')
end
if length(parameters)~=(1+p+o+q+extraP)
    error('Size of PARAMETERS is not compatible with input P, O, Q')
end
%%%%%%%%%%%%%%%%%%%%%%%%%%
% PARAMETER CHECKING
%%%%%%%%%%%%%%%%%%%%%%%%%%

model_name = ['EGARCH(' num2str(p) ',' num2str(o) ',' num2str(q) ')'];

parameters_text=num2str(parameters,'%4.4f');
stderr=sqrt(diag(vcv));
stderr_text=num2str(stderr,'%4.4f');
tstats=parameters./stderr;
tstats_text=num2str(tstats,'%4.4f');
pvals=2-2*normcdf(abs(tstats));
pvals_text=num2str(pvals,'%4.4f');

T=length(data);
AIC = -ll/T+2*length(parameters)/T;
BIC = -ll/T+log(T)*length(parameters)/T;

% Format the output
text=[];
text{1,1}= ' ';
text{2,1}= ' ';
text{3,1}=repmat('-',1,50);
text{4,1}=model_name;
text{5,1}=repmat('-',1,50);
text{6,1}=' ';
text{7,1}=['Loglikelihood: ' sprintf('%1.2f',ll)];
text{8,1}=['AIC: ' sprintf('%1.4f',AIC)];
text{9,1}=['BIC: ' sprintf('%1.4f',BIC)];
text{10,1}=' ';

for i=1:size(text,1);
    disp(text{i,1})
end

% Format the parameter table, need to right align everything
K=size(parameters_text,1);
for i=1:K
    N=size(parameters_text,2);
    if any(parameters_text(i,:)==' ')
        numSpace=sum(parameters_text(i,:)==' ');
        parameters_text(i,:)=[repmat(' ',1,numSpace) parameters_text(i,1:N-numSpace)];
    end
    N=size(stderr_text,2);
    if any(stderr_text(i,:)==' ')
        numSpace=sum(stderr_text(i,:)==' ');
        stderr_text(i,:)=[repmat(' ',1,numSpace) stderr_text(i,1:N-numSpace)];
    end
    N=size(tstats_text,2);
    if any(tstats_text(i,:)==' ')
        numSpace=sum(tstats_text(i,:)==' ');
        tstats_text(i,:)=[repmat(' ',1,numSpace) tstats_text(i,1:N-numSpace)];
    end
    N=size(pvals_text,2);
    if any(pvals_text(i,:)==' ')
        numSpace=sum(pvals_text(i,:)==' ');
        pvals_text(i,:)=[repmat(' ',1,numSpace) pvals_text(i,1:N-numSpace)];
    end
end
% Append column labels
labels={' Parameters','   Std. Err.','     T-stat','      P-val'};
cols = {parameters_text,stderr_text,tstats_text,pvals_text};
for i=1:length(labels);
    text1=labels{i};
    text2=cols{i};
    maxcols=max(size(text1,2),size(text2,2));
    if size(text1,2)<maxcols
        labels{i} = [repmat(' ',1,maxcols-size(text1,2)) text1 ];
    end
    if size(text2,2)<maxcols
        cols{i} = [repmat(' ',size(text2,1),maxcols-size(text2,2)) text2 ];
    end
end

% Finally variable names
variable_names=cell(length(parameters),1);
variable_names{1}='omega';
index=2;
for i=1:p
    variable_names{index}=['alpha(' num2str(i) ')'];
    index=index+1;
end
for i=1:o
    variable_names{index}=['gamma(' num2str(i) ')'];
    index=index+1;
end
for i=1:q
    variable_names{index}=['beta(' num2str(i) ')'];
    index=index+1;
end

maxVarNameLength=max(cellfun('length',variable_names));
for i=1:length(variable_names)
    variable_names{i} = [repmat(' ',1,maxVarNameLength-length(variable_names{i})) variable_names{i}];
end
variable_names=cell2mat(variable_names(:));

% Output the parameters
outmat=strvcat(' ',variable_names);
for i=1:4
    outmat=[outmat repmat('  ',size(outmat,1),1) strvcat(labels{i},cols{i})];
end

text2=[];
for i=1:length(text)
    text2=strvcat(text2,text{i});
end
text=strvcat(text2,outmat);

disp(outmat)


function h=plotgeometry(geo,angle)
%PLOTGEOMETRY(GEO,ANGLE) plots a simplified version of the CBCT geometry with the
% given geomerty GEO and angle ANGLE. If angle is not given, 0 will be chosen.
%
% h=PLOTGEOMETRY(...) will return the figure handle
%--------------------------------------------------------------------------
%--------------------------------------------------------------------------
% This file is part of the TIGRE Toolbox
%
% Copyright (c) 2015, University of Bath and
%                     CERN-European Organization for Nuclear Research
%                     All rights reserved.
%
% License:            Open Source under BSD.
%                     See the full license at
%                     https://github.com/CERN/TIGRE/blob/master/LICENSE
%
% Contact:            tigre.toolbox@gmail.com
% Codes:              https://github.com/CERN/TIGRE/
% Coded by:           Ander Biguri
%--------------------------------------------------------------------------
if nargin<2
    angle=0;
end
angle=angle*180/pi;
%% Figure stuff
h=figure('Name','Cone Beam Compute Tomography geometry');
hold on
title('Current CBCT geometry, in scale')
xlabel('X');
ylabel('Y');
zlabel('Z');
set(gcf, 'color', [1 1 1])

%% CUBE/Image

drawCube(geo.offOrigin,geo.sVoxel,'k',0.05,0);

%% Detector
drawCube([-geo.DSD+geo.DSO; geo.offDetector],[1; geo.sDetector],'r',1,angle)
plotCircle3D([0 0 0],-geo.DSD+geo.DSO);
%% source
p=plot3(geo.DSO,0,0,'.','MarkerSize',30);
rotate(p,[0  0  1],angle,[0 0 0]);
plotCircle3D([0 0 0],geo.DSO);

%% Arrows.
arrow=geo.sVoxel;
%XYZ arrows
try
arrow3d([0 arrow(1)],[0 0],[0 0],.90,5,15,'r');
arrow3d([0 0],[0 arrow(2)],[0 0],.90,5,15,'b');
arrow3d([0 0],[0 0],[0 arrow(3)],.90,5,15,'g');
catch e
    error('CBCT:plotgeometry:Arrow','arrow3D not found, make sure its added to the path');
end
%UV arrows

%%
axis equal;
view(128,26)
% grid on
% axis off;

end
function drawCube( origin, size,color,alpha,a)
% From
% http://www.mathworks.com/matlabcentral/newsreader/view_thread/235581

x=([0 1 1 0 0 0;1 1 0 0 1 1;1 1 0 0 1 1;0 1 1 0 0 0]-0.5)*size(1)+origin(1);
y=([0 0 1 1 0 0;0 1 1 0 0 0;0 1 1 0 1 1;0 0 1 1 1 1]-0.5)*size(2)+origin(2);
z=([0 0 0 0 0 1;0 0 0 0 0 1;1 1 1 1 0 1;1 1 1 1 0 1]-0.5)*size(3)+origin(3);
for i=1:6
    h=patch(x(:,i),y(:,i),z(:,i),color);
    set(h,'facealpha',alpha)
    rotate(h,[0 0 1],a,[0 0 0]);
end

end

function plotCircle3D(center,radius)

theta=0:0.1:2*pi;
v=null([0 0 1]);
points=repmat(center',1,size(theta,2))+radius*(v(:,1)*cos(theta)+v(:,2)*sin(theta));
plot3(points(1,:),points(2,:),points(3,:),'k-.');

end


function obj = addHolonomicConstraint(obj, constr, load_path)
    % Adds a holonomic constraint to the dynamical system
    %
    %
    % Parameters:
    % constr: the expression of the constraints @type HolonomicConstraint
    % load_path: the path from which the symbolic expressions for the
    % input map can be loaded @type char
    %
    % @note Any holonomic constraint introduces a set of constrained
    % wrenchs to the system (Lagrangian multiplier).

    % validate input argument
    validateattributes(constr, {'HolonomicConstraint'},...
        {},'ContinuousDynamics', 'HolonomicConstraint');

    n_constr = numel(constr);

    for i=1:n_constr
        c_obj = constr(i);
        c_name = c_obj.Name;

        if isfield(obj.HolonomicConstraints, c_name)
            error('The holonomic constraint (%s) has been already defined.\n',c_name);
        else

            % add virtual constraint
            obj.HolonomicConstraints.(c_name) = c_obj;

            % add constant parameters
            obj = addParam(obj, c_obj.ParamName, c_obj.Param);
            Jh = c_obj.ConstrJac;
            if ~exist('load_path','var')
                obj = addInput(obj, 'ConstraintWrench', c_obj.InputName, c_obj.Input, transpose(Jh));
            else
                obj = addInput(obj, 'ConstraintWrench', c_obj.InputName, c_obj.Input, transpose(Jh),'LoadPath',load_path);
            end
        end

    end

end


function [wmProb,faErr,mdErr,eigVal] = dtiFindWhiteMatter(eigVal,b0,xformToAcpc)
%
%  wmProb = dtiFindWhiteMatter(dt6_or_eigVals,b0,[xformToAcpc])
%
% Example usage:
% b0=niftiRead('dti06/bin/b0.nii.gz');
% b0 = double(b0.data);
% dt6=niftiRead('dti06/bin/tensors.nii.gz');
% dt6 = double(squeeze(dt6.data(:,:,:,1,[1 3 6 2 4 5])));
% wmProb = dtiFindWhiteMatter(dt6,b0);
% dtiWriteNiftiWrapper(uint8(round(wmProb*255)),xformToAcpc,'dti06/bin/wmProb.nii.gz',1./255)
%
% HISTORY:
% 2007.07.24 RFD: wrote it.

% This var isn't used any more, but many callers pass it in.
if(~exist('xformToAcpc','var')), xformToAcpc = []; end

finalThresh = 0.5;
histClipB0 = false;

targetMd = [0.6 1.0]; % in micrometers^2/msec
targetFa = [0.4 1.0];

if(~isempty(b0))
   if(~isa(b0,'double'))
      b0 = double(b0);
   end
   % Make sure the b0 is histogram clipped
   if(max(b0(:))>1)
      b0 = mrAnatHistogramClip(b0,0.4,0.99);
   end
end
%templateFile = which('whiteMatter.nii.gz');

% Ensure diffusivity units are in micrometers^2/msec
[curUnitStr,scale] = dtiGuessDiffusivityUnits(eigVal);
eigVal = eigVal.*scale;
if(size(eigVal,4)==6)
    [eigVec,eigVal] = dtiEig(eigVal);
    clear eigVec;
end

%% Compute FA Error term
[fa,md] = dtiComputeFA(eigVal);
faErr = zeros(size(fa));
faErr(fa<targetFa(1)) = (targetFa(1)-fa(fa<targetFa(1)))./targetFa(1);
faErr(fa>targetFa(2)) = (fa(fa>targetFa(2))-targetFa(2))./targetFa(2);
faErr(faErr>1) = 1;
faErr(isnan(faErr)) = 1;

% things with bogus fa>=1 values are always bad
%faErr(fa>=1) = 1;

%% Compute MD Error term
% TODO: ensure md is in micrometers^2/msec!
mdErr = zeros(size(md));
mdErr(md<targetMd(1)) = (targetMd(1)-md(md<targetMd(1)))./targetMd(1);
mdErr(md>targetMd(2)) = (md(md>targetMd(2))-targetMd(2))./targetMd(2);
mdErr(mdErr>1) = 1;
mdErr(isnan(mdErr)) = 1;

%% Compute location prior from a template
%locPriorNi = niftiRead(templateFile);
sz = size(faErr);
%xf = locPriorNi.qto_ijk*xform;
%[sampZ,sampY] = meshgrid([1:sz(2)],[1:sz(1)]);
%sampY = sampY(:); sampZ = sampZ(:);
%coords = mrAnatXformCoords(xf,[ones(size(sampY)) sampY sampZ]);
%locPrior = dtiSMooth3(locPrior,7);
% TODO: get a location prior.
locPrior = ones(sz);

if(~isempty(b0))
    %% Compute the b0 error.
    % Since the b0 intensity scale is arbitrary, we'll use the info we have so
    % far to get an empirical estimate of the desired b0 range. We assume that
    % the b0 within the target region is roughly uniform, a safe assumption
    % for all white matter regions.
    %
    % The b0 adds an important check against artifacts, since certain common
    % anatomical features (such as large sinuses) create very low b0 values,
    % but the FA is high and MD is often within the normal tissue range.
    %
    % Get an initial estimate based on current maps
    img = (1-faErr).*(1-mdErr).*locPrior;
    curGuess = img>finalThresh*0.95;

    % We want to be sure to remove the junk outside the brain. We do
    % that with a hard mask based on normalized b0 intensity.
    brainMask = dtiCleanImageMask(mrAnatHistogramClip(b0,0.4,0.99)>0.4);
    curGuess = curGuess&brainMask;

    mnB0 = mode(b0(curGuess(:)));
    stdB0 = std(b0(curGuess(:)));
    % b0Err is essentially a z-score clipped at ~4SDs and normalized to the 0-1
    % range. We clip and normalize symmetrically (with 'abs').
    b0Err = abs((b0-mnB0)./stdB0);
    if(histClipB0)
       b0Err(b0Err>7) = 7;
       b0Err = b0Err-5;
       b0Err(b0Err<0) = 0;
       b0Err = b0Err./2;
    else
       b0Err(b0Err>5) = 5;
       b0Err = b0Err-1;
       b0Err(b0Err<0) = 0;
       b0Err = b0Err./4;
    end
else
    b0Err = 0;
end

%% Compute the final score
wmProb = (1-faErr).*(1-mdErr).*(1-b0Err).*locPrior;

return;


function sources_to_keep = update_sources(qs,sources,addhull_sources);

p = size(sources,2);
% put the sources to add at the end of the list of sources
sources_diff = 1:size(sources,1);
sources_diff(addhull_sources) = [];
sources_to_keep = sources([ sources_diff ],:);
sources_to_add = sources([ addhull_sources ],:);
ltoadd = size(sources_to_add,1);
ltokeep = size(sources_to_keep,1);

while ~isempty(sources_to_add)
    % at each iteration, take one of the sources to add, remove it and add
    % all parents, then check descendants
    rest_of_sources = [sources_to_keep; sources_to_add(2:end,:)];
    local_to_add = sources_to_add(1,:) ;
    toadd  = add_one_source_c(int32(rest_of_sources'),int32(local_to_add),int32(qs));

%     toadd_old = [];
%     for i=1:p
%         temp  = local_to_add;
%         if (temp(i)<qs(i))   % has not reached the end of the dimension
%             temp(i) = temp(i)+1;
%             % check that temp is not a descendant of any sources
%             if ~any(all( rest_of_sources - repmat(temp,ltoadd+ltokeep-1,1)<=0,2))
%                 toadd_old = [ toadd_old;  temp];
%             end
%         end
%     end
%
%     if (size(toadd,1)~=size(toadd_old,1)), keyboard; end
%         toadd
%         toadd_old
%         pause
        sources_to_keep = [ sources_to_keep; toadd ];
        sources_to_add(1,:) = [];
        ltoadd = size(sources_to_add,1);
        ltokeep = size(sources_to_keep,1);
    end


function x = add_dc(y,dc,columns)
%ADD_DC Add DC channel to signals.
%   X = ADD_DC(Y,DC) adds the specified DC value to the (possibly
%   multi-dimensional) signal Y, returning the result as X. DC should be a
%   scalar value.
%
%   X = ADD_DC(Y,DC,'columns') where Y is a 2D matrix and DC is an array of
%   length size(Y,2), treats the columns of Y as individual 1D signals,
%   adding to each one the corresponding DC value from the DC array. X is
%   the same size as Y and contains the resulting signals.
%
%   See also REMOVE_DC.

%  Ron Rubinstein
%  Computer Science Department
%  Technion, Haifa 32000 Israel
%  ronrubin@cs
%
%  April 2009

if (nargin==3 && strcmpi(columns,'columns')), columns = 1;
else columns = 0;
end

if (columns)
  x = addtocols(y,dc);
else
  x = y + dc;
end


function p1 = gibbs(p1, x)
%GIBBS      Gibbs sampling
%
%           Description
%           P1 = GIBBS(P1, X) Samples one sample for parameters
%           contained in structure P1 at level n and and gets a
%           parameter structure X from level n-1 in hierarchy.
%           Returns a structure P1 containing new samples for
%           parameters in structure P1.
%
%           If P1 contains higher level parameters, e.g P1 =
%           net.p.w{1} and though there is a field P1.p, the
%           function calls itself to sample for those higher level
%           parameters also. So function takes care of the whole
%           hierarchical structure of ARD if called for the lowest
%           level parameters.

% Copyright (c) 1999-2003 Aki Vehtari

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

%Matlab 6.5
%if any(strcmp(fieldnames(p1),'p')) & ~isempty(p1.p) %isfield(p1,'p')
%  for a = fieldnames(p1.a)';
%    a=a{:};
%    if any(strcmp(fieldnames(p1.p),a)) %isfield(p1.p,a);
%      p2=p1.p.(a);
%      % call the spesified distribution sampler
%      p1.a.(a)=feval(['cond_' p1.f '_' p2.f],a,p1.a,p2.a,x);
%      % sample the upper level parameters
%      p1.p.(a)=gibbs(p2, p1.a.(a));
%    end
%  end
%end

% Pre matlab 6.5
S.type='.';
if any(strcmp(fieldnames(p1),'p')) & ~isempty(p1.p) %isfield(p1,'p')
  for a = fieldnames(p1.a)';
    a=a{:};
    S.subs=a;
    if any(strcmp(fieldnames(p1.p),a)) %isfield(p1.p,a);
      p2=subsref(p1.p,S);
      p1.a=subsasgn(p1.a, S, feval(['cond_' p1.f '_' p2.f],a,p1.a,p2.a,x));
      p1.p=subsasgn(p1.p, S, gibbs(p2, subsref(p1.a,S)));
    end
  end
end