function [p,msg] = spm_eeval(str,Type,n,m)
% Expression evaluation
% FORMAT [p,msg] = spm_eeval(str,Type,n,m)
% Str  - Expression to work with
%
% Type - type of evaluation
%      - 's'tring
%      - 'e'valuated string
%          - 'n'atural numbers
%          - 'w'hole numbers
%          - 'i'ntegers
%          - 'r'eals
%      - 'c'ondition indicator vector
%
% n ('e', 'c' & 'p' types)
%          - Size of matrix requred
%          - NaN for 'e' type implies no checking - returns input as evaluated
%          - length of n(:) specifies dimension - elements specify size
%          - Inf implies no restriction
%          - Scalar n expanded to [n,1] (i.e. a column vector)
%            (except 'x' contrast type when it's [n,np] for np
%          - E.g: [n,1] & [1,n] (scalar n) prompt for an n-vector,
%                         returned as column or row vector respectively
%                 [1,Inf] & [Inf,1] prompt for a single vector,
%                         returned as column or row vector respectively
%                 [n,Inf] & [Inf,n] prompts for any number of n-vectors,
%                         returned with row/column dimension n respectively.
%                 [a,b] prompts for an 2D matrix with row dimension a and
%                         column dimension b
%                 [a,Inf,b] prompt for a 3D matrix with row dimension a,
%                         page dimension b, and any column dimension.
%          - 'c' type can only deal with single vectors
%          - NaN for 'c' type treated as Inf
%          - Defaults (missing or empty) to NaN
%
% m ('n', 'w', 'n1', 'w1', 'bn1' & 'bw1' types)
%          - Maximum value (inclusive)
%
% m ('r' type)
%          - Maximum and minimum values (inclusive)
%
% m ('c' type)
%       - Number of unique conditions required by 'c' type
%          - Inf implies no restriction
%          - Defaults (missing or empty) to Inf - no restriction
%
% p     - Result
%
% msg   - Explanation of why it didn't work
%
%_______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Andrew Holmes
% $Id: spm_eeval.m 4439 2011-08-25 17:47:07Z guillaume $

if nargin<4, m=[]; end
if nargin<3, n=[]; end
if nargin<2, Type='e'; end
if nargin<1, str=''; end
if isempty(str), p='!'; msg='empty input'; return, end
switch lower(Type)
case 's'
    p = str; msg = '';
case 'e'
    p = evalin('base',['[',str,']'],'''!''');
    if ischar(p)
        msg = 'evaluation error';
    else
        [p,msg] = sf_SzChk(p,n);
    end
case 'n'
    p = evalin('base',['[',str,']'],'''!''');
    if ischar(p)
        msg = 'evaluation error';
    elseif any(floor(p(:))~=p(:)|p(:)<1) || ~isreal(p)
        p='!'; msg='natural number(s) required';
    elseif ~isempty(m) && any(p(:)>m)
        p='!'; msg=['max value is ',num2str(m)];
    else
        [p,msg] = sf_SzChk(p,n);
    end
case 'w'
    p = evalin('base',['[',str,']'],'''!''');
    if ischar(p)
        msg = 'evaluation error';
    elseif any(floor(p(:))~=p(:)|p(:)<0) || ~isreal(p)
        p='!'; msg='whole number(s) required';
    elseif ~isempty(m) && any(p(:)>m)
        p='!'; msg=['max value is ',num2str(m)];
    else
        [p,msg] = sf_SzChk(p,n);
    end
case 'i'
    p = evalin('base',['[',str,']'],'''!''');
    if ischar(p)
        msg = 'evaluation error';
    elseif any(floor(p(:))~=p(:)) || ~isreal(p)
        p='!'; msg='integer(s) required';
    else
        [p,msg] = sf_SzChk(p,n);
    end
case 'p'
    p = evalin('base',['[',str,']'],'''!''');
    if ischar(p)
        msg = 'evaluation error';
    elseif length(setxor(p(:)',m))
        p='!'; msg='invalid permutation';
    else
        [p,msg] = sf_SzChk(p,n);
    end
case 'r'
    p = evalin('base',['[',str,']'],'''!''');
    if ischar(p)
        msg = 'evaluation error';
    elseif ~isreal(p)
        p='!'; msg='real number(s) required';
    elseif ~isempty(m) && ( max(p)>max(m) || min(p)<min(m) )
        p='!'; msg=sprintf('real(s) in [%g,%g] required',min(m),max(m));
    else
        [p,msg] = sf_SzChk(p,n);
    end
case 'c'
    if isempty(m), m=Inf; end
    [p,msg] = icond(str,n,m);

otherwise
    error('unrecognised type');
end
return;

function [i,msg] = icond(i,n,m)
if nargin<3, m=Inf; end
if nargin<2, n=NaN; end
if any(isnan(n(:)))
    n=Inf;
elseif (length(n(:))==2 & ~any(n==1)) | length(n(:))>2
    error('condition input can only do vectors')
end
if nargin<2, i=''; end
if isempty(i), varargout={[],'empty input'}; return, end
msg = ''; i=i(:)';

if ischar(i)
    if i(1)=='0' & all(ismember(unique(i(:)),char(abs('0'):abs('9'))))
        %-Leading zeros in a digit list
        msg = sprintf('%s expanded',i);
        z = min(find([diff(i=='0'),1]));
        i = [zeros(1,z), icond(i(z+1:end))'];
    else
        %-Try an eval, for functions & string #s
        i = evalin('base',['[',i,']'],'i');
    end
end

if ischar(i)
    %-Evaluation error from above: see if it's an 'abab' or 'a b a b' type:
    [c,null,i] = unique(lower(i(~isspace(i))));
    if all(ismember(c,char(abs('a'):abs('z'))))
        %-Map characters a-z to 1-26, but let 'r' be zero (rest)
        tmp = c-'a'+1; tmp(tmp=='r'-'a'+1)=0;
        i   = tmp(i);
        msg = [sprintf('[%s] mapped to [',c),...
                sprintf('%d,',tmp(1:end-1)),...
                sprintf('%d',tmp(end)),']'];
    else
        i = '!'; msg = 'evaluation error';
    end
elseif ~all(floor(i(:))==i(:))
    i = '!'; msg = 'must be integers';
elseif length(i)==1 & prod(n)>1
    msg = sprintf('%d expanded',i);
    i = floor(i./10.^[floor(log10(i)+eps):-1:0]);
    i = i-[0,10*i(1:end-1)];
end

%-Check size of i & #conditions
if ~ischar(i), [i,msg] = sf_SzChk(i,n,msg); end
if ~ischar(i) & isfinite(m) & length(unique(i))~=m
    i = '!'; msg = sprintf('%d conditions required',m);
end
return;

function str = sf_SzStr(n,unused)
%=======================================================================
%-Size info string constuction
if nargin<2, l=0; else l=1; end
if nargin<1, error('insufficient arguments'); end;
if isempty(n), n=NaN; end
n=n(:); if length(n)==1, n=[n,1]; end; dn=length(n);
if any(isnan(n)) || (prod(n)==1 && dn<=2) || (dn==2 && min(n)==1 && isinf(max(n)))
    str = ''; lstr = '';
elseif dn==2 && min(n)==1
    str = sprintf('[%d]',max(n));   lstr = [str,'-vector'];
elseif dn==2 && sum(isinf(n))==1
    str = sprintf('[%d]',min(n));   lstr = [str,'-vector(s)'];
else
    str=''; for i = 1:dn
        if isfinite(n(i)), str = sprintf('%s,%d',str,n(i));
        else str = sprintf('%s,*',str); end
    end
    str = ['[',str(2:end),']'];     lstr = [str,'-matrix'];
end
if l, str=sprintf('\t%s',lstr); else str=[str,' ']; end

function [p,msg] = sf_SzChk(p,n,msg)
%=======================================================================
%-Size checking
if nargin<3, msg=''; end
if nargin<2, n=[]; end; if isempty(n), n=NaN; else n=n(:)'; end
if nargin<1, error('insufficient arguments'), end

if ischar(p) || any(isnan(n(:))), return, end
if length(n)==1, n=[n,1]; end

dn = length(n);
sp = size(p);

if dn==2 && min(n)==1
    %-[1,1], [1,n], [n,1], [1,Inf], [Inf,1] - vector - allow transpose
    %---------------------------------------------------------------
    i = min(find(n==max(n)));
    if n(i)==1 && max(sp)>1
        p='!'; msg='scalar required';
    elseif ndims(p)~=2 || ~any(sp==1) || ( isfinite(n(i)) && max(sp)~=n(i) )
        %-error: Not2D | not vector | not right length
        if isfinite(n(i)), str=sprintf('%d-',n(i)); else str=''; end
        p='!'; msg=[str,'vector required'];
    elseif sp(i)==1 && n(i)~=1
        p=p'; msg=[msg,' (input transposed)'];
    end

elseif dn==2 && sum(isinf(n))==1
    %-[n,Inf], [Inf,n] - n vector(s) required - allow transposing
    %---------------------------------------------------------------
    i = find(isfinite(n));
    if ndims(p)~=2 || ~any(sp==n(i))
        p='!'; msg=sprintf('%d-vector(s) required',min(n));
    elseif sp(i)~=n
        p=p'; msg=[msg,' (input transposed)'];
    end

else
    %-multi-dimensional matrix required - check dimensions
    %---------------------------------------------------------------
    if ndims(p)~=dn || ~all( size(p)==n | isinf(n) )
        p = '!'; msg='';
        for i = 1:dn
            if isfinite(n(i)), msg = sprintf('%s,%d',msg,n(i));
            else msg = sprintf('%s,*',msg); end
        end
        msg = ['[',msg(2:end),']-matrix required'];
    end
end


function [nFiles, aSize, anat] = CheckAnatomy(dirName)

% [nFiles, size] = CheckAnatomy(dirName);
%
% Looks at the files in the specified directory and finds all files
% with names of form I.*. Counts the number of files that continuously
% run in the sequence I.001, I.002, etc., and have the same non-zero
% size. Outputs the number of files found and their size.
%
% DBR  4/99

nFiles = 0;
aSize = [0 0];
anat = [];

if ~exist(dirName, 'dir'); return; end

dS = dir(fullfile(dirName, 'I.*'));
nList = length(dS);
if nList == 0; return; end

% Create a subset of files that match our filename criterion: I.nnn
nFList = 0;
for iList=1:nList
  fName = dS(iList).name;
  if length(fName) == 5 & strcmp('I.', upper(fName(1:2)))
    seqNo = str2num(fName(3:5));
    if length(seqNo)
      nFList = nFList + 1;
      fileList{nFList} = fName;
      seqNos(nFList) = seqNo;
    end
  end
end

% Sort the matching files in ascending numerical order.
[seqNos, sortInds] = sort(seqNos);
fileList = fileList(sortInds);

% Check the files for unbroken sequence and matching image size.
%
% Put up a status bar if there is more than a single file:
if nFList > 1
  hBar = mrvWaitbar(0, 'Scanning MRI files');
end
% Begin the second pass. Break if sequence or size isn't right.
for iList=1:nFList
  if seqNos(iList) ~= iList; break; end
  img = ReadMRImage(fullfile(dirName, fileList{iList}));
  imSize = size(img);
  if exist('firstSize', 'var')
    if ~all(firstSize == imSize); break; end
    nFiles = nFiles + 1;
    anat = cat(3, anat, img);
  else
    firstSize = imSize;
    nFiles = 1;
    anat = img;
  end
  if nFList > 1
    mrvWaitbar(iList/nFList)
  end
end
% Get rid of any status bar
if nFList > 1
  close(hBar)
end

aSize = firstSize;


function plot_branches(P,cover,segment,fig,ms,segind,BO)

n = nargin;
if n < 7
    BO = 1000;
    if n < 6
        segind = 1;
        if n < 5
            ms = 1;
            if n == 3
                fig = 1;
            end
        end
    end
end

Bal = cover.ball;
Segs = segment.segments;
SChi = segment.ChildSegment;
SPar = segment.ParentSegment;

if iscell(Segs{1})
    ns = max(size(Segs));
    Seg = cell(ns,1);
    for i = 1:ns
        m = size(Segs{i},1);
        S = zeros(0);
        for j = 1:m
            s = Segs{i}(j);
            s = s{:};
            S = [S; s];
        end
        Seg{i} = S;
    end
else
    Seg = Segs;
end

% Color the segments with unique colors
col = rand(ns,3);
for i = 2:ns
    C = col(SPar(i),:);
    c = col(i,:);
    while sum(abs(C-c)) < 0.2
        c = rand(1,3);
    end
    col(i,:) = c;
end

segments = segind;
C = SChi{segind};
b = 0;
while ~isempty(C) && b <= BO
    b = b+1;
    segments = [segments; C];
    C = SChi{segind};
end

ns = length(segment);
figure(fig)
for i = 1:ns
    if i == 2
        hold on
    end
    S = vertcat(Bal{Seg{segments(i)}});
    plot3(P(S,1),P(S,2),P(S,3),'.','Color',col(segments(i),:),'Markersize',ms)
end
hold off


classdef C10MOP2 < EvoXBenchProblem
% <multi> <real> <large/none> <expensive/none>

%------------------------------- Reference --------------------------------
% Z. Lu, R. Cheng, Y. Jin, K. C. Tan, and K. Deb, Neural architecture
% search as multiobjective optimization benchmarks: Problem formulation and
% performance assessment, IEEE Transactions on Evolutionary Computation,
% 2023.
%--------------------------------------------------------------------------

    methods
        %% Default settings of the problem
        function Setting(obj)
            config.name = 'nb101';
            config.args.objs = 'err&params&flops';
            config.args.normalized_objectives = true;
            obj.Setting@EvoXBenchProblem(config);
        end
    end
end


function h = clickA3DPoint(pointCloud)
%CLICKA3DPOINT
%   H = CLICKA3DPOINT(POINTCLOUD) shows a 3D point cloud and lets the user
%   select points by clicking on them. The selected point is highlighted
%   and its index in the point cloud will is printed on the screen.
%   POINTCLOUD should be a 3*N matrix, represending N 3D points.
%   Handle to the figure is returned.
%
%   other functions required:
%       CALLBACKCLICK3DPOINT  mouse click callback function
%       ROWNORM returns norms of each row of a matrix
%
%   To test this function ...
%       pointCloud = rand(3,100)*100;
%       h = clickA3DPoint(pointCloud);
%
%       now rotate or move the point cloud and try it again.
%       (on the figure View menu, turn the Camera Toolbar on, ...)
%
%   To turn off the callback ...
%       set(h, 'WindowButtonDownFcn','');
%
%   by Babak Taati
%   http://rcvlab.ece.queensu.ca/~taatib
%   Robotics and Computer Vision Laboratory (RCVLab)
%   Queen's University
%   May 4, 2005
%   revised Oct 30, 2007
%   revised May 19, 2009

if nargin ~= 1
    error('Requires one input arguments.')
end

if size(pointCloud, 1)~=3
    error('Input point cloud must be a 3*N matrix.');
end

% show the point cloud
h = gcf;
plot3(pointCloud(1,:), pointCloud(2,:), pointCloud(3,:), 'c.');
cameratoolbar('Show'); % show the camera toolbar
hold on; % so we can highlight clicked points without clearing the figure

% set the callback, pass pointCloud to the callback function
set(h, 'WindowButtonDownFcn', {@callbackClickA3DPoint, pointCloud});


function F = uniaxial(d,rate)
% deformationGradientTensor representing uniaxial compression / tension
%
% Syntax
%
%   F = velocityGradientTensor.uniaxial(d,rate)
%
% Input
%  d - @vector3d expansion direction
%  rate - deformation rate
%
% Output
%  F - @deformationGradientTensor
%

if nargin < 2, rate = 2; end

rot = orientation.map(xvector,d);

F = deformationGradientTensor(diag([rate,1./sqrt(rate),1./sqrt(rate)]));

F = rotate(F,inv(rot));

end


function [iF, IF_f] = invertFrame(F)

% INVERTFRAME  Invert frame.
%   INVERTFRAME(F)  gives the frame iF, inverse of F, so that its
%   composition is the origin frame:
%       O = COMPOSEFRAMES(F,iF) ==> O.x = [0 0 0 1 0 0 0]'
%
%   [iF, IF_f] = INVERTFRAME(F) returns tha Jacobian of the inversion.

if nargout == 1

    q = q2qc(F.q);
    t = -Rtp(F.q,F.t);
    iF.x = [t;q];
    iF = updateFrame(iF);

else

    [q, Q_q] = q2qc(F.q);
    [nt, nT_q, nT_t] = Rtp(F.q,F.t); % this should be -Rtp(). n** means negative.

    iF.x = [-nt;q];
    iF = updateFrame(iF);

%     IF_f = zeros(7);
    IF_f(1:3,1:3) = -nT_t;
    IF_f(1:3,4:7) = -nT_q;
    IF_f(4:7,4:7) = Q_q;

end

% ========== End of function - Start GPL license ==========

%   # START GPL LICENSE

%---------------------------------------------------------------------
%
%   This file is part of SLAMTB, a SLAM toolbox for Matlab.
%
%   SLAMTB 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.
%
%   SLAMTB 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 SLAMTB.  If not, see <http://www.gnu.org/licenses/>.
%
%---------------------------------------------------------------------

%   SLAMTB is Copyright:
%   Copyright (c) 2008-2010, Joan Sola @ LAAS-CNRS,
%   Copyright (c) 2010-2013, Joan Sola,
%   Copyright (c) 2014-2015, Joan Sola @ IRI-UPC-CSIC,
%   SLAMTB is Copyright 2009
%   by Joan Sola, Teresa Vidal-Calleja, David Marquez and Jean Marie Codol
%   @ LAAS-CNRS.
%   See on top of this file for its particular copyright.

%   # END GPL LICENSE


function nn = nnapplygrads(nn)
%NNAPPLYGRADS updates weights and biases with calculated gradients
% nn = nnapplygrads(nn) returns an neural network structure with updated
% weights and biases

    for i = 1 : (nn.n - 1)
        if(nn.weightPenaltyL2>0)
            dW = nn.dW{i} + nn.weightPenaltyL2 * [zeros(size(nn.W{i},1),1) nn.W{i}(:,2:end)];
        else
            dW = nn.dW{i};
        end

        dW = nn.learningRate * dW;

        if(nn.momentum>0)
            nn.vW{i} = nn.momentum*nn.vW{i} + dW;
            dW = nn.vW{i};
        end

        nn.W{i} = nn.W{i} - dW;
    end
end


function [Sbus, dSbus_dVm] = makeSbus(baseMVA, bus, gen, mpopt, Vm, Sg)
%MAKESBUS   Builds the vector of complex bus power injections.
%   SBUS = MAKESBUS(BASEMVA, BUS, GEN)
%   SBUS = MAKESBUS(BASEMVA, BUS, GEN, MPOPT, VM)
%   SBUS = MAKESBUS(BASEMVA, BUS, GEN, MPOPT, VM, SG)
%   returns the vector of complex bus power injections, that is, generation
%   minus load. Power is expressed in per unit. If the MPOPT and VM arguments
%   are present it evaluates any ZIP loads based on the provided voltage
%   magnitude vector. If VM is empty, it assumes nominal voltage. If SG is
%   provided, it is a complex ng x 1 vector of generator power injections in
%   p.u., and overrides the PG and QG columns in GEN, using GEN only for
%   connectivity information.
%
%   [SBUS, DSBUS_DVM] = MAKESBUS(BASEMVA, BUS, GEN, MPOPT, VM)
%   With two output arguments, it computes the partial derivative of the
%   bus injections with respect to voltage magnitude, leaving the first
%   return value SBUS empty. If VM is empty, it assumes no voltage dependence
%   and returns a sparse zero matrix.
%
%   See also MAKEYBUS.

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

%% define named indices into bus, gen matrices
[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
    VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
    MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
    QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;

%% default inputs
if nargin < 5
    Vm = [];
    if nargin < 4
        mpopt = [];
    end
end
nb = size(bus, 1);

%% get load parameters
Sd = makeSdzip(baseMVA, bus, mpopt);

if nargout == 2
    Sbus = [];
    if isempty(Vm)
        dSbus_dVm = sparse(nb, nb);
    else
        dSbus_dVm = -(spdiags(Sd.i + 2 * Vm .* Sd.z, 0, nb, nb));
    end
else
    %% compute per-bus generation in p.u.
    on = find(gen(:, GEN_STATUS) > 0);      %% which generators are on?
    gbus = gen(on, GEN_BUS);                %% what buses are they at?
    ngon = size(on, 1);
    Cg = sparse(gbus, (1:ngon)', 1, nb, ngon);  %% connection matrix
                                                %% element i, j is 1 if
                                                %% gen on(j) at bus i is ON
    if nargin > 5 && ~isempty(Sg)
        Sbusg = Cg * Sg(on);
    else
        Sbusg = Cg * (gen(on, PG) + 1j * gen(on, QG)) / baseMVA;
    end

    %% compute per-bus loads in p.u.
    if isempty(Vm)
        Vm = ones(nb, 1);
    end
    Sbusd = Sd.p + Sd.i .* Vm + Sd.z .* Vm.^2;

    %% form net complex bus power injection vector
    %% (power injected by generators + power injected by loads)
    Sbus = Sbusg - Sbusd;
end


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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FUNCTION: Reads in (x,y) positions of the immersed boundary from .vtk
%           format
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Fdata = read_Force_Scalar_Data_From_vtk(path,simNums,strChoice)

cd(path);

filename = [strChoice '.' num2str(simNums) '.vtk'];  % desired FORCE-LAG-DATA.xxxx.vtk file

fileID = fopen(filename);
if ( fileID== -1 )
    error('\nCANNOT OPEN THE FILE!');
end

str = fgets(fileID); %-1 if eof
if ~strcmp( str(3:5),'vtk');
    error('\nNot in proper VTK format');
end

% read in the header info %
str = fgets(fileID);
str = fgets(fileID);
str = fgets(fileID);
str = fgets(fileID);
str = fgets(fileID);

% Check whether VTK file has time info. This is a VTK file with time,
%       need to read the next 3 lines to have read in appropriate
%       number of header lines.
if ~strcmp( str(1), 'P')
	str = fgets(fileID);
    str = fgets(fileID);
    str = fgets(fileID);
end

% stores # of Lagrangian Pts. as stated in .vtk file
numLagPts = sscanf(str,'%*s %f %*s',1);

for i=1:numLagPts+5 % +5 to get to FORCE DATA
    str = fgets(fileID);
end

% read in the vertices %
[mat,count] = fscanf(fileID,'%f',numLagPts);
if count ~= numLagPts
   error('\nProblem reading in Lagrangian Pts. Force Data');
end

mat = reshape(mat, 1, count/1); % Reshape vector -> matrix (every 3 entries in vector make into matrix row)
forces = mat';              % Store vertices in new matrix

fclose(fileID);               % Closes the data file.

Fdata = forces(:,1);         % magnitude of the force

cd ..;                        % Change directory back to ../hier_IB2d_data/ directory

clear mat str filename fileID count;


%% This file will be used to plot the performance comparison of SINDy-PI and PDE-Find
% Coded By: K
% Last Updated: 2019/06/23
%%
clc;clear all; close all;

%% Add path
addpath('./SINDy_PI_Results')
addpath('./PDE_Find_Results')
%% Load data
Files=dir('./SINDy_PI_Results/*.mat');

Error_DL=zeros(length(Files),1);
for k=1:length(Files)
   FileNames=strcat('SINDy_PI_Results/',Files(k).name);
   load(FileNames)
   Error_DL(k,1)=minVal_Final;
   digits(4)
   Expression
end

%%
Files=dir('./PDE_Find_Results/*.mat');

Error_PDE_Find=zeros(length(Files),1);
for k=1:length(Files)
   FileNames=strcat('PDE_Find_Results/',Files(k).name);
   load(FileNames)
   Error_PDE_Find(k,1)=minVal_Final;
   digits(4)
   Expression
end

%% Plot
close all
% Note that the first point should have zero noise, we set it up as 1e-5
% for the convenience of plotting
g0=[1e-5;0.0001;0.001;0.01;0.1;1];
figure(1)
hold on
set(gca,'FontSize',18);
set(gcf,'Position',[100 100 800 150]);
set(gcf,'PaperPositionMode','auto');
grid on

plot(g0,Error_PDE_Find,'linewidth',3,'linestyle','-','color','red')
scatter(g0,Error_PDE_Find,100,'filled','MarkerEdgeColor',[0 0 0],'MarkerFaceColor',1*[1 0 0])

plot(g0,Error_DL,'linewidth',3,'linestyle','-','color','blue')
scatter(g0,Error_DL,100,'filled','MarkerEdgeColor',[0 0 0],'MarkerFaceColor',1*[0 0 1])

xticks([1e-5 1e-4 1e-3 1e-2 1e-1 1])
xticklabels({'0','10^{-4}','10^{-3}','10^{-2}','10^{-1}','1'})

box('on')
set(gca, 'XScale', 'log', 'YScale', 'log');


function new_X = extract(X,idx)
%EXTRACT Creates a new ktensor with only the specified components.
%
%   Y = EXTRACT(X,S) selected the subset of components in X as defined by
%   S. It should be the case that S is a subset of [1,...,NCOMPONENTS(X)].
%
%   See also KTENSOR, NCOMPONENTS.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

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

%% Set-up
N = ndims(X);
%% Extract
new_lambda = X.lambda(idx);
new_U = cell(N,1);
for i = 1 : N
    new_U{i} = X.u{i}(:,idx);
end
new_X = ktensor(new_lambda, new_U);


function plot_segments(P,Bal,fig,ms,seg1,seg2,seg3,seg4,seg5)

% Plots point cloud segments/subsets defined as subsets of cover sets.
% If the subsets intersect, then assiggnes the common points to the
% segments given first.
%
% Inputs
% P     Point cloud
% Bal   Cover sets. Bal = cover.ball
% fig   figure number
% seg1  Segment/subset 1, color blue
% seg2  (Optional) Segment/subset 2, color red
% seg3  (Optional) Segment/subset 3, color green
% seg4  (Optional) Segment/subset 4, color cyan
% seg5  (Optional) Segment/subset 5, color magenta

if nargin == 5
    S1 = unique(vertcat(Bal{seg1}));
    figure(fig)
    plot3(P(S1,1),P(S1,2),P(S1,3),'b.','Markersize',ms)
    axis equal
elseif nargin == 6
    S1 = unique(vertcat(Bal{seg1}));
    S2 = unique(vertcat(Bal{seg2}));
    S2 = setdiff(S2,S1);
    figure(fig)
    plot3(P(S1,1),P(S1,2),P(S1,3),'b.','Markersize',1.5*ms)
    hold on
    plot3(P(S2,1),P(S2,2),P(S2,3),'r.','Markersize',ms)
    axis equal
    hold off
elseif nargin == 7
    S1 = unique(vertcat(Bal{seg1}));
    S2 = unique(vertcat(Bal{seg2}));
    S3 = unique(vertcat(Bal{seg3}));
    S2 = setdiff(S2,S1);
    S3 = setdiff(S3,S1);
    S3 = setdiff(S3,S2);
    figure(fig)
    plot3(P(S1,1),P(S1,2),P(S1,3),'b.','Markersize',ms)
    hold on
    plot3(P(S2,1),P(S2,2),P(S2,3),'r.','Markersize',ms)
    plot3(P(S3,1),P(S3,2),P(S3,3),'g.','Markersize',ms)
    axis equal
    hold off
elseif nargin == 8
    S1 = unique(vertcat(Bal{seg1}));
    S2 = unique(vertcat(Bal{seg2}));
    S3 = unique(vertcat(Bal{seg3}));
    S4 = unique(vertcat(Bal{seg4}));
    S2 = setdiff(S2,S1);
    S3 = setdiff(S3,S1);
    S3 = setdiff(S3,S2);
    S4 = setdiff(S4,S1);
    S4 = setdiff(S4,S2);
    S4 = setdiff(S4,S3);
    figure(fig)
    plot3(P(S1,1),P(S1,2),P(S1,3),'b.','Markersize',ms)
    hold on
    plot3(P(S2,1),P(S2,2),P(S2,3),'r.','Markersize',ms)
    plot3(P(S3,1),P(S3,2),P(S3,3),'g.','Markersize',ms)
    plot3(P(S4,1),P(S4,2),P(S4,3),'c.','Markersize',ms)
    axis equal
    hold off
elseif nargin == 9
    S1 = unique(vertcat(Bal{seg1}));
    S2 = unique(vertcat(Bal{seg2}));
    S3 = unique(vertcat(Bal{seg3}));
    S4 = unique(vertcat(Bal{seg4}));
    S5 = unique(vertcat(Bal{seg5}));
    S2 = setdiff(S2,S1);
    S3 = setdiff(S3,S1);
    S3 = setdiff(S3,S2);
    S4 = setdiff(S4,S1);
    S4 = setdiff(S4,S2);
    S4 = setdiff(S4,S3);
    S5 = setdiff(S5,S1);
    S5 = setdiff(S5,S2);
    S5 = setdiff(S5,S3);
    S5 = setdiff(S5,S4);
    figure(fig)
    plot3(P(S1,1),P(S1,2),P(S1,3),'b.','Markersize',ms)
    hold on
    plot3(P(S2,1),P(S2,2),P(S2,3),'r.','Markersize',ms)
    plot3(P(S3,1),P(S3,2),P(S3,3),'g.','Markersize',ms)
    plot3(P(S4,1),P(S4,2),P(S4,3),'c.','Markersize',ms)
    plot3(P(S5,1),P(S5,2),P(S5,3),'m.','Markersize',ms)
    axis equal
    hold off
end


%%*******************************************************************
%% Prod2: compute the block diagonal matrix A*B
%%
%%    C = Prod2(blk,A,B,options);
%%
%% INPUT:  blk = a cell array describing the block structure of A and B
%%         A,B = square matrices or column vectors.
%%
%%   options = 0  if no special structure
%%             1  if C is symmetric
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*******************************************************************

   function  C = Prod2(blk,A,B,options);

   global spdensity

   if (nargin == 3); options = 0; end;
   iscellA = iscell(A); iscellB = iscell(B);
%%
   if (~iscellA & ~iscellB)
      if (size(blk,1) > 1);
         error('Prod2: blk and A,B are not compatible');
      end;
      if strcmp(blk{1},'s')
         numblk = length(blk{2});
         isspA = issparse(A); isspB = issparse(B);
         if (numblk > 1)
            if ~isspA; A=sparse(A); isspA=1; end
            if ~isspB; B=sparse(B); isspB=1; end
         end
         %%use_matlab = (options==0 & ~isspA & ~isspB) | (isspA & isspB);
         use_matlab = (~isspA & ~isspB) | (isspA & isspB);
         if (use_matlab)
            C = A*B;
            if (options==1); C = 0.5*(C+C'); end;
         else
            C = mexProd2(blk,A,B,options);
         end
         checksparse = (numblk==1) & (isspA | isspB);
         if (checksparse)
            n2 = sum(blk{2}.*blk{2});
            if (mexnnz(C) <= spdensity*n2);
               if ~issparse(C); C = sparse(C); end;
            else
               if issparse(C); C = full(C); end;
            end
         end
      elseif (strcmp(blk{1},'q') | strcmp(blk{1},'l') | strcmp(blk{1},'u'))
         C = A.*B;
      end
   else
      error(['Prod2: A,B must be matrices']);
   end
%%*******************************************************************


function f = compose(f, op, varargin)
%COMPOSE   Compose command for SPHEREFUN objects.
%   F = COMPOSE(F, OP)  returns the SPHEREFUN that approximates OP(F).
%
%   F = COMPOSE(F, OP, G)  returns the SPHEREFUN that approximates OP(F).
%
%   F = COMPOSE(F, G) with a CHEBFUN G with one column returns a SPHEREFUN that
%   approximates G(F).  If G has 3 columns, the result is a SPHEREFUNV. If G is
%   a CHEBFUN2 or CHEBFUN2V, the composition is interpreted as G(real(F),
%   imag(F)).
%
%   This command is a wrapper for the SPHEREFUN constructor.

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

if ( isempty(op) )
    return
elseif ( isempty(f) )
    f = op;

elseif ( isa(op, 'chebfun') )
    % Composition OP(f) of SPHEREFUN object f and CHEBFUN OP

    if ( length(op.domain) > 2 )
        % If OP has several pieces, OP(SPHEREFUN) might be inaccurate.
        warning('CHEBFUN:SPHEREFUN:compose:pieces', ...
            ['The composition of a CHEBFUN with several pieces and a SPHEREFUN\n', ...
            'might be inaccurate.']);
    end

    % Check that image(f) is contained in domain(OP).
    vals = minandmax2est(f);        % Estimate of image(f).
    tol = 100 * chebfun2eps * max(vscale(f), vscale(op)) * ...
            norm(f.domain, inf);    % Tolerance.
    if ( ~isSubset(vals, op.domain, tol) )
        error('CHEBFUN:SPHEREFUN:COMPOSE:DomainMismatch', ...
            'OP(F) is not defined, since image(F) is not contained in domain(OP).')
    end

    nColumns = size(op, 2);
    if ( nColumns == 1 )
        % Call constructor:
        f = spherefun(@(x,y) op(feval(f, x, y)), f.domain);

    elseif ( nColumns == 3 )
        % Extract columns of the CHEBFUN OP:
        op1 = op(:,1);
        op2 = op(:,2);
        op3 = op(:,3);

        % Call constructor:
        f = spherefunv(@(x,y) op1(feval(f, x, y)), ...
            @(x,y) op2(feval(f, x, y)), @(x,y) op3(feval(f, x, y)));

    else
        % The CHEBFUN object OP has a wrong number of columns.
        error('CHEBFUN:SPHEREFUN:COMPOSE:Columns', ...
            'The CHEBFUN object must have 1 or 3 columns.')

    end

elseif ( isa(op, 'chebfun2') )
    % Composition OP(f) of SPHEREFUN object f and CHEBFUN2 OP, interpreted as
    % OP(real(f), imag(f)).  For now SPHEREFUNS are real, but this might change
    % in the future.

    % Check that image(f) is contained in domain(OP).
    vals = minandmax2est(f);        % Estimate of image(f).
    tol = 100 * chebfun2eps * max(vscale(f), vscale(op)) * ...
            norm(f.domain, inf);    % Tolerance.
    if ( ~isSubset(vals, op.domain(1:2), tol) )
        error('CHEBFUN:SPHEREFUN:COMPOSE:DomainMismatch2', ...
            'OP(F) is not defined, since image(F) is not contained in domain(OP).')
    end

    % Call constructor:
    f = spherefun(@(x,y) op(feval(real(f), x, y), feval(imag(f), x, y)), ...
        f.domain);

elseif ( isa(op, 'chebfun2v') )
    % Composition OP(f) of SPHEREFUN object f and CHEBFUN2V OP with three
    % components, interpreted as OP(real(f), imag(f)).
    % For now SPHEREFUNS are real, but this might change in the future.

    % Check that OP has three components:
    if ( op.nComponents ~= 3 )
        error('CHEBFUN:SPHEREFUN:COMPOSE:C2VnComponents', ...
            'The Chebfun2v objects must have three components.')
    end

    % Get the components:
    op1 = op(1);
    op2 = op(2);
    op3 = op(3);

    % Check that image(f) is contained in domain(OP).
    vals = minandmax2est(f);        % Estimate of image(f).
    tol = 100 * chebfun2eps * max(vscale(f), vscale(op)) * ...
            norm(f.domain, inf);    % Tolerance.
    if ( ~isSubset(vals, op1.domain(1:2), tol) )
        error('CHEBFUN:SPHEREFUN:COMPOSE:DomainMismatch2v', ...
            'OP(F) is not defined, since image(F) is not contained in domain(OP).')
    end

    % Get real and imaginary parts of f:
    realf = real(f);
    imagf = imag(f);

    % Call constructor:
    f = spherefunv(@(x,y) op1(feval(realf, x, y), feval(imagf, x, y)), ...
        @(x,y) op2(feval(realf, x, y), feval(imagf, x, y)), ...
        @(x,y) op3(feval(realf, x, y), feval(imagf, x, y)));

elseif ( nargin == 2 && nargin(op) == 1 )
    % OP has one input variable.

    % Call constructor:
    f = spherefun(@(x,y) op( feval(f, x, y) ), f.domain);

elseif ( nargin == 3 && nargin(op) == 2 )
    % OP has two input variables.

    g = varargin{1};
    if ( isa(g, 'double') )     % promote
        g = spherefun(@(x,y,z) g + 0*x, f.domain);
    end

    if ( isa(f, 'double') )     % promote
        f = spherefun(@(x,y,z) f + 0*x, g.domain);
    end

    % Call constructor:
    f = spherefun(@(x,y) op( feval(f, x, y), feval(g, x, y) ), f.domain);

else
    % Not sure what to do, error:
    error('CHEBFUN:SPHEREFUN:COMPOSE:OP', 'NARGIN(OP) not correct.')
end

end


function z=hatmatrix(varargin)

fit = locfit(varargin{:},'module','hatm');
z = lfknots(fit)';

return;


function [ selvalid ] = softSelect( hypScores, thres, soft )
%SOFTSELECT Summary of this function goes here
%   Detailed explanation goes here
nm = (thres-hypScores)./soft;
rn = rand(length(nm),1);
selvalid = rn>nm;

end


function C = times(A,B)
%TIMES Element-wise multiplication for ktensor.
%
%   TIMES(A,B) denotes element-by-element multiplication.
%
%   C = TIMES(A,B) is called for the syntax 'A .* B' when A or B is a
%   tensor.
%
%   See also KTENSOR, SPTENSOR/TIMES.
%
%MATLAB Tensor Toolbox.
%Copyright 2015, Sandia Corporation.

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

if ~isequal(size(A),size(B))
    error('Must be two tensors of the same size');
end

switch class(B)
    case {'sptensor','tensor'}
        % Call back to sptensor version.
        C = times(B,A);
        return;
    otherwise
        error('Invalid second argument for ktensor/times');
end


classdef VehicleArticulatedLinear < VehicleDynamicsLateral.VehicleArticulated
    % VehicleArticulatedLinear Linear articulated vehicle model.
    %
    % It inherits properties from VehicleArticulated.

    methods
        % Constructor
        function self = VehicleArticulatedLinear()
            self.mF0 = 5200;
            self.mR0 = 2400;
            self.mF = 6000;
            self.mR = 10000;
            self.mM = 17000;
            self.IT = 46000;
            self.IS = 450000;
            self.lT = 3.5;
            self.lS = 7.7;
            self.c = -0.3;
            self.nF = 2;
            self.nR = 4;
            self.nM = 8;
            self.wT = 2.6;
            self.wS = 2.4;
            self.muy = 0.3;
            self.deltaf = 0;
            self.Fxf = 0;
            self.Fxr = 0;
            self.Fxm = 0;
        end

        function dx = Model(self,t,states,tspan)
            % Vehicle parameters
            mT = self.mT;
            mS = self.mS;
            % IT = self.IT;
            % IS = self.IS;
            a = self.a;
            b = self.b;
            c = self.c;
            d = self.d;
            e = self.e;
            nF = self.nF;
            nR = self.nR;
            nM = self.nM;
            g = 9.81;

            % Vertical forces
            FzF = self.mF * g;
            FzR = self.mR * g;
            FzM = self.mM * g;
            muy = self.muy;

            v0 = 20;

            % State
            X = states(1,1);
            Y = states(2,1);
            PSI     = states(3,1);
            PHI     = states(4,1);
            V       = states(5,1);
            ALPHAT  = states(6,1);
            dPSI    = states(7,1);
            dPHI    = states(8,1);

            if isa(self.deltaf,'function_handle')
                deltaf = self.deltaf([X;Y;PSI;PHI;V;ALPHAT;dPSI;dPHI],t);
            elseif length(self.deltaf)>1
                deltaf = interp1(tspan,self.deltaf,t);
            else
                deltaf = self.deltaf;
            end

            % Slip angles - linear
            ALPHAF = ALPHAT + a/v0*dPSI - deltaf;
            ALPHAR = ALPHAT - b/v0*dPSI;
            ALPHAM = ALPHAT + PHI - (dPSI*(b + c + d + e))/v0 + (dPHI*(d + e))/v0;

            % Longitudinal forces
            if isa(self.Fxf,'function_handle')
                FxF = self.Fxf([X;Y;PSI;PHI;V;ALPHAT;dPSI;dPHI],t);
            elseif length(self.Fxf)>1
                FxF = interp1(tspan,self.Fxf,t);
            else
                FxF = self.Fxf;
            end

            if isa(self.Fxr,'function_handle')
                FxR = self.Fxr([X;Y;PSI;PHI;V;ALPHAT;dPSI;dPHI],t);
            elseif length(self.Fxr)>1
                FxR = interp1(tspan,self.Fxr,t);
            else
                FxR = self.Fxr;
            end

            if isa(self.Fxm,'function_handle')
                FxM = self.Fxm([X;Y;PSI;PHI;V;ALPHAT;dPSI;dPHI],t);
            elseif length(self.Fxm)>1
                FxM = interp1(tspan,self.Fxm,t);
            else
                FxM = self.Fxm;
            end

            % Lateral forces - Characteristic curve
            FyF = nF*self.tire.Characteristic(ALPHAF,FzF/nF,muy);
            FyR = nR*self.tire.Characteristic(ALPHAR,FzR/nR,muy);
            FyM = nM*self.tire.Characteristic(ALPHAM,FzM/nM,muy);

            A = [ 0  0   0  0  1   0                       0  0;...
                  0  0  v0  0  0  v0                       0  0;...
                  0  0   0  0  0   0                       1  0;...
                  0  0   0  0  0   0                       0  1;...
                  0  0   0  0  0   0                       0  0;...
                  0  0   0  0  0   0           (-v0*(mS + mT))  0;...
                  0  0   0  0  0   0  (mS*(d*v0 + v0*(b + c)))  0;...
                  0  0   0  0  0   0                (-d*mS*v0)  0];

            B = [ 0  0  0  0  0   0                0;...
                  0  0  0  0  0   0                0;...
                  0  0  0  0  0   0                0;...
                  0  0  0  0  0   0                0;...
                  0  1  1  1  0   0                0;...
                  0  0  0  0  1   1                1;...
                  0  0  0  0  a  -b  (- b - c - d - e);...
                  0  0  0  0  0   0            (d + e)];

            vetEst = [X ; Y ; PSI ; PHI ; V ; ALPHAT ; dPSI ; dPHI];
            vetEnt = [deltaf ; FxF ; FxR ; FxM ; FyF ; FyR ; FyM];

            % Integrator output
            dx = A*vetEst + B*vetEnt;
        end

        function [value,isterminal,direction] = velocity(~,~,states)
            % If the velocity is less than 0.1m/s the integrator stops.
            % The MassMatrix is singular when the velocity is 0 m/s.
            value = states(5,1) - 0.1;
            isterminal = 1;
            direction = -1;
        end

        function E = MassMatrix(self,~,~)
            % Vehicle parameters
            mT = self.mT;
            mS = self.mS;
            IT = self.IT;
            IS = self.IS;
            % a = self.a;
            b = self.b;
            c = self.c;
            d = self.d;
            % e = self.e;
            % deltaf = self.deltaf;
            % nF = self.nF;
            % nR = self.nR;
            % nM = self.nM;

            % g = 9.81;

            v0 = 20;

            % Mass matrix
            E = [ 1  0  0  0        0                        0                                               0                            0;...
                  0  1  0  0        0                        0                                               0                            0;...
                  0  0  1  0        0                        0                                               0                            0;...
                  0  0  0  1        0                        0                                               0                            0;...
                  0  0  0  0  (mS + mT)                      0                                               0                            0;...
                  0  0  0  0        0             (v0*(mS + mT))                                 (-mS*(b + c + d))                         (d*mS);...
                  0  0  0  0        0  ( -mS*v0*(b + c + d))            (IS + IT + mS*(b + c + d)^2)  (- IS - mS*(d^2 + (b + c)*d));...
                  0  0  0  0        0                  (d*mS*v0)                     (- IS - mS*(d^2 + (b + c)*d))                  (mS*d^2 + IS)];

        end
    end
end

%% See Also
%
% <../../index.html Home>
%


classdef LayerAP < dagnn.Loss
  % @author: Hakan Bilen
  % 11 step average precision
  properties
    cls_index = 1
    resetLayer = false
    gtLabels = []
    scores   = []
    ids      = []
    aps      = []
    voc07    = true % 11 step
    classNames = {}
  end

  methods
    function outputs = forward(obj, inputs, params)
      if obj.resetLayer
        obj.gtLabels = [] ;
        obj.scores   = [] ;
        obj.ids      = [] ;
        obj.aps      = [] ;
        obj.resetLayer = false ;
      end

      if numel(inputs)==2
        obj.scores = [obj.scores gather(squeeze(inputs{1}(:,:,obj.cls_index,:)))];
        obj.gtLabels = [obj.gtLabels gather(squeeze(inputs{2}(:,:,obj.cls_index,:)))];
      elseif numel(inputs)>2
        scoresCur = gather(squeeze(inputs{1}(:,:,obj.cls_index,:)));
        gtLabelsCur = gather(squeeze(inputs{2}(:,:,obj.cls_index,:)));

        idsCur = gather(squeeze(inputs{3}));

        [lia,locb] = ismember(idsCur,obj.ids);

        if any(lia)
          obj.scores = [obj.scores scoresCur(~lia,:)];
          obj.gtLabels = [obj.gtLabels gtLabelsCur(~lia,:)];
          obj.ids = [obj.ids(:) ; idsCur(~lia,:)];

          nz = find(lia);
          for i=1:numel(nz)
            obj.scores(locb(nz(i)),:) = obj.scores(locb(nz(i)),:) + ...
              scoresCur(nz(i),:);
          end
        else
          obj.scores = [obj.scores scoresCur];
          obj.gtLabels = [obj.gtLabels gtLabelsCur];
          obj.ids = [obj.ids(:) ; idsCur]';
        end
      else
        error('wrong number of inputs');
      end

      obj.aps = obj.compute_average_precision();
      obj.average = 100 * mean(obj.aps);
      outputs{1} =  100 * mean(obj.aps);
    end

    function [derInputs, derParams] = backward(obj, inputs, params, derOutputs)
      derInputs = cell(1,numel(inputs));
      derInputs{1} = derOutputs{1} ;
      derParams = {} ;
    end

    function reset(obj)
      obj.resetLayer = true ;
%       obj.average = 0 ;
%       obj.aps = 0 ;
%       obj.gtLabels = [];
%       obj.scores   = [];
%       obj.ids      = [];
    end

    function printAP(obj)
      if isempty(obj.classNames)
        for i=1:numel(obj.aps)
          fprintf('class-%d %.1f\n',i,100*obj.aps(i)) ;
        end
      else
        for i=1:numel(obj.aps)
          fprintf('%-50s %.1f\n',obj.classNames{i},100*obj.aps(i)) ;
        end
      end
    end

    function aps = compute_average_precision(obj)
      assert(all(size(obj.scores)==size(obj.gtLabels)));
      % nImg = size(obj.scores,1);
      nCls = numel(obj.cls_index);

      aps = zeros(1,nCls);

      for c=1:nCls
        gt = obj.gtLabels(c,:);
        conf = obj.scores(c,:) ;
        if sum(gt>0)==0, continue ; end

        % compute average precision
        if obj.voc07
          [rec,prec,ap]=obj.VOC07ap(conf,gt) ;
        else
          [rec,prec,ap]=obj.THUMOSeventclspr(conf,gt) ;
        end
        aps(c) = ap;
      end
    end

    function [rec,prec,ap]=VOC07ap(obj,conf,gt)
      [~,si]=sort(-conf);
      tp=gt(si)>0;
      fp=gt(si)<0;

      fp=cumsum(fp);
      tp=cumsum(tp);

      rec=tp/sum(gt>0);
      prec=tp./(fp+tp);
      ap=0;
      for t=0:0.1:1
        p=max(prec(rec>=t));
        if isempty(p)
          p=0;
        end
        ap=ap+p/11;
      end
    end

    function [rec,prec,ap]=THUMOSeventclspr(obj,conf,gt)
      [so,sortind]=sort(-conf);
      tp=gt(sortind)==1;
      fp=gt(sortind)~=1;
      npos=length(find(gt==1));

      % compute precision/recall
      fp=cumsum(fp);
      tp=cumsum(tp);
      rec=tp/npos;
      prec=tp./(fp+tp);

      % compute average precision

      ap=0;
      tmp=gt(sortind)==1;
      for i=1:length(conf)
        if tmp(i)==1
          ap=ap+prec(i);
        end
      end
      ap=ap/npos;
    end

    function obj = LayerAP(varargin)
      obj.load(varargin) ;
      obj.loss = 'average_precision' ;
    end
  end
end


% -------------------------------------------------------------------------
function net = cnn_init_resnext(net,opts)
% -------------------------------------------------------------------------
% initialize classifier
net = dagnn.DagNN.loadobj(net) ;

% convs = find(arrayfun(@(a) isa(a.block, 'dagnn.Conv'), net.layers)==1);

fclayer = net.getLayer('classifier_0') ;
sizeW = size(net.params(fclayer.paramIndexes(1)).value);

% opts.nCls = 101;
nCls = opts.nCls ;
DropOutRate = opts.DropOutRate ;

net.params(fclayer.paramIndexes(1)).value = ...
  0.01 * randn([sizeW(1:3),nCls],'single') ;
net.params(fclayer.paramIndexes(2)).value = zeros(nCls,1,'single') ;

% change loss
softmax = find(arrayfun(@(a) isa(a.block, 'dagnn.SoftMax'), net.layers)==1);
if ~isempty(softmax)
  net.removeLayer(net.layers(softmax(1)).name) ;
end
% convs = find(arrayfun(@(a) isa(a.block, 'dagnn.Conv'), net.layers)==1);
fclayer = find(arrayfun(@(a) strcmp(a.name, 'classifier_0'), net.layers)==1);
net.renameVar(net.layers(fclayer(end)).name,'prediction') ;
net.renameVar('data','input') ;

%------------------------------------------------------------------------%
% configure appr-rank-pool
switch opts.pool1Type
  case 'arpool'
    if strcmp(opts.pool1Layer,'conv0')
      poolLyr1 = 1 ;
      net.addLayer('arpool',AppRankPooling('scale',0.1),{'input','VideoId1'},'DynImg');
      net.setLayerInputs(net.layers(1).name,{'DynImg'}) ;
    else
      poolLyr1 = find(arrayfun(@(a) strcmp(a.name, opts.pool1Layer), net.layers)==1);
      assert(~isempty(poolLyr1));
      net.addLayer('arpool',AppRankPooling('scale',0.1),{net.layers(poolLyr1).inputs{1},'VideoId1'},'DynImg');
      net.setLayerInputs(opts.pool1Layer,{'DynImg'}) ;
    end
  case 'ppool1'
    if strcmp(opts.pool1Layer,'conv0')
      poolLyr1 = 1 ;
    else
      poolLyr1 = find(arrayfun(@(a) strcmp(a.name, opts.pool1Layer), net.layers)==1);
    end
    net.addLayer('parampool',LinComb('pad',[1 1 10 1]),...
      {'features_4_0_merge','VideoId1'},'DynImg0',{'conv0f','conv0b'});

%     net.params(end-1).value = 0.1 * ones(1,1,10,1,'single');
    net.params(end-1).value = 0.1 * randn(1,1,10,1,'single');
    net.params(end).value = zeros(1,1,'single');

    net.addLayer('BnormDyn',dagnn.BatchNorm('numChannels',256),'DynImg0','DynImg',...
      {'dym','dyb','dybx'}) ;
    net.params(end-2).value =  ones(256,1,'single') ;
    net.params(end-1).value =  zeros(256,1,'single') ;
    net.params(end).value   =  zeros(256,2,'single') ;

%     net.addLayer('reluP',dagnn.ReLU(),...
%       {'DynImg1'},'DynImg');
    net.layers(16).inputs{1} = 'DynImg' ;
    for i=numel(net.params)-4:numel(net.params),
      net.params(i).learningRate = 0.1 * net.params(i).learningRate;
    end
  case 'none'
  otherwise
    error('Unknown pool type %s', opts.pool1Type) ;
end

net.rebuild() ;
%------------------------------------------------------------------------%
% second pool layer (max pooling)
% poolLyr2 = find(arrayfun(@(a) strcmp(a.name, 'pool5'), net.layers)==1);
poolLyr2 = find(arrayfun(@(a) strcmp(a.name, 'features_7_1_merge'), net.layers)==1);
net.addLayer('tempPoolMax',TemporalPooling('method','max'),...
  {net.layers(poolLyr2(1)).outputs{1},'VideoId2'},'tempPoolMax');

% change the input of fc last layer
% net.setLayerInputs(net.layers(convs(end)).name,'tempPoolMax') ;
% net.addLayer('bnar',dagnn.BatchNorm('numChannels',2048),{'tempPoolMax'},...
%   'tempPoolMaxbn',{'bnar_m','bnar_b','bnar_x'});
poolLyr2next = find(arrayfun(@(a) strcmp(a.name, 'features_7_1_id_relu'), net.layers)==1);
net.setLayerInputs(net.layers(poolLyr2next(1)).name,{'tempPoolMax'}) ;
net.rebuild() ;
%------------------------------------------------------------------------%
% add drop-out layers
if DropOutRate>0

  pool5 = find(arrayfun(@(a) strcmp(a.name, 'features_8'), net.layers)==1);
  oo = net.layers(pool5(1)).outputs{1};
  net.addLayer('drop_pool5',dagnn.DropOut('rate',DropOutRate),...
    oo,sprintf('drop_%s',oo),{});
  net.setLayerInputs('classifier_permute',{sprintf('drop_%s',oo)}) ;
end

%------------------------------------------------------------------------%
% add multi-class error
net.addLayer('errMC',ErrorMultiClass(),{'prediction','label'},'mcerr');

net.addLayer('loss', ...
             LossNormalized('loss', 'softmaxlog') ,...
             {'prediction', 'label'}, ...
             'objective') ;

%------------------------------------------------------------------------%
net.rebuild()

% replace standard matconvnet bnorm with my version
bns = find(arrayfun(@(a) strcmp(class(a.block), 'dagnn.BatchNorm'), net.layers)==1);
for i=1:numel(bns)
  bb = net.layers(bns(i)).block ;
  net.layers(bns(i)).block = BatchNormN('numChannels',bb.numChannels,...
  'epsilon',bb.epsilon,...
  'opts',bb.opts) ;
end

% dagMergeBatchNorm(net) ;
% dagRemoveLayersOfType(net, 'dagnn.BatchNorm') ;
net_ = net.saveobj ;
net = dagnn.DagNN.loadobj(net_) ;
net.meta.normalization.border = [32 32] ;


function maxTMap=getMaxTVal(numberOfTMaps,tMapRoot,tMapStartIndex)
% function maxTMap=getMapTVal(numberOfTMaps,tMapRoot)
% Finds the MAX of a set of T maps.
% Don't know what to do to make a retinotopy map...the best way, maybe
  % is to find the MAX of T maps of contrasts for each different phase

    if (~exist('tMapRoot','var'))
      tMapRoot='spmT_000'; % Can't have more than 9 different phases for
                           % now
    end

    if (~exist('tMapStartIndex','var'))
      tMapStartIndex=1; %

    end
    if (numberOfTMaps>8)
      error('Cannot have more than 8 TMaps at the moment');
    end

    % Load in the first one just to get the size
    firstMapVol=spm_vol([tMapRoot,int2str(tMapStartIndex)]);
    firstMap=spm_read_vols(firstMapVol);
    [x y z]=size(firstMap);
    counter=1;
    fprintf('\nSize is %d x %d x%d',x,y,z);

    % First TMap should be spm_T0001
    for thisTmap=1:(numberOfTMaps)
      fileName=[tMapRoot,int2str(thisTmap+tMapStartIndex-1)];

        mapVol(counter)=spm_vol(fileName);
        mapData(:,:,:,counter)=spm_read_vols(mapVol(counter));
        disp(thisTmap);
        counter=counter+1;
    end

    % Now for each plane we want to find the max
    maxTMap=max(mapData,[],4);


% test_all_wls.m

list = {
'ir_pwls_os_lalm test'
'pwls_example'
'pwls_sps_os_test'
'pwls_sps_example'
'pwls_sps_zoom'
'pwls_pcg1 test'
'qpwls_qn_test'
'qpwls_sps_example'
'qpwls_pcg1 test'
'qpwls_pcg1_test'
'wls_grpr_test'
'wls_pcg_test'
'pwls_gca_test'
'pwls_admm2 test'
'qpwls_pcg2_test'
%'qpwls_art2_vs_sps' % very slow!
};

run_mfile_local(list)


%SHAPE Abstract superclass for primitive shapes
%
% Defines concrete and abstract properties and methods which are common
% to all shape subclasses (primitives). Also contains some functions
%
% Copyright (C) Bryan Moutrie, 2013-2014
% Licensed under the GNU Lesser General Public License
% see full file for full statement
%
% Syntax:
%  (1) shape = Shape(T, s, ...)
%
% Outputs:
%  shape : Shape object. Note as Shape is abstract it cannot be
%           instantiated, hence shape is an object of a Shape subclass.
%
% Inputs:
%  T   : See transform property
%  s   : See scale property (can be input as scalar or 3-vector)
%  ... : Options - other properties in name-value pairs
%
% See documentation for information on properties and methods
% (type doc Shape into the command window)
%
% See also Box.Box CollisionModel Cone Curvilinear Cylinder.Cylinder
% Ellipsoid.Ellipsoid Sphere.Sphere surface

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

classdef (Abstract) Shape

    properties
        % Short text description of object for user reference
        note = '<Add a description with note property>'
        transform = eye(4) % Transformation matrix of the shape
        scale = [1 1 1] % Scale vector of the shape, [s_x s_y s_z]
        FaceColor = pHRIWARE('blue'); % The surface property
        FaceAlpha = 1 % The surface property
        EdgeColor = pHRIWARE('navy'); % The surface property
        EdgeAlpha = 1 % The surface property
    end

    properties (Abstract)
        volume % Volume of shape

        %FACES  Logical vector of which faces to plot
        % For Boxes, faces is a 1x6 vector, whose elements correspond
        % to the faces in the negative y-z, x-z, x-y and positive y-z,
        % x-z, x-y planes, with respect to that shape's frame,
        %  in that order
        % For Curvilinears, faces is a 1x2 vector, whose elements
        %  correspond to the end faces whose centres are at the origin
        %  and not at the origin, with respect to that shape's frame,
        %  in that order
        % For Ellipsoids, faces is not currently used
        faces

        %N "Resolution" of the shape, for plotting
        % For Boxes, each face will comprise of an nxn grid of points
        % For Curvilinears, it is the equivalent of cylinder(n)
        % For Ellipsoids, it is the equivalent of sphere(n)
        n
    end

    properties (Constant)
        sym = exist('sym','class'); % Symbolic Math Toolbox install flag
    end

    methods (Abstract)
        %PLOT Plot the shape
        %
        % Plots the shape object to the current figure as a surface
        % object or objects. Only a few options are included, but a
        % graphics handle can be optionally returned for more advanced
        % demands.
        %
        % Copyright (C) Bryan Moutrie, 2013-2014
        % Licensed under the GNU General Public License, see file for
        % statement
        %
        % Syntax:
        %  (1) shape.plot()
        %  (2) shape.plot(...)
        %  (3) h = shape.plot(...)
        %
        %  (1) Plots the shape with the options specified by its
        %       various properties
        %  (2) is as per (1) but can specify over-riding values for
        %       options for the plot only, in name-value pairs
        %  (3) is as per (1) or (2) but returns a handle or vecor of
        %       handles to the surface objects plotted
        %
        % Outputs:
        %  h : graphics handle for each surface plotted
        %
        % Inputs:
        %  ... : Plotting options (which are Shape properties), in
        %         name-value pairs
        %
        % See also Shape.cloud Shape.parseopts
        h = plot(shape, varargin)

        %CLOUD Generate point cloud from shape
        %
        % Generates three arrays corresponding to the x, y and z points
        % of a shape's point data which is readable by the surface
        % function. If the shape is a Box, the third dimension of X, Y,
        % and Z is the points for each face - therefore some points are
        % duplicated (more specifically the corner and edge points)
        %
        % Copyright (C) Bryan Moutrie, 2013-2014
        % Licensed under the GNU General Public License, see file for
        % statement
        %
        % Syntax:
        %  (1) [X, Y, Z] = shape.cloud()
        %
        % Outputs:
        %  X : array of x-coordinates
        %  Y : array of y-coordinates
        %  Z : array of z-coordinates
        %
        % See also Shape.plot surface
        [X, Y, Z] = cloud(shape)

        %CHECK Check if point(s) are inside the shape
        %
        % Check to see if point(s) lie inside a primitive shape.
        % Points on the surface are treated as outside the shape.
        %
        % Copyright (C) Bryan Moutrie, 2013-2014
        % Licensed under the GNU General Public License, see file for
        % statement
        %
        % Syntax:
        %  (1) c = shape.check(x, y, z)
        %  (2) c = shape.check(p)
        %  (3) f = shape.check()
        %  (4) h = shape.check()
        %
        %  (2) is as per (1) where p = [x, y, z]
        %  (3) Requires the MuPAD symbolic mathematics toolbox
        %  (4) Repalces (3) if no MuPAD symbolic mathematics toolbox
        %
        % Outputs:
        %  c : mx1 vector, where there are m points. Each element is
        %       the logical value of the mth point being inside the
        %       shape
        %  f : anonymous function, f(x, y, z), which reduces check to a
        %       simplified, one-line evaluation
        %  h : function handle, h(x, y, z), OR h(p), which reduces
        %       check to a simplified, one-line evaluation
        %
        % Inputs:
        %  x : x-coordinate(s) of point(s), may be any size/shape
        %  y : y-coordinate(s) of point(s), may be any size/shape
        %  z : z-coordinate(s) of point(s), may be any size/shape
        %  p : An mx3 matrix, where each column is x, y, z. m may be 1.
        %
        % See also CollisionModel SerialLink.collisions sym2func
        c = check(shape, varargin)
    end

    methods
        function shape = Shape(T, s, varargin)
            shape = shape.parseopts(varargin{:});
            if ~isempty(T), shape.transform = T; end
            if ~isempty(s), shape.scale = s; end
        end

        function disp(shape)
            w = whos('shape');
            line1 = [w.class,': ',shape.note];
            line2(1:length(line1)) = '-';
            line3 = 'transform =';
            line4 = ['scale = ',mat2str(shape.scale)];
            line5 = ['volume = ',num2str(shape.volume), ' u^3'];
            if isprop(shape,'radius'),
                if ~isa(shape.radius,'function_handle') %#ok<*MCNPN>
                    line6 = ['radius = ',num2str(shape.radius)];
                else
                    line6 = ['radius = ',func2str(shape.radius)];
                end
            else
                line6 = [];
            end
            line7 = line2;
            line8 = 'Plot options:';
            line9 = ['FaceColor = ',mat2str(shape.FaceColor,2),...
                ' | FaceAlpha = ',num2str(shape.FaceAlpha)];
            line10 = ['EdgeColor = ',mat2str(shape.EdgeColor,2),...
                ' | EdgeAlpha = ',num2str(shape.EdgeAlpha)];
            line11 = ['n = ',num2str(shape.n),' | faces = ',...
                mat2str(shape.faces),];

            disp(line1);
            disp(line2);
            disp(line3);
            disp(shape.transform);
            disp(line4);
            disp(line5);
            disp(line6);
            disp(line7);
            disp(line8);
            disp(line9);
            disp(line10);
            disp(line11);
        end

        function [shape, frames] = parseopts(shape, varargin)
            %PARSEOPTS Set plot options (and more) in one line
            %
            % Parses multiple plot options to shape properties (faces,
            % n, FaceColor, FaceAlpha, EdgeColor, EdgeAlpha) in
            % name-value pairs. The note property can also be set.
            % Additionally, the pair "'animate', frames" may be used to
            % animate the shape with the transformations in frames
            % within the plot method. If not specified, is identity.
            %
            % Copyright (C) Bryan Moutrie, 2013-2014
            % Licensed under the GNU General Public License, see file
            % for statement
            %
            % Syntax:
            %  (1) [shape, frames] = shape.parseopts(...)
            %
            % Outputs:
            %  shape  : Shape object with new property values
            %  frames : Coordinate frames to animate shape. Relative to
            %            the shape's own transform.
            %
            % Inputs:
            %  ... : Options - plotting properties in name-value pairs

            frames = [];
            for i = 1: 2: length(varargin)-1
                if strcmp(varargin{i},'FaceColor')
                    shape.FaceColor = varargin{i+1};
                elseif strcmp(varargin{i},'FaceAlpha')
                    shape.FaceAlpha = varargin{i+1};
                elseif strcmp(varargin{i},'EdgeColor')
                    shape.EdgeColor = varargin{i+1};
                elseif strcmp(varargin{i},'EdgeAlpha')
                    shape.EdgeAlpha = varargin{i+1};
                elseif strcmp(varargin{i},'animate')
                        frames = varargin{i+1};
                elseif strcmp(varargin{i},'n')
                    shape.n = varargin{i+1};
                elseif strcmp(varargin{i},'faces')
                    shape.faces = varargin{i+1};
                elseif strcmp(varargin{i},'note')
                    shape.note = varargin{i+1};
                else
                    error(pHRIWARE('error','inputValue'));
                end
            end
        end

        function vargout = animate(shape, h, frames)
            %ANIMATE Animate a plotted shape
            %
            % Animate a plotted shape by applying a series of
            % transformations to its graphics handle. A handle can be
            % returned by a call to plot. Transformations for each
            % frame are applied before the shape's own transformation.
            % Animation is at a fixed 100 fps.
            %
            % Copyright (C) Bryan Moutrie, 2013-2014
            % Licensed under the GNU General Public License, see file
            % for statement
            %
            % Syntax:
            %  (1) shape.animate(h, frames)
            %  (2) h = shape.animate(h, frames)
            %
            %  (2) is as per (1) but returns graphics handle of
            %       animated shape
            %
            % Outputs:
            %  h : Modified graphics handle(s)
            %
            % Inputs:
            %  h     : Graphics handle(s) of a Shape object
            %  frames: 4x4xm array of m frames/transformation matrices
            %
            % See also Shape.plot

            t = hgtransform;
            set(h,'Parent',t);
            for i = 1: size(frames,3)
                set(t, 'Matrix', frames(:,:,i));
                pause(0.01);
            end

            if nargout == 1, vargout = h; end
        end

        function shape = set.note(shape, note)
            if ~ischar(note)
                error(pHRIWARE('error','inputType'));
            else
                shape.note = note;
            end
        end

        function shape = set.scale(shape, scale)
            shape.scale = scale .* [1 1 1]; % Allows scalar or 3-vector
        end

%         function f = dyncheck(s, points)
%             s.transform = symT * s.transform;
%             switch nargin
%                 case 1
%                     dyncheck = s.check;
%                     f = @(T,x,y,z) dyncheck(T(1),T(5),T(9),...
%                         T(2),T(6),T(10),...
%                         T(3),T(7),T(11),...
%                         T(13),T(14),T(15),x,y,z);
%                 case 2
%                     dyncheck = s.check(points);
%                     f = @(T) dyncheck(T(1),T(5),T(9),...
%                         T(2),T(6),T(10),...
%                         T(3),T(7),T(11),...
%                         T(13),T(14),T(15));
%             end
%         end
    end

    methods (Access = protected)
        function [Xst, Yst, Zst] = sat(shape, X, Y, Z)
            %SAT Scale and transform point cloud data
            X_sz = size(X);
            Y_sz = size(Y);
            Z_sz = size(Z);

            X = X(:) * shape.scale(1);
            Y = Y(:) * shape.scale(2);
            Z = Z(:) * shape.scale(3);

            P = shape.transform * [X, Y, Z, ones(size(X))]';
            Xst = reshape(P(1,:), X_sz);
            Yst = reshape(P(2,:), Y_sz);
            Zst = reshape(P(3,:), Z_sz);
        end
    end
end


classdef math_model_opf_dc < mp.math_model_opf
%MP.MATH_MODEL_OPF_DC  MATPOWER mathematical model for DC optimal power flow (OPF) problem.
%   ?
%
%   MP.MATH_MODEL_OPF_DC ... power flow ...
%
%   Properties
%       ? - ?
%
%   Methods
%       ?

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

%     properties
%     end

    methods
        %% constructor
        function obj = math_model_opf_dc()
            obj@mp.math_model_opf();
            obj.element_classes = { @mp.mme_bus_opf_dc, @mp.mme_gen_opf_dc, ...
                @mp.mme_load_pf_dc, @mp.mme_branch_opf_dc, @mp.mme_shunt_pf_dc };
        end

        function tag = form_tag(obj)
            tag = 'dc';
        end

        function name = form_name(obj)
            name = 'DC';
        end

        function [vx, z, x] = convert_x_m2n(obj, mmx, nm)
            nm_vars = obj.update_nm_vars(mmx, nm);

            %% convert (real) math model x to network model x
            vx = nm_vars.va;
            z  = nm_vars.z;
            if nargout < 2
                vx = [vx; z];
            elseif nargout > 2
                x = [vx; z];
            end
        end

        function obj = add_node_balance_constraints(obj, nm, dm, mpopt)
            [B, K, p] = nm.get_params();

            %% power balance constraints
            C = nm.C;
            Amis = C * [B*C' K*nm.D'];
            bmis = -C * p;
            obj.add_lin_constraint('Pmis', Amis, bmis, bmis, ...
                                [nm.va.order; nm.z.order]);
        end

        function opt = solve_opts(obj, nm, dm, mpopt)
            opt = mpopt2qpopt(mpopt, obj.problem_type());

            switch opt.alg
                case {'MIPS', 'IPOPT'}
                    if mpopt.opf.start < 2      %% initialize interior point
                        opt.x0 = obj.interior_x0(obj, nm, dm);
                    end
                case 'OSQP'
                    opt.x0 = [];        %% disable provided starting point
            end
        end
    end     %% methods
end         %% classdef


classdef FMeasureMerger < handle
    properties(Constant)
        USE_ORIGINAL_IDEA=false;
    end

    methods(Static)
        function [bestIds, fMeasure]=GetBest(matchIdPerRow, ...
                mergeIdPerRow, matchId, mergeIds, adaptiveBins, transpose)
            if isempty(adaptiveBins)
                [matchSize, fMeasures4MergeIds,mergeSizes,truePositives]...
                    =FMeasureMerger.Compute(matchIdPerRow, ...
                    mergeIdPerRow, matchId, mergeIds, transpose);
                if FMeasureMerger.USE_ORIGINAL_IDEA
                    [bestIds, fMeasure]=...
                        FMeasureMerger.FindBestUsingOriginalIdea(...
                        matchSize, mergeIds, fMeasures4MergeIds, mergeSizes, ...
                        truePositives);
                else
                    [bestIds, fMeasure]=FMeasureMerger.FindBest(...
                    matchSize, mergeIds, fMeasures4MergeIds, mergeSizes, ...
                    truePositives);
                end
            else
                [matchChoices, fMeasures4MergeIds, allMergeChoices] ...
                    =FMeasureMerger.ComputeBins(matchIdPerRow, ...
                    mergeIdPerRow, matchId, mergeIds, adaptiveBins, transpose);
                [bestIds, fMeasure]=FMeasureMerger.FindBestBins(...
                    mergeIds, fMeasures4MergeIds, matchChoices, ...
                    allMergeChoices, adaptiveBins, transpose);
            end
        end

        function [matchChoices, fMeasures4MergeIds, allMergeChoices]=...
                ComputeBins(idPerRow1, idPerRow2, ...
                matchId, mergeIds, adaptiveBins, transpose)
            if ~transpose
                matchChoices=MatBasics.LookForIds(idPerRow1, matchId);
            else
                matchChoices=MatBasics.LookForIds(idPerRow2, matchId);
            end
            nMergeIds=length(mergeIds);
            allMergeChoices=cell(1, nMergeIds);
            fMeasures4MergeIds=zeros(1,nMergeIds);
            for i=1:nMergeIds
                if ~transpose
                    mergeChoices=MatBasics.LookForIds(idPerRow2, mergeIds(i));
                    fMeasures4MergeIds(i)=adaptiveBins.fMeasure(matchChoices, mergeChoices);
                else
                    mergeChoices=MatBasics.LookForIds(idPerRow1, mergeIds(i));
                    fMeasures4MergeIds(i)=adaptiveBins.fMeasure(mergeChoices, matchChoices);
                end
                allMergeChoices{i}=mergeChoices;
                if isnan(fMeasures4MergeIds(i))
                    fMeasures4MergeIds(i)=0;
                end
            end
        end

        function [bestIds, fMeasure]=FindBestBins(mergeIds,...
                fMeasures4MergeIds, matchChoices, allMergeChoices, ...
                adaptiveBins, transpose)
            [maxF, idx]=max(fMeasures4MergeIds);
            bestIds=mergeIds(idx);
            fMeasure=-100;% force at least ONE merger
            nMergeCandidates=length(fMeasures4MergeIds);
            nextFms=zeros(1, nMergeCandidates);
            mergeChoices=allMergeChoices{idx};
            mergeIds(idx)=nan;
            while ~all(isnan(mergeIds))
                for i=1:nMergeCandidates
                    if isnan(mergeIds(i))
                        nextFms(i)=-1;
                    else
                        if ~transpose
                            nextFms(i)=adaptiveBins.fMeasure(...
                                matchChoices, mergeChoices|allMergeChoices{i});
                        else
                            nextFms(i)=adaptiveBins.fMeasure(...
                                mergeChoices|allMergeChoices{i}, matchChoices);
                        end
                    end
                end
                [f, idx]=max(nextFms);
                if f>fMeasure
                    fMeasure=f;
                    mergeChoices=mergeChoices|allMergeChoices{idx};
                    bestIds(end+1)=mergeIds(idx);
                else
                    break; % nothing changed!
                end
                mergeIds(idx)=nan;
            end
            if QfHiDM.F_MEASURE_MERGE_FAST==-1
                FMeasureMerger.NoteIfNoMergerImprovement(fMeasure, maxF, ...
                    bestIds(1));
            end
            bestIds=sort(bestIds);
        end

        function [matchSize, fMeasures4MergeIds, mergeSizes, truePositives]=...
                Compute(idPerRow1, idPerRow2, matchId, mergeIds, transpose)
            if ~transpose
                matchChoices=MatBasics.LookForIds(idPerRow1, matchId);
            else
                matchChoices=MatBasics.LookForIds(idPerRow2, matchId);
            end
            matchSize=sum(matchChoices);
            nMergeIds=length(mergeIds);
            fMeasures4MergeIds=zeros(1,nMergeIds);
            truePositives=zeros(1,nMergeIds);
            mergeSizes=zeros(1,nMergeIds);
            for i=1:nMergeIds
                if ~transpose
                    mergeChoices=MatBasics.LookForIds(idPerRow2, mergeIds(i));
                else
                    mergeChoices=MatBasics.LookForIds(idPerRow1, mergeIds(i));
                end
                mergeSizes(i)=sum(mergeChoices);
                truePositives(i)=sum(matchChoices&mergeChoices);
                p=truePositives(i)/mergeSizes(i);
                r=truePositives(i)/matchSize;
                fMeasures4MergeIds(i)=(2*p*r)/(p+r);
                if isnan(fMeasures4MergeIds(i))
                    fMeasures4MergeIds(i)=0;
                end
            end
        end

%This method was necessary over the
%FindBestUsingOriginalIdea when it was found that
%the next highest F-measure does not ALWAYS
%lead to the best F-measure after merging.
%This was found with the Neutrophil scenario
%when trying to find first best merger of 2 after
%starting with a merge candidate with max F-measure
%that is based on a precision of 212/584 and matchSize of 300
%and the next 2 candidates in decreasing F-measure
%order is precision 8/105 and 2/54.
%The best F-measure when combining the 2nd candidate
%is 2/54 and not 8/105

        function [bestIds, fMeasure]=FindBest(matchSize, mergeIds, ...
            fMeasures4MergeIds, mergeSizes, truePositives)
            [maxF, idx]=max(fMeasures4MergeIds);
            bestIds=mergeIds(idx);
            fMeasure=-100;% force at least ONE merger
            truePositive=truePositives(idx);
            mergeSize=mergeSizes(idx);
            truePositives(idx)=nan;
            while ~all(isnan(truePositives))
                tp=truePositive+truePositives;
                p=tp./(mergeSizes+mergeSize);
                r=tp./matchSize;
                [f, idx]=max((2*p.*r)./(p+r));
                if f>fMeasure
                    fMeasure=f;
                    truePositive=truePositive+truePositives(idx);
                    mergeSize=mergeSize+mergeSizes(idx);
                    bestIds(end+1)=mergeIds(idx);
                else
                    break; % nothing changed!
                end
                truePositives(idx)=nan;
            end
            if QfHiDM.F_MEASURE_MERGE_FAST==-1
                FMeasureMerger.NoteIfNoMergerImprovement(fMeasure, maxF,...
                    bestIds(1));
            end
            bestIds=sort(bestIds);
        end

        function [bestIds, fMeasure]=FindBestUsingOriginalIdea(matchSize,...
                mergeIds, fMeasures4MergeIds, mergeSizes, truePositives)
            [fmBest2Worst, I]=sort(fMeasures4MergeIds, 'descend');
            idx=I(1);
            bestIds=mergeIds(idx);
            fMeasure=-100;% force at least ONE merger
            truePositive=truePositives(idx);
            mergeSize=mergeSizes(idx);
            truePositives(idx)=nan;
            tp=truePositive+truePositives;
            p=tp./(mergeSizes+mergeSize);
            r=tp./matchSize;
            [f, idx]=max((2*p.*r)./(p+r));
            if f>fMeasure
                fMeasure=f;
                truePositive=truePositive+truePositives(idx);
                truePositives(idx)=nan;
                mergeSize=mergeSize+mergeSizes(idx);
                bestIds(end+1)=mergeIds(idx);
                nMergeCandidates=length(fMeasures4MergeIds);
                for i=2:nMergeCandidates
                    if fMeasure<.5 && fmBest2Worst(i)<.5
                        %NOT going to get better!
                        break;
                    end
                    idx=I(i);
                    if isnan(truePositives(idx))
                        continue;
                    end
                    c=mergeSizes(idx);
                    tp=truePositive+truePositives(idx);
                    p=tp/(c+mergeSize);
                    r=tp/matchSize;
                    f=(2*p*r)/(p+r);
                    if f>fMeasure
                        fMeasure=f;
                        truePositive=tp;
                        mergeSize=c+mergeSize;
                        bestIds(end+1)=mergeIds(idx);
                    end
                end
            end

            if QfHiDM.F_MEASURE_MERGE_FAST==-1
                FMeasureMerger.NoteIfNoMergerImprovement(fMeasure,...
                    fmBest2Worst(1), bestIds(1));
            end
            bestIds=sort(bestIds);
        end

        function NoteIfNoMergerImprovement(fMeasure, maxF, bestId)
            if fMeasure<maxF
                fprintf(['No improvement by merging:  Best merger (fm=%s) is LESS than '...
                    'ID=%d (fm=%s)!\n'], ...
                    String.encodeRounded(fMeasure, 3), bestId, ...
                    String.encodeRounded(maxF(1),3));
            end
        end

        function [dif, newF, oldF]=DetectChange(matchSize, ...
                 currentTruePositives, currentMergeSize, newTruePositives, newMergeSize)
             p=currentTruePositives/currentMergeSize;
             r=currentTruePositives/matchSize;
             oldF=(2*p*r)/(p+r);
             p=newTruePositives/currentMergeSize;
             r=newTruePositives/matchSize;
             individualF=(2*p*r)/(p+r);
             tp=currentTruePositives+newTruePositives;
             p=tp/(newMergeSize+currentMergeSize);
             r=tp/matchSize;
             newF=(2*p*r)/(p+r);
             dif=newF-oldF;
             if dif<0
                 word='WORSER';
             else
                 word='better';
             end
             fprintf('%s F-measures:  old=%s, individual=%s, merged=%s, change=%s\n',...
                 word, ...
                 String.encodeRounded(oldF, 3), ...
                 String.encodeRounded(individualF, 3), ...
                 String.encodeRounded(newF, 3), ...
                 String.encodeRounded(dif, 3));
        end
    end
end


function [output, firstIndexPoint] = read_hs_file( filename, outfile)

%read_hs_file Reads in BTI-Headshape files
%   filename: file with the headshape informations
%   outfile: if present, a ctf ".shape" file is written
%   output: if present, a 3xN matrix containing the headshape-points
%
%   (C) 2007 by Thomas Hartmann

% This file is part of FieldTrip, see http://www.ru.nl/neuroimaging/fieldtrip
% 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: read_bti_hs.m 945 2010-04-21 17:41:20Z roboos $

if nargin == 1
    outfile = [];
end %if

fid = fopen(filename, 'r', 'b');
version = fread(fid, 1, '*uint32');
timestamp = fread(fid, 1, '*int32');
checksum = fread(fid, 1, '*int32');
nPoints = fread(fid, 1, '*int32');

firstIndexPoint = fread(fid, [3, 5], 'double')';

points = fread(fid, [3, double(nPoints)], 'double');

fclose(fid);

if(nargout > 0)
    output = points';
end %if

if(nargin == 2)
    fid = fopen(outfile, 'wt');
    fprintf(fid, '%d\n', nPoints);
    for i = 1:size(points, 2)
        fprintf(fid, '%.3f\t%.3f\t%.3f\n', points(1, i), points(2, i), points(3, i));
    end %for
    fclose(fid);

end %if


function pink_noise_test03 ( )

%*****************************************************************************80
%
%% TEST03 tests RANH.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    31 May 2010
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST03\n' );
  fprintf ( 1, '  RANH is a random hold function.\n' );
  fprintf ( 1, '  Given a value U and a delay D, it returns the value\n' );
  fprintf ( 1, '  U for D calls, then resets U.\n' );

  for d = 5 : -1 : 1
    fprintf ( 1, '\n' );
    fprintf ( 1, '   I   D   Q      U           Y\n' );
    fprintf ( 1, '\n' );
    u = 0.5;
    q = 3;
    for i = 1 : 20
      [ y, u, q ] = ranh ( d, u, q );
      fprintf ( 1, '  %2d  %2d  %2d  %10f  %10f\n', i, d, q, u, y );
    end
  end

  return
end