function tf = ispolycw_N(x, y)
%ISPOLYCW_N True if polygon vertices are in clockwise order
%
%   TF = ISPOLYCW(X, Y) returns true if the polygonal contour vertices
%   represented by X and Y are ordered in the clockwise direction.  X and Y
%   are numeric vectors with the same number of elements.
%
%   Alternatively, X and Y can contain multiple contours, either in
%   NaN-separated vector form or in cell array form.  In that case,
%   ISPOLYCW returns a logical array containing one true or false value
%   per contour.
%
%   ISPOLYCW always returns true for polygonal contours containing two or
%   fewer vertices.
%
%   Vertex ordering is not well defined for self-intersecting polygonal
%   contours.  For such contours, ISPOLYCW returns a result based on the
%   order or vertices immediately before and after the left-most of the
%   lowest vertices.  In other words, of the vertices with the lowest Y
%   value, find the vertex with the lowest X value.  For a few special
%   cases of self-intersecting contours, the vertex ordering cannot be
%   determined using only the left-most of the lowest vertices; for these
%   cases, ISPOLYCW uses a signed area test to determine the ordering.
%
%   Class Support
%   -------------
%   X and Y may be any numeric class.
%
%   Example
%   -------
%   Orientation of a square:
%
%       x = [0 1 1 0 0];
%       y = [0 0 1 1 0];
%       ispolycw(x, y)                     % Returns 0
%       ispolycw(fliplr(x), fliplr(y))     % Returns 1
%
%   See also POLY2CW, POLY2CCW, POLYBOOL.

% Copyright 2004-2009 The MathWorks, Inc.
% $Revision: 1.1.4.3 $  $Date: 2009/08/11 15:44:28 $

if isempty(x)
   tf = true;
   return;
end

if ~iscell(x)
   checkxy_N(x, y, mfilename, 'X', 'Y', 1, 2)
   is_row = (size(x,1) == 1);
   [x, y] = polysplit_N(x, y);
   if is_row
      x = x';
      y = y';
   end
end

tf = false(size(x));
for k = 1:numel(x)
   tf(k) = isContourClockwise(x{k}, y{k});
end

%----------------------------------------------------------------------
function tf = isContourClockwise(x, y)

if numel(x) <= 1
    tf = true;
    return;
end

is_closed = (x(1) == x(end)) && (y(1) == y(end));
if is_closed
    x(end) = [];
    y(end) = [];
end

[x, y] = removeDuplicates(x, y);
num_vertices = numel(x);
if num_vertices <= 2
    tf = true;
    return;
end

idx = findExtremeVertices(x, y);

if numel(idx) > 1
    % The same extreme vertex appears multiple, nonsuccessive times in
    % the vertex list.  Use signed area test.
    tf = signedArea(x, y) <= 0;
    return;
end

% Find the three vertices we are interested in: the left-most of the
% lowest vertices, as well as the ones immediately before and after it.
p = mod((idx - 1) + [-1, 0, 1], num_vertices) + 1;
xx = x(p);
yy = y(p);

if ~isfloat(xx)
    xx = double(xx);
end
if ~isfloat(yy)
    yy = double(yy);
end

ux = xx(2) - xx(1);
uy = yy(2) - yy(1);

vx = xx(3) - xx(2);
vy = yy(3) - yy(2);

a = ux*vy;
b = uy*vx;
if a == b
    % The left-most lowest vertex is the end-point of a kind of linear
    % "spur."  The contour doubles back on itself, such as in this case:
    % x = [0 1 1 0 0 -1 0];
    % y = [0 0 1 1 0 -1 0];
    % The left-most lowest vertex is (-1,-1), but we since this vertex
    % is the end-point of a spur, we can't tell the direction from it.
    % Use the signed polygon test.
    tf = signedArea(x, y) <= 0;
else
    tf = a < b;
end

%----------------------------------------------------------------------
function [xout, yout] = removeDuplicates(x, y)
num_vertices = numel(x);
k1 = [2:num_vertices 1];
k2 = 1:num_vertices;
dups = (x(k1) == x(k2)) & (y(k1) == y(k2));
xout = x;
yout = y;
xout(dups) = [];
yout(dups) = [];

%----------------------------------------------------------------------
function idx = findExtremeVertices(x, y)
% Return the indices of all the left-most lowest vertices in (x,y).

% Find the vertices with the minimum y.
idx = find(y == min(y));

x_subset = x(idx);
idx2 = (x_subset == min(x_subset));

idx = idx(idx2);

%----------------------------------------------------------------------
function a = signedArea(x, y)
% a = signedArea(x,y) returns twice the signed area of the polygonal
% contour represented by vectors x and y.  Assumes (x,y) is NOT closed.

% Reference:
% http://geometryalgorithms.com/Archive/algorithm_0101/algorithm_0101.htm

x = x - mean(x);
n = numel(x);
if n <= 2
    a = 0;
else
    i = [2:n 1];
    j = [3:n 1 2];
    k = (1:n);
    a = sum(x(i) .* (y(j) - y(k)));
end


function v=shear_bulk2poisson(mu,k)

v=((3.*k)-(2.*mu))./((6.*k)+(2.*mu));

end

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function [y,t,optw,W,C,confb95,yb] = sskernel(x,tin,W)
% [y,t,optw,W,C,confb95,yb] = sskernel(x,t,W)
%
% Function `sskernel' returns an optimized kernel density estimate
% using a Gauss kernel function.
%
% Examples:
% >> x = 0.5-0.5*log(rand(1,1e3)); t = linspace(0,3,1000);
% >> [y,t,optw] = sskernel(x,t);
% This example produces a vector of kernel density estimates, y, at points
% specified in a vector t, using an optimized bandwidth, optw (a standard
% deviation of a normal density function).
%
% >> sskernel(x);
% By calling the function without output arguments, the estimated density
% is displayed along with 95% bootstrap confidence intervals.
%
% Input arguments:
% x:    Sample data vector.
% tin (optinal):
%       Points at which estimation are computed. Please use fine resolution
%       to obtain a correct optimal bandwidth.
% W (optinal):
%       A vector of kernel bandwidths.
%       If W is provided, the optimal bandwidth is selected from the
%       elements of W.
%       * Do not search bandwidths smaller than a sampling resolution of data.
%       If W is not provided, the program searches the optimal bandwidth
%       using a golden section search method.
%
% Output arguments:
% y:    Estimated density
% t:    Points at which estimation was computed.
%       The same as tin if tin is provided.
%       (If the sampling resolution of tin is smaller than the sampling
%       resolution of the data, x, the estimation was done at smaller
%       number of points than t. The results, t and y, are obtained by
%       interpolating the low resolution sampling points.)
% optw: Optimal kernel bandwidth.
% W:    Kernel bandwidths examined.
% C:    Cost functions of W.
% conf95:
%       Bootstrap confidence intervals.
% yb:   Booststrap samples.
%
%
% Usage:
% >> [y,t,optw] = sskernel(x);
% When t is not given in the input arguments, i.e., the output argument t
% is generated automatically.
%
% >> W = linspace(0.01,1,20);
% >> [y,t,optw] = sskernel(x,t,W);
% The optimal bandwidth is selected from the elements of W.
%
% >> [y,t,optw] = sskernel(x,t,0.1);
% If the density estimate with a given bandwidth, simply put a scalar value
% as W. The computation is faster than the built-in function, ksdensity.
%
% >> [y,t,optw,confb95,yb] = sskernel(x);
% This additionally computes 95% bootstrap confidence intervals, confb95.
% The bootstrap samples are provided as yb.
%
%
% Optimization principle:
% The optimal bandwidth is obtained as a minimizer of the formula,
% sum_{i,j} \int k(x - x_i) k(x - x_j) dx  -  2 sum_{i~=j} k(x_i - x_j),
% where k(x) is the kernel function, according to
%
% Hideaki Shimazaki and Shigeru Shinomoto
% Kernel Bandwidth Optimization in Spike Rate Estimation
% Journal of Computational Neuroscience 2010
% http://dx.doi.org/10.1007/s10827-009-0180-4
%
% The above optimization is based on a principle of minimizing
% expected L2 loss function between the kernel estimate and an unknown
% underlying density function. An assumption is merely that samples
% are drawn from the density independently each other.
%
% For more information, please visit
% http://2000.jukuin.keio.ac.jp/shimazaki/res/kernel.html
%
% See also SSVKERNEL, SSHIST
%
% Bug fix
% 131004 fixed a problem for large values
%
% Hideaki Shimazaki
% http://2000.jukuin.keio.ac.jp/shimazaki

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parameters Settings
x = reshape(x,1,numel(x));

if nargin == 1
    T = max(x) - min(x);
    [mbuf,nbuf,dt_samp] = find( sort(diff(sort(x))),1,'first');
    tin = linspace(min(x),max(x), min(ceil(T/dt_samp),1e3));
    t = tin;
    x_ab = x( logical((x >= min(tin)) .*(x <= max(tin))) ) ;
else
    T = max(tin) - min(tin);
    x_ab = x( logical((x >= min(tin)) .*(x <= max(tin))) ) ;
    [mbuf,nbuf,dt_samp] = find( sort(diff(sort(x_ab))),1,'first');

    if dt_samp > min(diff(tin))
        t = linspace(min(tin),max(tin), min(ceil(T/dt_samp),1e3));
    else
        t = tin;
    end
end

dt = min(diff(t));

% Create a finest histogram
y_hist = histc(x_ab,t-dt/2);
L = length(y_hist);
N = sum(y_hist);
y_hist = y_hist/N/dt;   %density

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute a Cost Function

if nargin >= 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Global search
C = zeros(1,length(W));
C_min = Inf;

for k = 1: length(W)
	w = W(k);
    [C(k) yh] = CostFunction(y_hist,N,w,dt);

    if C(k) < C_min
        C_min = C(k);
        optw = w;
        y = yh;
    end
end

else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Golden section search on a log-exp scale
% Initialize
Wmin = 2*dt; Wmax = 1*(max(x) - min(x));

tol = 10^-5;
phi = (sqrt(5) + 1)/2;        %golden ratio
%logexp = @(x) log(1+exp(x));
%ilogexp = @(x) log(exp(x)-1);

%a = Wmin; b = Wmax;
a = ilogexp(Wmin); b = ilogexp(Wmax);

c1 = (phi-1)*a + (2-phi)*b;
c2 = (2-phi)*a + (phi-1)*b;

f1 = CostFunction(y_hist,N,logexp(c1),dt);
f2 = CostFunction(y_hist,N,logexp(c2),dt);

k = 1;
while abs(b-a) > tol*(abs(c1)+abs(c2)) && k <= 20
	if (f1 < f2)
        b = c2;
        c2 = c1;

        c1 = (phi - 1)*a + (2 - phi)*b;

        f2 = f1;
        [f1 yh1] = CostFunction(y_hist,N,logexp(c1),dt);

        W(k) = logexp(c1);
        C(k) = f1;
        optw = logexp(c1);
        y = yh1./sum(yh1.*dt);  %make the final output a density
    else
        a = c1;
        c1 = c2;

        c2 = (2 - phi)*a + (phi - 1)*b;

        f1 = f2;
        [f2 yh2] = CostFunction(y_hist,N,logexp(c2),dt);

        W(k) = logexp(c2);
        C(k) = f2;
        optw = logexp(c2);
        y = yh2./sum(yh2.*dt);
    end

    k = k + 1;
end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bootstrap Confidence Intervals
if nargout == 0 || nargout >= 6
    nbs = 1e3;        %number of bootstrap samples
    yb = zeros(nbs,length(tin));

    for i = 1: nbs,
        %y_histb = poissrnd(y_hist*dt*N)/dt/N;

        idx = ceil(rand(1,N)*N);
        xb = x_ab(idx);
        y_histb = histc(xb,t-dt/2)/dt/N;

        yb_buf = fftkernel(y_histb,optw/dt);
        yb_buf = yb_buf / sum(yb_buf*dt);

        yb(i,:) = interp1(t,yb_buf,tin);
    end

    ybsort = sort(yb);
    y95b = ybsort(floor(0.05*nbs),:);
    y95u = ybsort(floor(0.95*nbs),:);

    confb95 = [y95b; y95u];
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Return results
y = interp1(t,y,tin);
t = tin;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Display results
if nargout == 0
            hold on;

            line([t; t],[y95b; y95u]...
                    ,'Color',[7 7 7]/8,'LineWidth',1 );
            plot(t,y95b,'Color',[7 7 7]/9,'LineWidth',1);
            plot(t,y95u,'Color',[7 7 7]/9,'LineWidth',1);

            plot(t,y,'Color',[0.9 0.2 0.2],'LineWidth',2);

            grid on;
            ylabel('density');
            set(gca,'TickDir','out');
else
    if nargin >= 4
        if strcmp(option,'Visible')
            hold on;

            if nargout >= 6
                line([t; t],[y95b; y95u]...
                    ,'Color',[7 7 7]/8,'LineWidth',1 );
                plot(t,y95b,'Color',[7 7 7]/9,'LineWidth',1);
                plot(t,y95u,'Color',[7 7 7]/9,'LineWidth',1);
            end

            plot(t,y,'Color',[0.9 0.2 0.2],'LineWidth',1);

            grid on;
            ylabel('density');
            set(gca,'TickDir','out');

        end
    end
end

function [C yh] = CostFunction(y_hist,N,w,dt)
yh = fftkernel(y_hist,w/dt);  %density

%formula for density
C = sum(yh.^2)*dt - 2* sum(yh.*y_hist)*dt...
        + 2*1/sqrt(2*pi)/w/N;
C = C * N* N;

%formula for rate
%C = dt*sum( yh.^2 - 2*yh.*y_hist + 2/sqrt(2*pi)/w*y_hist );

function y = fftkernel(x,w)
% y = fftkernel(x,w)
%
% Function `fftkernel' applies the Gauss kernel smoother to
% an input signal using FFT algorithm.
%
% Input argument
% x:    Sample signal vector.
% w: 	Kernel bandwidth (the standard deviation) in unit of
%       the sampling resolution of x.
%
% Output argument
% y: 	Smoothed signal.
%
% MAY 5/23, 2012 Author Hideaki Shimazaki
% RIKEN Brain Science Insitute
% http://2000.jukuin.keio.ac.jp/shimazaki

L = length(x);
Lmax = max(1:L+3*w);
n = 2^(nextpow2(Lmax));

X = fft(x,n);

f = (0:n-1)/n;
f = [-f(1:n/2+1) f(n/2:-1:2)];

K = exp(-0.5*(w*2*pi*f).^2);

y = ifft(X.*K,n);

y = y(1:L);

function y = logexp(x)
if x<1e2
    y = log(1+exp(x));
else
    y = x;
end

function y = ilogexp(x)
%ilogexp = @(x) log(exp(x)-1);
if x<1e2
    y = log(exp(x)-1);
else
    y = x;
end


%% Mesh Generator for Tecplot
% Generating a 2D mesh for Tecplot for an axisymmetric diffuser.
% by Manuel Diaz, 2012.09.15.

clear all; close all;
%% Parameters
L0 = 0; L1 = 10 + L0; L2 = 6 + L1 + L0;
H0 = 0; H1 = 0.5;
theta = deg2rad(5); % theta = 5 degress converted to radians
H2 = H1 + L2*tan(theta);

%% Number of elements of edges (ne)
ne_x1 = 25; ne_x2 = 40; ne_y = 40;

%% End Points for the rectangular zones:
Z1=[ L0,H1 ; L1,H1 ; L1,H0 ; L0,H0 ]; % Zone1
Z2=[ L1,H1 ; L2,H2 ; L2,H0 ; L1,H0 ]; % Zone2

%% Zone 1:
% There are 4 edge lines, each having several edge points.
% We use the Function "Pinterpol" to create the edge points for zone 1.

E1 = Pinterpol(Z1(1,1),Z1(1,2),Z1(2,1),Z1(2,2),ne_x1);
E2 = Pinterpol(Z1(4,1),Z1(4,2),Z1(3,1),Z1(3,2),ne_x1);

% Now generating the mesh for Zone 1
M1 = zeros(ne_x1+1,ne_y+1,2);
for i = 1:(ne_x1+1);
    V = Pinterpol(E1(i,1),E1(i,2),E2(i,1),E2(i,2),ne_y);
    M1(i,1:(ne_y+1),1:2) = V; % mesh1
end

%% Zone 2:
% Similarly for zone 2
E1 = Pinterpol(Z2(1,1),Z2(1,2),Z2(2,1),Z2(2,2),ne_x2);
E2 = Pinterpol(Z2(4,1),Z2(4,2),Z2(3,1),Z2(3,2),ne_x2);

% generating the mesh for Zone 2
M2 = zeros(ne_x2+1,ne_y+1,2);
for i = 1:(ne_x2+1);
    V = Pinterpol(E1(i,1),E1(i,2),E2(i,1),E2(i,2),ne_y);
    M2(i,1:(ne_y+1),1:2) = V; % mesh2
end

%% To Tecplot
% Writing Output data for Tecplot format:

file = fopen('mesh1.tec','w');
% h1 gets the handel for the file "mesh1.tec".
% 'w' specifies that it will be written.
% similarly 'r' is for reading and 'a' for appending.

fprintf(file, 'TITLE = "Mesh from Matlab"\n');
fprintf(file, 'VARIABLES = "X" "Y"\n');
fprintf(file, 'ZONE T = "Inlet zone"\n');
fprintf(file, 'I = %d, J = %d, K = 1, F = POINT\n\n', ne_x1+1,ne_y+1);

for j = 1:(ne_y+1)
    for i = 1:(ne_x1+1)
        fprintf(file, '%f\t%f\n', M1(i,j,1),M1(i,j,2));
    end
end

fprintf(file, 'ZONE T="Diffuser zone"\n');
fprintf(file, 'I = %d, J=%d, k=1, F=POINT\n\n', ne_x2+1,ne_y+1);

for j = 1:(ne_y+1)
    for i = 1:(ne_x2+1)
        fprintf(file, '%f\t%f\n', M2(i,j,1),M2(i,j,2));
    end
end

fclose(file);


function [X,Y,Z]=cylinder2(x,y,z,r,N,o)
%
%   [X,Y,Z]=cylinder2(x,y,z,r,N,o)
%
%   Vectors x, y, z define the central line of cylindrical surface
%   and vector r defines the radius of cylindrical surface, and has
%   the same length as x, y, z.
%
%   N is the number of points around the circumference. The default value
%   is N = 100.
%
%   Matrix o defines ovality of the directrix (circle) of cylindrical
%   surface. Its elements take values between 0 and 1 and apply to the
%   primary and secondary axis of directrix. The defeault values are
%   o=ones(length(x),2).
%
%   Matrices X, Y, Z define the cylindrical surface, surf(X,Y,Z) displays
%   the cylindrical surface.
%
%   Example 1: Horn
%
%              f=linspace(0,4*pi,100);
%              x=cos(f); y=sin(f); z=f; r=-1/99*([1:100]-1)+1;
%              [X,Y,Z]=cylinder2(x,y,z,r);
%
%   Example 2: Pot
%
%              x=[0 0 1 1 .5 .5]; y=[0 0 3 3 1.5 1.5];
%              z=[0 0 2 2 1 1];   r=[0 1 1.5 1.2 1 0];
%              [X,Y,Z]=cylinder2(x,y,z,r,6); view([-150 25])
%
%   Example 3: Plumbing
%
%              x=[0 0 0 0 0 0  1 1 1 1 1 1]; y=[0 .2 .2 1 1 .5 .5 1 1 .2 .2 0];
%              z=[1 1 1 1 0 0 0 0 1 1 1 1]; r=[.2 .2 .1 .1 .1 .1 .1 .1 .1 .1 .2 .2];
%              o=[1 1 .5 .5 .5 1 1 .5 .5 .5 1 1; 1 1 1 1 1 .5 .5 1 1 1 1 1];
%              [X,Y,Z]=cylinder2(x,y,z,r,8,o);
%
%
%   Example 4: Triangle , closed central line
%
%              f=linspace(0,2*pi,4);
%              x=cos(f-pi/6); y=sin(f-pi/6); z=zeros(4,1); r=0.2*ones(4,1);
%              [X,Y,Z]=cylinder3(x,y,z,r); view([0 90])
%
%
%
%   Copyright (c) 2011, Version 2.2
%   Avni Pllana <avniu66@hotmail.com>

X=[]; Y=[]; Z=[];

if nargin<5
    N=100;
end

x=x(:); y=y(:); z=z(:); r=r(:);

nx=length(x);
ny=length(y);
nz=length(z);
nr=length(r);

an=[nx ny nz nr];
if ~ismember(diff(an),[0 0 0],'rows')
    disp(' ')
    disp('x, y, z, r must have the same length!')
else
    if nx<2
        disp(' ')
        disp('The length of x must be greater than 1!')
    else

      if nargin<6
        o=ones(nx,2);
      else
        [o1,o2]=size(o);
        if o2>o1
            o=o';
        end
      end

      C=[x y z];
      D=diff(C);

      for i=1:nx-1
         if norm(D(i,:))>0
            E(i,:)=D(i,:)/norm(D(i,:));
         else
            E(i,:)=[0 0 0];
         end

      end

      if norm(C(1,:)-C(nx,:))<1e-10 && norm(cross(E(1,:),E(nx-1,:)))>0
         Closed=1;
         nxx=nx+1;
         E=[E;E(1,:)];
      else
         Closed=0;
         nxx=nx;
      end

      f=linspace(0,2*pi,N+1);
      for j=1:N+1
          xcc(j)=cos(f(j));
          ycc(j)=sin(f(j));
          zcc(j)=0;
      end

      for i=1:nx

          if i==1

              if ~Closed

                  d=[];
                  k=i;

                  while k<nx-1
                      if norm(cross(E(k,:),E(k+1,:)))==0
                          k=k+1;
                          d=[d k];
                      else
                          break
                      end

                  end

                  if norm(E(1,:))==0;
                      vz=E(2,:);
                  else
                      vz=E(1,:);
                  end

                  if k==nx-1
                     if norm(cross([0 0 1],vz))~=0
                         va=cross([0 0 1],vz);
                     else
                         va=cross([1 1 1],vz);
                     end
                  else
                     va=cross(E(k+1,:),vz);
                  end

                  vy=va/norm(va);
                  vx=cross(vy,vz);
                  V=[vx;vy;vz];
                  Vp=V;
                  Vpp=V;
                  alf=0;

              else

                  d=[];
                  vb=(E(1,:)+E(nx-1,:))/2;
                  vz=vb/norm(vb);
                  va=cross(E(1,:),E(nx-1,:));
                  vy=va/norm(va);
                  vx=cross(vy,vz);
                  V=[vx;vy;vz];
                  Vpp=V;

                  alf=acos(E(1,:)*E(nx-1,:)');

                  if abs(alf>3*pi/4)
                     alf=0;
                  end

              end

          else

             if ismember(i,d)
                 V=Vp;
                 alf=0;
             else
                    d=[];
                    k=i;

                    while k<nx-1
                      if norm(cross(E(k,:),E(k+1,:)))==0
                          k=k+1;
                          d=[d k];
                      else
                          break
                      end

                    end

                    if ~isempty(d) || i==nx
                          if norm(E(i-1,:))==0;
                              vz=E(i-2,:);
                          else
                              if i==nx
                                vz=E(i-1,:);
                              else
                                vz=E(i,:);
                              end
                          end

                          va=Vpp(2,:);
                          vy=va/norm(va);
                          vx=cross(vy,vz);
                          V=[vx;vy;vz];

                          Vp=V;
                          alf=0;

                    end

                    if i<nxx

                          vb=(E(i,:)+E(i-1,:))/2;
                          vz=vb/norm(vb);
                          va=cross(E(i,:),E(i-1,:));
                          vy=va/norm(va);
                          vx=cross(vy,vz);
                          V=[vx;vy;vz];

                          %%%%%%%%%%%%%
                          ang=acos(vy*Vpp(2,:)');
                          Vang=cross(vy,Vpp(2,:));
                          if Vang*vz'>0
                              ang=-ang;
                          end

                          A=[cos(ang) sin(ang); -sin(ang) cos(ang)];
                          xy=A*[xcc;ycc];
                          xcc=xy(1,:);
                          ycc=xy(2,:);
                          %%%%%%%%%%%%
                          Vpp=V;

                          alf=acos(E(i,:)*E(i-1,:)');

                         if abs(alf>3*pi/4)
                            alf=0;
                         end
                     end
             end

          end

          xc=o(i,1)*r(i)/cos(alf/2)*xcc;
          yc=o(i,2)*r(i)*ycc;
          xyz=[xc;yc;zcc];

          M=pinv(V);

          xyz1=M*xyz+repmat([x(i);y(i);z(i)],1,N+1);

          X(:,i)=xyz1(1,:)';
          Y(:,i)=xyz1(2,:)';
          Z(:,i)=xyz1(3,:)';

      end

       figure
       surf(X,Y,Z)
       shading interp
       camlight
       grid on
       axis equal

    end
end


% Data file PILZ3
% Forced damped vibrations of a mechanical
% system with one degree of freedom, contained
% a reverse pendulum.
  s     = 1; % degree of freedom
  L     = '2.5*qt1^2 - 1/2*c*q1^2 - 3.9*cos(10*q1)'; % Lagrangian
  QN{1} = '-k*qt1 + 10*sin(p*t)'; % generalized non potential force
  Tend  = 20;    % upper bound of integration
  qj0   = 0.05;  % initial coordinate
  qtj0  = 0;     % initial velocity
  eps   = 1e-10; % desirable accuracy
  np    = 3;     % number of parameters
  P{1}  = 'c';   % spring stiffness
  P{2}  = 'k';   % coefficient of damping
  P{3}  = 'p';   % disturbance frequency


function [sol,times,ocp] = bouncingball

  before_contact = ocl.Stage([], @before_contact_vars, @before_contact_ode, 'N', 3, 'd', 2);
  after_contact = ocl.Stage(1, @after_contact_vars, @after_contact_ode, ...
                            @after_contact_cost, 'N', 5, 'd', 2);

  before_contact.setInitialStateBounds('s', 1);
  before_contact.setInitialStateBounds('v', 0);
  before_contact.setEndStateBounds('s', 0);

  after_contact.setEndStateBounds('s', 1);

  ocp = ocl.MultiStageProblem({before_contact, after_contact}, {@stage_transition});

  [sol,times] = ocp.solve(ocp.getInitialGuess());

  % stage 1
  figure;
  subplot(1,2,1)
  hold on; grid on;
  ocl.plot(times{1}.states, sol{1}.states.s)
  ocl.plot(times{1}.states, sol{1}.states.v)
  legend({'s','v'})
  xlabel('time [s]');
  ylim([-5 3])
  yticks(-5:3)
  title('stage 1')

  % stage 2
  subplot(1,2,2)
  hold on; grid on;
  ocl.plot(times{2}.states, sol{2}.states.s)
  ocl.plot(times{2}.states, sol{2}.states.v)
  ocl.stairs(times{2}.controls, sol{2}.controls.F)
  legend({'s','v','F'})
  xlabel('time [s]');
  ylim([-5 3])
  yticks(-5:3)
  title('stage 2')

end

function before_contact_vars(sh)
  sh.addState('s');
  sh.addState('v');
end

function before_contact_ode(sh,x,~,~,~)
  sh.setODE('s', x.v);
  sh.setODE('v', -10);
end

function after_contact_vars(sh)
  sh.addState('s');
  sh.addState('v');
  sh.addControl('F');
end

function after_contact_ode(sh,x,~,u,~)
  sh.setODE('s', x.v);
  sh.setODE('v', -10 + 10*u.F);
end

function after_contact_cost(ch,~,~,u,~)
  ch.add( u.F^2 );
end

function stage_transition(ch, x0, xF)
  % x0 current stage
  % xF previous stage
  ch.add(x0.s, '==', xF.s);
  ch.add(x0.v, '==', -xF.v/2);
end


function [outR, outID] = makeBayesWeightedCorr1(Pr, bID, varargin)
%function [outR, outID] = makeBayesWeightedCorr1(Pr, bID, preComputedQ (optional))

outID = unique(bID);
h = histc(bID, outID);
if isempty(varargin)
    Q = makeQForWeightedCorr(h, size(Pr, 2));
else
    Q = varargin{1};
end

outR = zeros(length(outID), 1);
for i = 1:length(outR)
    outR(i) = makeWeightedCorr1(Q{h(i)}, reshape(Pr(bID == outID(i), :), [], 1));
end

end

function out = makeWeightedCorr1(xy, w);
%function out = makeWeightedCorr1(xy, w);

mxy = sum(xy.*repmat(w, 1, 2)/sum(w));
covxy = sum(w.*(xy(:, 1) - mxy(1)).*(xy(:, 2) - mxy(2)))/sum(w);
covxx = sum(w.*(xy(:, 1) - mxy(1)).*(xy(:, 1) - mxy(1)))/sum(w);
covyy = sum(w.*(xy(:, 2) - mxy(2)).*(xy(:, 2) - mxy(2)))/sum(w);
out = covxy/(sqrt(covyy*covxx));
end


function [ xnew, ferr, q ] = roots_rc ( n, x, fx, q )

%*****************************************************************************80
%
%% ROOTS_RC solves a system of nonlinear equations using reverse communication.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 January 2013
%
%  Author:
%
%    Original FORTRAN77 version by Gaston Gonnet.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Gaston Gonnet,
%    On the Structure of Zero Finders,
%    BIT Numerical Mathematics,
%    Volume 17, Number 2, June 1977, pages 170-183.
%
%  Parameters:
%
%    Input, integer N, the number of equations.
%
%    Input, real X(N).  Before the first call, the user should
%    set X to an initial guess or estimate for the root.  Thereafter, the input
%    value of X should be the output value of XNEW from the previous call.
%
%    Input, real FX(N), the value of the function at XNEW.
%
%    Workspace, real ( kind = 8 ) Q(2*N+2,N+2).  Before the first call
%    for a given problem, the user must set Q(2*N+1,1) to 0.0.
%
%    Output, real ( kind = 8 ) XNEW(N), a new point at which a function
%    value is requested.
%
%    Output, real ( kind = 8 ) FERR, the function error, that is, the sum of
%    the absolute values of the most recently computed function vector.
%
%    Workspace, real ( kind = 8 ) Q(2*N+2,N+2).
%
  ferr = sum ( abs ( fx(1:n) ) );
%
%  Initialization if Q(2*N+1,1) = 0.0.
%
  if ( q(2*n+1,1) == 0.0 )

    for i = 1 : n
      for j = 1 : n + 1
        q(i,j) = 0.0;
        q(i+1,j) = 0.0;
      end
      q(i,i) = 100.0;
      q(i+n,i) = 1.0;
    end

    q(2*n+1,1:n) = 1.0E+30;
    q(2*n+2,1:n) = n;

    for i = 1 : n
      q(i+n,n+1) = x(i);
    end

    q(1:n,n+1) = fx(1:n);

    q(2*n+1,n+1) = ferr;
    q(2*n+2,n+1) = 0.0;
    damp = 0.99;

  else

    jsus = 1;
    for i = 2 : n + 1
      if ( 2 * n <= q(2*n+2,i) )
        q(2*n+1,i) = 1.0E+30;
      end
      if ( q(2*n+2,jsus) < floor ( ( n + 3 ) / 2 ) )
        jsus = i;
      end
      if ( ( n + 3 ) / 2 <= q(2*n+2,i) && q(2*n+1,jsus) < q(2*n+1,i) )
        jsus = i;
      end
    end

    for i = 1 : n
      q(i+n,jsus) = x(i);
      q(i,jsus) = fx(i);
    end

    q(2*n+1,jsus) = ferr;
    q(2*n+2,jsus) = 0;
    jsma = 1;
    damp = 0.0;

    for j = 1 : n + 1
      if ( 1.0E+30 / 10.0 < q(2*n+1,j) )
        damp = 0.99;
      end
      if ( q(2*n+1,j) < q(2*n+1,jsma) )
        jsma = j;
      end
    end

    if ( jsma ~= n + 1 )
      for i = 1 : 2 * n + 2
        t = q(i,jsma);
        q(i,jsma) = q(i,n+1);
        q(i,n+1) = t;
      end
    end

  end

  q(1:n,n+2) = q(1:n,n+1);
%
%  Call the linear equation solver, which should not destroy the matrix
%  in Q(1:N,1:N), and should overwrite the solution into Q(1:N,N+2).
%
  q(1:n,n+2) = q(1:n,1:n) \ q(1:n,n+2);

  sump = sum ( q(1:n,n+2) );

  if ( abs ( 1.0 - sump ) <= 1.0E-10 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'ROOT - Fatal error!\n' );
    fprintf ( 1, '  SUMP almost exactly 1.\n' );
    fprintf ( 1, '  SUMP = %g\n', sump );
    error ( 'ROOTS_RC - Fatal error!' );
  end

  for i = 1 : n
    xnew(i) = q(i+n,n+1);
    for j = 1 : n
      xnew(i) = xnew(i) - q(i+n,j) * q(j,n+2);
    end
%
%  If system not complete, damp the solution.
%
    xnew(i) = xnew(i) / ( 1.0 - sump ) * ( 1.0 - damp ) ...
      + q(i+n,n+1) * damp;

  end

  for j = 1 : n + 1
    q(2*n+2,j) = q(2*n+2,j) + 1.0;
  end

  return
end


function M = shapefitfactory(VJt)
% Linear manifold structure for optimization over the ShapeFit search space
%
% function M = shapefitfactory(VJt)
%
% Input: VJt is a matrix of size dxn, such that VJt * ones(n, 1) = 0.
%
% Returns M, a structure describing the Euclidean space of d-by-n matrices
% equipped with the standard Frobenius distance and associated trace inner
% product, as a manifold for Manopt. Matrices on M, denoted by T, have size
% dxn and obey T*ones(n, 1) = 0 (centered columns) and <VJt, T> = 1, where
% <A, B> = Trace(A' * B).
%
% See this paper: http://arxiv.org/abs/1506.01437
% ShapeFit: Exact location recovery from corrupted pairwise directions, 2015
% Paul Hand, Choongbum Lee, Vladislav Voroninski
%
% See also: shapefit_smoothed

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, June 18, 2015.
% Contributors:
% Change log:

    [d, n] = size(VJt);

    M.name = @() sprintf('ShapeFit space of size %d x %d', d, n);

    M.dim = @() d*n - d - 1;

    M.inner = @(x, d1, d2) d1(:).'*d2(:);

    M.norm = @(x, d) norm(d, 'fro');

    M.dist = @(x, y) norm(x-y, 'fro');

    M.typicaldist = @() sqrt(d*n);

    M.proj = @(T, U) projection(U);
    VJt_normed = VJt / norm(VJt, 'fro');
    function PU = projection(U)
        % Center the columns
        PU = bsxfun(@minus, U, mean(U, 2));
        % Remove component along VJt
        % Note: these two actions can be executed separately, without
        % interference, owing to VJt having centered columns itself.
        PU = PU - (VJt_normed(:)'*U(:))*VJt_normed;
    end

    M.egrad2rgrad = M.proj;

    M.ehess2rhess = @(x, eg, eh, d) projection(eh);

    M.tangent = @(x, d) d;

    M.exp = @exp;
    function y = exp(x, d, t)
        if nargin == 3
            y = x + t*d;
        else
            y = x + d;
        end
    end

    M.retr = M.exp;

	M.log = @(x, y) y-x;

    M.hash = @(x) ['z' hashmd5(x(:))];

    M.randvec = @(x) randvec();
    function u = randvec()
        u = projection(randn(d, n));
        u = u / norm(u, 'fro');
    end

    % We exploit the fact that VJt_normed belongs to the manifold
    M.rand = @() VJt_normed + randn(1) * randvec();

    M.lincomb = @matrixlincomb;

    M.zerovec = @(x) zeros(d, n);

    M.transp = @(x1, x2, d) d;

    M.pairmean = @(x1, x2) .5*(x1+x2);

    M.vec = @(x, u_mat) u_mat(:);
    M.mat = @(x, u_vec) reshape(u_vec, [d, n]);
    M.vecmatareisometries = @() true;

end


% SFR_Bif_Diag_Second_Method - Bifurcation diagram with history.
% Copyright Springer 2013 Stephen Lynch.
clear
format long;
halfN=19999;N=2*halfN+1;N1=1+halfN;
E(1)=0.4;B=0.15;Pmax=16;

% Ramp the power up
for n=1:halfN
    E(n+1)=sqrt(n*Pmax/N1)+B*E(n)*exp(1i*abs(E(n))^2);
    Esqr(n+1)=abs(E(n+1))^2;
end

% Ramp the power down
for n=N1:N
    E(n+1)=sqrt(2*Pmax-n*Pmax/N1)+B*E(n)*exp(1i*abs(E(n))^2);
    Esqr(n+1)=abs(E(n+1))^2;
end

for n=1:halfN
    Esqr1(n)=Esqr(N+1-n);
    ptsup(n)=n*Pmax/N1;
end

% Plot the bifurcation diagrams
fsize=15;
hold on
set(gca,'xtick',0:4:16,'FontSize',fsize)
set(gca,'ytick',0:5:25,'FontSize',fsize)
plot(ptsup(1:halfN),Esqr(1:halfN),'.','MarkerSize',1);
plot(ptsup(1:halfN),Esqr1(1:halfN),'.','MarkerSize',1);
xlabel('Input Power','FontSize',fsize);
ylabel('Output Power','FontSize',fsize);
hold off


y       = load('data/motorcycle.dat')';
time    = y(1, :);
delta   = y(2, [2:end 1]);
y       = y(3, :);

%% Spline smoothing model %%
spline              = ssm_spline(delta);
spline              = estimate(y, spline, [1 0.1]);
[alphahat V]        = statesmo(y, spline);
conf                = squeeze(1.96*realsqrt(V(1, 1, :)))';
[eps eta epsvar]    = disturbsmo(y, spline);

figure('Name', 'Motorcycle acceleration data analyzed by a cubic spline');
subplot(2, 1, 1), plot(time, alphahat(1, :), 'b'), hold all, plot(time, [alphahat(1, :)+conf; alphahat(1, :)-conf], 'b:'), scatter(time, y, 10, 'r', 's', 'filled'), hold off, title('Spline and 95% confidence intervals'), ylim([-140 80]), set(gca,'YGrid','on');
subplot(2, 1, 2), scatter(time, eps./realsqrt(epsvar), 10, 'r', 's', 'filled'), title('Standardized irregular'), set(gca,'YGrid','on');
if ispc, set(gcf, 'WindowStyle', 'docked'); end

%% Continuous local level model %%
abseps          = abs(eps);
contllm         = [ssm_gaussian ssmodel('continuous local level', 0, 1, 1, 1, ssmat(0, [], true, zeros(size(delta)), true), 'Qd', {@(X) exp(2*X)*delta}, {[]}, ssparam({'zeta var'}, '1/2 log'))];
[contllm logL]  = estimate(abseps, contllm, [1 0.1]);
alphahat        = statesmo(abseps, contllm);

figure('Name', 'Correction for heteroscedasticity');
subplot(3, 1, 1), plot(time, alphahat, 'b'), hold all, scatter(time, abseps, 10, 'r', 's', 'filled'), hold off, title('Absolute smoothed irregular and h^\ast_t'), ylim([0 87.5]);

%% Correction for heteroscedasticity %%
h2                  = (alphahat/alphahat(1)).^2;
splineh             = [ssmodel('Heteroscedastic noise', ssmat(0, [], true, zeros(size(h2)), true), zeros(1, 0), [], [], [], 'Hd', {@(X) exp(2*X)*h2}, {[]}, ssparam({'epsilon var'}, '1/2 log')) spline];
splineh             = estimate(y, splineh, [1 0.1]);
[alphahath Vh]      = statesmo(y, splineh);
confh               = squeeze(1.96*realsqrt(Vh(1, 1, :)))';
[epsh eta epsvarh]  = disturbsmo(y, splineh);

subplot(3, 1, 2), plot(time, alphahath(1, :), 'b'), hold all, plot(time, [alphahath(1, :)+confh; alphahath(1, :)-confh], 'b:'), scatter(time, y, 10, 'r', 's', 'filled'), hold off, title('Spline and 95% confidence intervals'), ylim([-140 80]), set(gca,'YGrid','on');
subplot(3, 1, 3), scatter(time, epsh./realsqrt(epsvarh), 10, 'r', 's', 'filled'), title('Standardized irregular'), set(gca,'YGrid','on');
if ispc, set(gcf, 'WindowStyle', 'docked'); end


% MLRC Muli-response Linear Regression Combiner
%
%   W = A*(WU*MLRC)
%   W = WT*MLRC(B*WT)
%   D = C*W
%
% INPUT
%   A   Dataset used for training base classifiers as well as combiner
%   B   Dataset used for training combiner of trained base classifiers
%   C   Dataset used for testing (executing) the combiner
%   WU  Set of untrained base classifiers, see STACKED
%   WT  Set of trained base classifiers, see STACKED
%
% OUTPUT
%   W   Trained Muli-response Linear Regression Combiner
%   D   Dataset with prob. products (over base classifiers) per class
%
% DESCRIPTION
% Using dataset A that contains the posterior probabilities of each instance
% belonging to each class predicted by the base classifiers to train a
% multi-response linear regression combiner.
% If the original classification problem has K classes, it is converted
% into K seperate regression problems, where the problem for class c has
% instances with responses equal to 1 when they have label c and zero
% otherwise. Put in another way, this function establish a multi-response
% linear regression model for each class and utilize these models to estimate
% the probability that the instances belong to each class.
% Note that in the model for class c, only the probabilities of class c
% predicted by the set of base classifiers are used.
%
% REFERENCE
% 1. Ting, KM, Witten IH. Issues in stacked generalization, Journal of
% Artificial Intelligent Research, 1999, 10: 271-289.
% 2. Dzeroski S, Zenko B. Is combining classifiers with stacking better
% than selecting the best one? Machine Learning, 2004, 54(3): 255-273.
%
% SEE ALSO (PRTools Guide)
% DATASETS, MAPPINGS, STACKED, CLASSC, TESTD, LABELD

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

function W = mlrc(A)

        name = 'MLR combiner';

    % If there are no inputs, return an untrained mapping.
    % Handle untrained calls like MLRC([])
    if nargin < 1 || isempty(A)
        W = prmapping(mfilename);
        W = setname(W,name);
        return
    end

    islabtype(A,'crisp');       % allow crisp labels only
    isvaldfile(A,1,2);          % at least one object per class and 2 classes

    A = testdatasize(A,'features'); % test whether they fit
    A = setprior(A,getprior(A));    % avoid many warnings
    [m,k,c] = getsize(A);           % size of training set; (m objects; k features; c classes)
    L = k/c;                        % compute the number of classifiers
    A = setfeatlab(A,repmat([1:c]',L,1)); % reset the feature labels of dataset A such that the first c features correspond to
                                          % the first classifier, the next c features correspond to the second classifier, ect.
    C = zeros(c*L,c);                     % register the coefficients of each model
    options = optimset('ToLX',1e-4);
    for i = 1:c                         % run over all classes
        Res = zeros(m,1);
        Index = find(A.featlab == i);   % find the indices correspond to the jth class
        B = seldat(A,[],Index);         % select the data corresponding to the jth class(m x L matrix)
        I = A.nlab == i;
        Res(I) = 1;
        [x,resnorm,residual,exitflag] = lsqnonneg(B.data,Res,[],options); % compute the nonnegative coefficients
        if exitflag == 0
            resnorm
        end

        for j = 1:L
            C((j-1)*c+i,i) = x(j);
        end
    end

    W = affine(C,[],A,getlablist(A),k,c);
    W = setname(W,name);

return


classdef RWMOP20 < PROBLEM
% <multi> <real> <constrained>
% Hydro-static thrust bearing design problem

%------------------------------- Reference --------------------------------
% A. Kumar, G. Wu, M. Ali, Q. Luo, R. Mallipeddi, P. Suganthan, and S. Das,
% A benchmark-suite of real-world constrained multi-objective optimization
% problems and some baseline results, Swarm and Evolutionary Computation,
% 2021, 67: 100961.
%------------------------------- Copyright --------------------------------
% Copyright (c) 2023 BIMK Group. You are free to use the PlatEMO for
% research purposes. All publications which use this platform or any code
% in the platform should acknowledge the use of "PlatEMO" and reference "Ye
% Tian, Ran Cheng, Xingyi Zhang, and Yaochu Jin, PlatEMO: A MATLAB platform
% for evolutionary multi-objective optimization [educational forum], IEEE
% Computational Intelligence Magazine, 2017, 12(4): 73-87".
%--------------------------------------------------------------------------

    methods
        %% Initialization
        function Setting(obj)
            obj.M        = 2;
            obj.D        = 4;
            obj.lower    = [ 1, 1,  1e-6,1];
            obj.upper    = [16, 16, 16*1e-6,16];
            obj.encoding = ones(1,obj.D);
        end
        %% Evaluate multiple solutions
        function Population = Evaluation(obj,varargin)
            x = varargin{1};
            R = x(:,1); Ro = x(:,2);  mu = x(:,3); Q = x(:,4);
            gamma = 0.0307; C = 0.5; n = -3.55; C1 = 10.04;
            Ws = 101000; Pmax = 1000; delTmax = 50; hmin = 0.001;
            gg = 386.4; N = 750;
            P    = (log10(log10(8.122*1e6.*mu+0.8))-C1)./n;
            delT = 2.*(10.^P-560);
            Ef   = 9336.*Q.*gamma.*C.*delT;
            h    = (2.*pi.*N./60).^2.*2.*pi.*mu./Ef.*(R.^4./4-Ro.^4./4)-1e-5;
            Po   = (6.*mu.*Q./(pi.*h.^3)).*log(R./Ro);
            W    = pi.*Po./2.*(R.^2-Ro.^2)./(log(R./Ro)-1e-5);
            % Objective function
            f(:,1) = (Q.*Po./0.7+Ef)./12;
            f(:,2) = gamma./(gg.*Po).*(Q./(2.*pi.*R.*h));
            % Constraints
            g(:,1) = Ws-W;
            g(:,2) = Po-Pmax;
            g(:,3) = delT-delTmax;
            g(:,4) = hmin-h;
            g(:,5) = Ro-R;
            g(:,6) = f(:,2)-0.001;
            g(:,7) = W./(pi.*(R.^2-Ro.^2)+1e-5)-5000;
            Population = SOLUTION(varargin{1},f,g,varargin{2:end});
            obj.FE     = obj.FE + length(Population);
        end
        %% Generate a point for hypervolume calculation
        function R = GetOptimum(obj,~)
            R = [2.6725846e+02  -2.7672651e-05];
        end
    end
end


function square_hex_grid_test02 ( )

%*****************************************************************************80
%
%% SQUARE_HEX_GRID_TEST02 tests HEX_GRID_01_H.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2009
%
%  Author:
%
%    John Burkardt
%
  test_num = 17;

  nodes_per_layer_test = [ ...
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 41, 81, 101, 1001, 10001 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'SQUARE_HEX_GRID_TEST02\n' );
  fprintf ( 1, '  For a hexagonal grid of points in the unit square,\n' );
  fprintf ( 1, '  given NODES_PER_LAYER, the number of grid points\n' );
  fprintf ( 1, '  along the first layer,\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  HEX_GRID_01_H computes HX and HY, the spacings\n' );
  fprintf ( 1, '  in the row and column directions.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    NODES    LAYERS   HX          HY\n' );
  fprintf ( 1, '      PER\n' );
  fprintf ( 1, '    LAYER\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
    nodes_per_layer = nodes_per_layer_test ( test );
    layers = hex_grid_01_layers ( nodes_per_layer );
    [ hx, hy ] = hex_grid_01_h ( nodes_per_layer );
    fprintf ( 1, '  %6d  %6d  %10f  %10f\n', nodes_per_layer, layers, hx, hy );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  LAYERS is chosen so that LAYERS-1 layers just fit\n' );
  fprintf ( 1, '  inside the unit square, but LAYERS layers do not.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  LAYERS      HY     (LAYERS-1)*HY    LAYERS*HY\n' );
  fprintf ( 1, '\n' );

  for test = 1 : test_num
    nodes_per_layer = nodes_per_layer_test ( test );
    layers = hex_grid_01_layers ( nodes_per_layer );
    [ hx, hy ] = hex_grid_01_h ( nodes_per_layer );

    temp1 =  ( layers - 1 ) * hy;
    temp2 =  ( layers ) * hy;

    fprintf ( 1, '  %6d  %10f  %10f  %10f\n', ...
      nodes_per_layer, hy, temp1, temp2 );

  end

  return
end


function f=loglikGaPfromVWH(varargin)
% f=loglikGaPfromVWH(varargin)
% complete log likellihood of the GaP model
% Vxt =     varargin{1};        %data (XxT)
% Wxk =     varargin{2};        %basis functions (XxK)
% Hkt =     varargin{3};        %intensities (KxT)
% alpha =   varargin{4};        %parameters of the Gamma blinking (Kx1)
% beta =    varargin{5};        %parameters of the Gamma blinking (Kx1)
% peval =   varargin{6};        %parameters
% Gamma distribution with mean alpha/beta!
% X: number of pixels
% T: number of images (time - slices)
% K: number of components

Vxt =     varargin{1};        %data (XxT)
Wxk =     varargin{2};        %basis functions (XxK)
Hkt =     varargin{3};        %intensities (KxT)
alpha =   varargin{4};        %parameters of the Gamma blinking (Kx1)
beta =    varargin{5};        %parameters of the Gamma blinking (Kx1)
peval =   varargin{6};        %parameters

k=size(Wxk,2);
if length(alpha) ==1; alpha = repmat(alpha,k, 1); end
if length(beta) ==1; beta = repmat(beta,k, 1); end
%[Wxkbg,Hktbg]=addbg(Wxk, Hkt, peval.bg);
%P=Wxkbg*Hktbg; %current approximation (XxT)
P=Wxk*Hkt; %current approximation (XxT)

%Poisson contribution
t1=Vxt.*log(P) - P - factorialapprox(Vxt); %(XxT)
%Gamma contribution
t2a=bsxfun(@times,(alpha-1),log(Hkt)) - bsxfun(@times,beta,Hkt); % (KxT)
t2b=-alpha.*log(beta)-log(gamma(alpha)); %(1xK)

f=sum(t1(:))+sum(t2a(:))+sum(t2b(:));
% Conjugate gradient is mimimizing! for this it needs to be f=-f;


function [to_fine, from_fine] = twoDquad_spline(x_fine,y_fine,x_knots,y_knots)
% Create 2D quadratic polynomial based spline approximation
%
% by SeHyoun Ahn, July 2016
%
% REFERENCE: To be Written
%
% PARAMTERS:
%    x_fine,y_fine = fine grid points
%    x_knots,y_knots = coarser grid to reduce to
%
% OUTPUTS:
%    to_fine = change of basis from spline basis to finer grid points
%    from_fine = change of basis from finer grid points to spline basis
%
% EXAMPLES:
%   x = linspace(-1,1,100)';
%   y = linspace(-1,1,100)';
%
%   % z = e^(-(x^2+y^2));
%   z = exp(-bsxfun(@plus,x.^2,y'.^2));
%
%   knot_x = linspace(-1,1,4)';
%   knot_y = linspace(-1,1,4)';
%
%   [to_fine, from_fine] = twoDquad_spline(x,y,knot_x,knot_y);
%
%   z_approxed = to_fine*from_fine*z(:);
%
%   surf(z);
%   hold on;
%   disp('press any key');
%   pause();
%   surf(reshape(z_approxed,100,100));
%
% SYNTAX:
% [to_fine, from_fine] = twoDquad_spline(x_fine,y_fine,x_knots,y_knots)

n_x_fine = length(x_fine);
n_y_fine = length(y_fine);

n_x_knots = length(x_knots);
n_y_knots = length(y_knots);
h_x = diff(x_knots);
h_y = diff(y_knots);

% Find the Location of Rectangle
x_locs = sum(bsxfun(@ge,x_fine,x_knots'),2);
x_locs = min(x_locs,n_x_knots-1);
x_adjusted = (x_fine - x_knots(x_locs))./h_x(x_locs);

y_locs = sum(bsxfun(@ge,y_fine,y_knots'),2);
y_locs = min(y_locs,n_y_knots-1);
y_adjusted = (y_fine - y_knots(y_locs))./h_y(y_locs);

xx = bsxfun(@times,x_adjusted,ones(1,n_y_fine));
yy = bsxfun(@times,ones(n_x_fine,1),y_adjusted');

xx_locs = bsxfun(@times,x_locs,ones(1,n_y_fine));
yy_locs = bsxfun(@times,ones(n_x_fine,1),y_locs');

% Stacked value of which rectangle the grid point is in
position = xx_locs(:) + (yy_locs(:)-1)*(n_x_knots-1);

% Evaluation of Polynomial Basis
polynomials_stacked = [ones(n_x_fine*n_y_fine,1),  xx(:),  yy(:),  ...
                        xx(:).^2,  xx(:).*yy(:),  yy(:).^2,  ...
                        xx(:).^2.*yy(:),  xx(:).*yy(:).^2];

evaluation = zeros(n_x_fine*n_y_fine,8*(n_x_knots-1)*(n_y_knots-1));

for i=(n_x_knots-1)*(n_y_knots-1):-1:1
    locs = find(position==i);
    evaluation(locs,(i-1)*8+1:8*i) = polynomials_stacked(locs,:);
end

evaluation = sparse(evaluation);

coeff_change = [1, 0, 0, 0, 0, 0, 0, 0;         % f(0,0)
                1, 1, 0, 1, 0, 0, 0, 0;         % f(1,0)
                1, 0, 1, 0, 0, 1, 0, 0;         % f(0,1)
                1, 1, 1, 1, 1, 1, 1, 1;         % f(1,1)
                0, 1, 0, 0, 0, 0, 0, 0;         % dx(0,0)
                0, 0, 1, 0, 0, 0, 0, 0;         % dy(0,0)
                0, 0, 1, 0, 1, 0, 1, 0;         % dy(1,0)
                0, 1, 0, 0, 1, 0, 0, 1];        % dx(0,1)

revert_change = sparse(inv(coeff_change));
aux = kron(speye(n_y_knots-1),spdiags(ones(n_x_knots-1,1),0,n_x_knots-1,n_x_knots));

%% Unpack Values-Derivatives to Proper Location
f00 = [aux,sparse((n_x_knots-1)*(n_y_knots-1),2*n_x_knots*n_y_knots-n_y_knots)]';
f10 = [sparse((n_x_knots-1)*(n_y_knots-1),1),aux,sparse((n_x_knots-1)*(n_y_knots-1),2*n_x_knots*n_y_knots-n_y_knots-1)]';
f01 = [sparse((n_x_knots-1)*(n_y_knots-1),n_x_knots),aux,sparse((n_x_knots-1)*(n_y_knots-1),2*n_x_knots*n_y_knots-n_x_knots-n_y_knots)]';
f11 = [sparse((n_x_knots-1)*(n_y_knots-1),n_x_knots+1),aux,sparse((n_x_knots-1)*(n_y_knots-1),2*n_x_knots*n_y_knots-n_x_knots-n_y_knots-1)]';
dx00 = [sparse((n_x_knots-1)*(n_y_knots-1),n_x_knots*n_y_knots),spdiags(repmat(h_x,n_y_knots-1,1),0,(n_x_knots-1)*(n_y_knots-1),(n_x_knots-1)*(n_y_knots-1)),sparse((n_x_knots-1)*(n_y_knots-1),n_x_knots*n_y_knots-1)]';
dx01 = [sparse((n_x_knots-1)*(n_y_knots-1),n_x_knots*n_y_knots+n_x_knots-1),spdiags(repmat(h_x,n_y_knots-1,1),0,(n_x_knots-1)*(n_y_knots-1),(n_x_knots-1)*(n_y_knots-1)),sparse((n_x_knots-1)*(n_y_knots-1),n_x_knots*n_y_knots-n_x_knots)]';
aux = kron(spdiags(h_y,0,n_y_knots-1,n_y_knots-1),spdiags(ones(n_x_knots-1,1),0,n_x_knots-1,n_x_knots));
dy00 = [sparse((n_x_knots-1)*(n_y_knots-1),2*n_x_knots*n_y_knots-n_y_knots),aux]';
dy10 = [sparse((n_x_knots-1)*(n_y_knots-1),2*n_x_knots*n_y_knots-n_y_knots+1),aux(:,1:end-1)]';

% Warning: Overwriting aux matrix here
aux = [f00(:),f10(:),f01(:),f11(:),dx00(:),dy00(:),dy10(:),dx01(:)]';

% Change Value/Derivatives to Coefficient Basis
aux = revert_change*aux;

%% A nightmare set of transformations. Good luck!
% These are supposed to reorder things to match location of the basis
% expansion
aux = reshape(aux,8*(3*n_x_knots*n_y_knots-n_x_knots-n_y_knots),(n_x_knots-1)*(n_y_knots-1));
permute = reshape(1:8*(3*n_x_knots*n_y_knots-n_x_knots-n_y_knots),8,3*n_x_knots*n_y_knots-n_x_knots-n_y_knots)';
aux = reshape(aux(permute(:),:),3*n_x_knots*n_y_knots-n_x_knots-n_y_knots,8*(n_x_knots-1)*(n_y_knots-1))';

%% Finally Basis Change
to_fine = evaluation*aux;

% Sometimes less than full basis are required up to machine accuarcy, so reduce with SVD
[u,d,~] = svd(full(to_fine),'econ');
singles = find(diag(d)>d(1,1)*eps*10);

% Basis Change Functions
to_fine = u(:,singles)*d(singles,singles);
% Since we took an SVD, so we can just invert by multiplication
from_fine = (d(singles,singles)\u(:,singles)');


function [x, timing] = blendenpik_under_alternative(A, b, params)
% [x, timing] = blendenpik_under(A, b, params)
%
% Alternative function for solving the equation
% x = arg min norm(A * x - b, 2) using Blendenpik, where A has
% more columns than rows. Less stable than the regular version.
%
% "params" - parameters governning the method.
%    params.type - type of mixing transform. Optional values: 'DCT', 'DHT', 'WHT'.
%                  Default is DHT.
%    params.gamma - gamma * m columns will be sampled (A is m-by-n).
%                   Default is 4.
%    params.preprocess_steps - number of mixing steps to do in advance.
%                               Default is 1.
%    params.maxcond - maximum condition number of the preconditioner.
%                     Default is 1 / (5 * epsilon_machine).
%    params.tol - convergence thershold for LSQR.
%                 Default is 1e-14.
%    params.maxit - maximum number of LSQR iterations.
%                   Default is 1000.
%    params.lsvec - whether to output in "timing" the LSQR residuals.
%                   Default is false.
%    params.use_full_lsqr - whether to use LSQR with full
%                           orthogonalization. Useful for
%                           preprocess_steps=0.
%                           Default is false.
%
% Output:
%   x - the solution.
%   timing - statistics on the time spent on various phases.
%
% 6-December 2009, Version 1.3
% Copyright (C) 2009, Haim Avron and Sivan Toledo.

if (nargin < 3)
    params = struct;
end

if (~isfield(params, 'type'));
    params.type = 'DHT';
end

if (~isfield(params, 'gamma'))
    params.gamma = 4;
end

if (~isfield(params, 'preprocess_steps'))
    params.preprocess_steps = 1;
end

if (~isfield(params, 'tol'))
    params.tol = 1e-14;
end

if (~isfield(params, 'maxit'))
    params.maxit = 1000;
end

if (~isfield(params, 'maxcond'))
    params.maxcond = 1 / (5 * eps);
end

if (~isfield(params, 'lsvec'))
    params.lsvec = false;
end

if (~isfield(params, 'slight_coherence'))
    params.slight_coherence = 0;
end

if (~isfield(params, 'use_full_lsqr'))
    params.use_full_lsqr = false;
end

tstart = wtime;

%% Build preconditioner
t1 = wtime;

[m, n] = size(A);
AT = A';
t0 = wtime;
frut_D = sign(randn(n, 1));
B = fast_unitary_transform(AT, frut_D, params.type);
nn = size(B, 1);
frut_D(n+1:nn) = 0;
frut_time = wtime - t0;
disp(sprintf('\t\tRandom unit diagonal + unitary transformation time: %.2f sec', frut_time));
timing.precond_timing.timing.frut_time = frut_time;

t0 = wtime;
t = params.gamma * m / nn;
s = rand(nn, 1);
SB = B(find(s < t), :);
sample_time = wtime - t0;
disp(sprintf('\t\tRandom sampling time: %.2f sec', sample_time));
timing.precond_timing.sample_time = sample_time;

t0 = wtime;
[Y, tau] = mex_dgeqrf(SB);
qr_time = wtime - t0;
disp(sprintf('\t\tQR on random sample time: %.2f sec', qr_time));
timing.qr_time = qr_time;

timing.preprocess_total_time = wtime - t1;
disp(sprintf('\tPreprocessing time: %.2f sec', timing.preprocess_total_time));

%% One solution
t1 = wtime;
y = mex_dtrsm(Y, b, 1.0, 'L', 'U', 'T', 'N');
ssz = size(Y, 1);
p0 = mex_dormqr(Y, tau, [y; zeros(ssz-m, 1)], 'L', 'N');
p1 = zeros(nn, 1); p1(s < t) = p0;
p2 = fast_unitary_transform(p1, frut_D, ['I' params.type]);
p = p2(1:n);
timing.find_non_min_time = wtime - t1;
disp(sprintf('\tFind a non-minimal solution: %.2f sec', timing.find_non_min_time));

%% LSQR
t1 = wtime;
R = triu(Y(1:m, 1:m));
% clear Y;
% clear SB
% clear tau;
if (~params.lsvec)
    if (~params.use_full_lsqr)
        [x0, timing.lsqr_its] = dense_lsqr(AT, p, R, params.tol, params.maxit);
    else
        [x0, timing.lsqr_its] = dense_full_lsqr(AT, p, R, params.tol, params.maxit);
    end
else
    [x0, timing.lsqr_its, timing.lsvec, timing.resvec] = dense_lsqr(AT, p, R, params.tol, params.maxit);
end
timing.lsqr_time = wtime - t1;
disp(sprintf('\tLSQR time: %.2f sec', timing.lsqr_time));

%% Mult by AT to get final solution
t1 = wtime;
x = AT * x0;
timing.multAT_time = wtime - t1;
disp(sprintf('\tMultiply by A'' time: %.2f sec', timing.multAT_time));
timing.total_time = wtime - tstart;
disp(sprintf('Total time: %.2f sec', timing.total_time));


function [f,J] = spm_fx_phase (phi,u,P,M)
% State equation for a phase-coupled oscillator
% FORMAT [f,J] = spm_fx_phase (phi,u,P,M)
%
% phi       state variable
% u         []
% P         model (variable) parameter structure
% M         model (fixed) parameter structure
%
% f         Flow vector, dphi/dt
% J         Jacobian, J(i,j)=df_i/dphi_j
%__________________________________________________________________________
% Copyright (C) 2009 Wellcome Trust Centre for Neuroimaging

% Will Penny
% $Id: spm_fx_phase.m 2908 2009-03-20 14:54:03Z will $

% Sin terms
if isfield(P,'As')
    Nr=size(P.As,1);
    Ns=size(P.As,3);

    % negative abs
    Ahs=~(P.As==0);
    As=-abs(P.As).*Ahs;
else
    Ns=0;
end

% Cos terms
if isfield(P,'Ac')
    Nc=size(P.Ac,3);
    Nr=size(P.Ac,1);

    % Positive abs
    Ahc=~(P.Ac==0);
    Ac=abs(P.Ac).*Ahc;
else
    Nc=0;
end

% Flow vector
f=zeros(Nr,1);
for i=1:Nr,
    change=0;
    for j=1:Nr,
        phi_diff=phi(i)-phi(j);
        for n=1:Ns,
            change=change+As(i,j,n)*sin(n*phi_diff);
        end
        for n=1:Nc,
            change=change+Ac(i,j,n)*cos(n*phi_diff);
        end
    end
    exc=M.freq+P.df(i)+change;
    f(i)=2*pi*exc;
end

if nargout == 1; return, end

% Jacobian
As=-As;
for i=1:Nr,
    for j=1:Nr,
        jac=0;
        if i==j
            % Diagonal
            for jj=1:Nr,
                for n=1:Ns,
                    jac=jac-n*As(i,jj,n);
                end
            end
        else
            % Off-diagonal
            phi_diff=phi(i)-phi(j);
            for n=1:Ns,
                jac=jac+n*As(i,j,n)*cos(n*phi_diff);
            end
            for n=1:Nc,
                jac=jac+n*Ac(i,j,n)*sin(n*phi_diff);
            end
        end
        J(i,j)=jac;
    end
end
J=J*2*pi;


function [x, R] = orth_at(x, pos, dir, apply)
    %ORTH_AT Orthogonalize single core.
    %   X = ORTH_AT( X, POS, 'LEFT') left-orthogonalizes the core at position POS
    %   and multiplies the corresponding R-factor with core POS+1. All other cores
    %   are untouched. The modified tensor is returned.
    %
    %   X = ORTH_AT( X, POS, 'RIGHT') right-orthogonalizes the core at position POS
    %   and multiplies the corresponding R-factor with core POS-1. All other cores
    %   are untouched. The modified tensor is returned.
    %
    %   See also ORTHOGONALIZE.

    %   TTeMPS Toolbox.
    %   Michael Steinlechner, 2013-2016
    %   Questions and contact: michael.steinlechner@epfl.ch
    %   BSD 2-clause license, see LICENSE.txt

    if ~exist('apply', 'var')
        apply = true;
    end

    sz = size(x.U{pos});

    if length(sz) == 2
        sz = [sz, 1];
    end

    if strcmpi(dir, 'left')
        [Q, R] = qr_unique(unfold(x.U{pos}, 'left'));
        x.U{pos} = reshape(Q, [sz(1), sz(2), size(Q, 2)]);

        if apply
            x.U{pos + 1} = tensorprod_ttemps(x.U{pos + 1}, R, 1);
        end

    elseif strcmpi(dir, 'right')
        % mind the transpose as we want to orthonormalize rows
        [Q, R] = qr_unique(unfold(x.U{pos}, 'right')');
        x.U{pos} = reshape(Q', [size(Q, 2), sz(2), sz(3)]);

        if apply
            x.U{pos - 1} = tensorprod_ttemps(x.U{pos - 1}, R, 3);
        end

    else
        error('Unknown direction specified. Choose either LEFT or RIGHT')
    end

end


% example_nufft1_antenna.m
%
% This m-file is an example of applying the NUFFT method to compute
% the far-field beam pattern of a 2D array of nonuniformly spaced
% (point?) antenna elements.
% In the nomenclature of the 1999 SIAM J Sci. Comput. paper by Nguyen and Liu,
% this is "Problem 1."
%
% This provides an example of how to compute "the Fourier transform"
% of nonuniformly spaced data.
%
% The user should think very carefully about whether it is truly meaningful
% to compute "the FT" of unequally spaced data first.  It certainly is
% meaningful for attenna beam patterns, but may not always be what is really
% useful for all applications with nonuniformly sampled data.
%
% Copyright 2007, Jeff Fessler, University of Michigan

%
% antenna element locations in 2d plane
%
clf, pl = @(p) subplot(220+p);
for choice=1:2
	tmp = [0:40]'/41 * 2 * pi;
	yc = sin(choice*tmp); % funny bowtie pattern for illustration
	xc = cos(tmp); clear tmp
	pl(choice), plot(xc, yc, 'o'), axis square
	xlabel 'x', ylabel 'x', title 'antenna locations'

	% create NUFFT structure
	N = [1 1]*2^8;
	J = [5 5];	% interpolation neighborhood
	K = N*2;	% two-times oversampling
	om = [xc yc];	% 'frequencies' are locations here!

	% the following line probably needs to be changed
	% to get the proper scaling/dimensions in the pattern
	% but for now i just make it fill up [-pi/20,pi/20]
	% in hopes of getting a nice 'picture' of pattern
	om = (pi/20) * om / max(om(:));
	st = nufft_init(om, N, J, K, N/2, 'minmax:kb');

	weights = ones(size(xc)); % equal weights on each element; could change

	% call the *adjoint* NUFFT; this is what does "the FT of unequal data"
	pattern = nufft_adj(weights, st);

	pl(2+choice)
	im(pattern, 'pattern')
end


%%
% \documentclass[12pt]{article}
%
% \title{ODEbox: A Toolbox for Ordinary Differential Equations\\
% Getting Started with the odeSolveIVP Tool}
%
% \author{Matthew Harker and Paul O'Leary\\
% Institute for Automation\\
% University of Leoben\\
% A-8700 Leoben,
% Austria\\
% URL: automation.unileoben.ac.at\\
% \\
% Original: January 9, 2013\\
% $\copyright$ 2013\\
% \\
% Last Modified: \today}
%%
% This is the documentation for the \lstinline{odeSolveIVP.m} file. This is
% a tool for the solution of initial value problems. It offers a very
% simple interface to solving such problems. Two different examples are
% documented here to show the different possible calls to the tool. The
% examples which have been selected are from Kreyszig~\cite{Kreyszig2010}
% and Adams~\cite{Adams}, since this
% give the analytical results enabling a comparison with the numerical
% solutions.
%
%%
% \section{Tidy up the Workspace}
clear all;
close all;
setUpGraphics;
%
%%
% \section{IVP Example 1}
%
% The equation being considered here is:
% %
% \begin{equation}
%   \dddot{y} + 3 \, \ddot{y} + 3 \, \dot{y} + y = 30 \, \mathrm{e}^{-x},
% \end{equation}
% %
% with the initial conditions
% %
% \begin{equation}
%   y(0) = 3,
%   \hspace{2mm}
%   \dot{y}(0) = -3,
%   \hspace{2mm}
%   \text{and}
%   \hspace{2mm}
%   \ddot{y}(0) = -47.
% \end{equation}
% %
% The analytical solution to this equation is,
% %
% \begin{equation}
%   (3 - 25 \, x^2 + 5 \, x^3)  \, \mathrm{e}^{-x}
% \end{equation}
%
% this example is from~\cite[Chapter 2]{Kreyszig2010}.
%%
% \subsection{Define the paramates for $x$.}
%
% Define the minimum, maximum x values and the number of points desired for
% the solution.
%
xMin = 0 ;
xMax = 10 ;
noPts = 73 ;
%%
% Setup the paramater vector
%
params = [xMin, xMax, noPts ];
%%
% \subsection{Call the \lstinline{odeSolveIVP}}
%
% A vector cof constant coefficients are used for this example equation.
%
[y, x, vals] = odeSolveIVP( [1;3;3;1] , '30*exp(-x)', [ 3 ; -3; -47 ] , params, 13);
%%
% Defining a MATLAB inline function for the analytical solution.
%
f = inline('(3 - 25 * x.^2).* exp(-x) + 5 * (x.^3).*exp(-x)') ;
%%
% \subsection{Plot the Results}
%
% The inline analytical solution is computed during plotting.
%
fig1 = figure;
plot( x, f(x), 'k');
hold on;
plot( x, y, 'ro');
grid on;
xlabel('$$x$$');
ylabel('$$y(x)$$');
legend('Analytic','Numerical','Location','SouthEast');
%
%\caption{Comparison of the analytical and the numerical solution for the first example.}
%%
% \section{IVP Example 2}
%
% The equation being considered here is:
% %
% \begin{equation}
%   x^2 \ddot{y} - 3 \, x\, \dot{y} + 13 y = 0,
% \end{equation}
% %
% with the initial conditions
% %
% \begin{equation}
%   y(0) = 5,
%   \hspace{2mm}
%   \text{and}
%   \hspace{2mm}
%   \dot{y}(0) = 0,
% \end{equation}
% %
% The analytical solution to this equation is,
% %
% \begin{equation}
%   5 \, x^2 \, \cos(3 \log(x)) - (10/3) \, x^2 \, \sin(3 \log(x))
% \end{equation}
%
% this example if from~\cite{Adams}.
%%
% \subsection{Define the paramates for $x$.}
%
% Define the minimum, maximum x values and the number of points desired for
% the solution.
%
noPts = 73 ;
xMin = 1 ;
xMax = 5 ;
%%
% Generate the vector of x values for which the equation should be solved.
% We are now artifically generating a nonuniformly spaced set of pointe to
% compute the solution. This is done to demonstrate the possibility of
% working with arbitrary nodes.
%
z = linspace( 0, 1, noPts )';
z = z.^2;
%
x = xMin + z * (xMax - xMin);
%
%%
% \subsection{Call the \lstinline{odeSolveIVP}}
%
% This is an equation with variable coefficients, i.e., the coefficients
% are functions of $x$. the functions are defines as strings which can be
% computed to inline functions. the notation [] is used to indicate that
% its is a homogeneous equation, i.e., the forcing function is identically
% zero. This call is with x as a vector of points where the solution should
% be computed.
%
[y, x, vals] = odeSolveIVP( {'x.^2';'-3*x';'13'} , [], [ 5 ; 0 ] , x, 13);
%%
% The inline for the analytical solution is, this is only needed for
% comparison purposes.
%
f = inline('5*x.^2.*cos(3*log(x)) - (10/3)*x.^2.*sin(3*log(x))') ;
%%
% \subsection{Plot the Results}
fig1 = figure;
plot( x, f(x), 'k');
hold on;
plot( x, y, 'ro');
grid on;
xlabel('$$x$$');
ylabel('$$y(x)$$');
legend('Analytic','Numerical','Location','NorthWest');
%
%\caption{Comparison of the analytical and the numerical solution for the
% second example. Note the non-uniform spacing of the nodes.}
%
%% Define the Bibliography
%
% \bibliographystyle{plain}
% \bibliography{odebib}


% INVWISHIRND - Inverse Wishart Random Matrix
% Copyright (c) 1998, Harvard University. Full copyright in the file Copyright
%
%   [IW] = invwishirnd(S,d)
%
% S = p x p symmetric, postitive definite "scale" matrix
% d = "degrees of freedom" parameter
%   = "precision" parameter
%   (d must be an integer for this routine, see INVWISHRND)
%
% IW = random matrix from the inverse Wishart distribution
%
% Note:
%   different sources use different parameterizations w.r.t. nu
%   this routine uses that of Press and Shigemasu (1989):
%   density(IW) is proportional to
%     exp[-.5*trace(S*inv(IW))] / [det(IW) ^ (d/2)].
%
%   With this density definition:
%   mean(IW) = S/(d-2p-2) when d>2p+2,
%   mode(IW) = S/d.
%
% See also: INVWISHRND, WISHRND

function [IW] = invwishirnd(S,d)
[p,p2] = size(S) ;
W = wishirnd(inv(S),d-p-1) ;
IW = inv(W) ;


function [ CONDXY ] = ConditionalHist( X,Y,varargin)
%[CONDXY] = ConditionalHist(X,Y) Calculates the conditional probabilty
%of Y given X
%
%INPUT
%   X
%   Y
% (options)
%   'numXbins'  (default: 50)
%   'numYbins'  (default: 50)
%   'Xbounds'
%   'Ybounds'
%   'Xbinoverlap' (default: 1)
%   'minX'      (default: 25)
%   'conditionby'   condition on X with different occupancy from datapoints
%
%
%OUTPUT
%   CONDXY
%       .pYX    a [numXbins x numYbins] matrix in which the [x,y]th element is P(y|x)
%       .XYhist joint histogram of X and Y
%       .XYprop joint probability of X and Y
%       .Xhist  histogram of X
%       .Xbins  X bins
%       .Ybins  Y bins
%
%DLevenstein 2019
%%
p = inputParser;
addParameter(p,'numXbins',50)
addParameter(p,'numYbins',50)
addParameter(p,'Xbounds',[])
addParameter(p,'Ybounds',[])
addParameter(p,'minX',25)
addParameter(p,'Xbinoverlap',1)
addParameter(p,'conditionby',[])
parse(p,varargin{:})
numXbins = p.Results.numXbins;
numYbins = p.Results.numYbins;
Xbounds = p.Results.Xbounds;
Ybounds = p.Results.Ybounds;
minX = p.Results.minX;
Xbinoverlap = p.Results.Xbinoverlap;
conditionby = p.Results.conditionby;

%% For cell input

if iscell(Y) && iscell(X)
    CONDXY = cellfun(@(x,y) ConditionalHist(x,y,varargin{:}),...
        X,Y,'UniformOutput',false);
    CONDXY = bz_CollapseStruct([CONDXY{:}],3);
    CONDXY.Xbins = CONDXY.Xbins(1,:,1);
    CONDXY.Ybins = CONDXY.Ybins(1,:,1);
    return
end

%% For multiple columns in X - conditonal probabilty of each

if size(Y,2)>1 && size(X,2)==1
    for yy = 1:size(Y,2)
        CONDXY(yy) = ConditionalHist(X,Y(:,yy),varargin{:});
    end
    CONDXY = bz_CollapseStruct(CONDXY,3);
    return
end

%%
if isempty(Xbounds)
    Xbounds(1) = min(X); Xbounds(2) = max(X);
end
if isempty(Ybounds)
    Ybounds(1) = min(Y(~isinf(Y))); Ybounds(2) = max(Y(~isinf(Y)));
end

Xedges = linspace(Xbounds(1),Xbounds(2),numXbins+1);
Xbins = Xedges(1:end-1)+ 0.5.*diff(Xedges([1 2]));
Xedges(1) = -inf;Xedges(end) = inf;

Yedges = linspace(Ybounds(1),Ybounds(2),numYbins+1);
Ybins = Yedges(1:end-1)+ 0.5.*diff(Yedges([1 2]));
Yedges(1) = -inf;Yedges(end) = inf;

%First calculate the marginal probability of X
[Xhist,~,XbinID] = histcounts(X,Xedges);

%Then calculate the joint probabilty of X and Y
if length(Ybins) ==1
    XYhist = Xhist;
elseif isempty(Y)
    warning('Y is empty... using nans')
    Y = nan(size(X));
    XYhist = nan(length(Xbins),length(Ybins));
else
    [XYhist] = hist3([X,Y],{Xbins,Ybins});
end

% Conditional probability of Y given X
if isempty(conditionby)
    Xhist4norm = Xhist;
else
    Xhist4norm = histcounts(conditionby,Xedges);
end
Xhist4norm(Xhist4norm<=minX) = nan; %Remove bins that don't have enough sampling
pYX = bsxfun(@(x,y) x./y,XYhist,Xhist4norm');

%Mean Y given X
for xx = 1:length(Xbins)
    meanYX(xx) = nanmean(Y(XbinID==xx));
    meanYX(isnan(Xhist4norm)) = nan;
end

CONDXY.pYX = pYX;
CONDXY.XYhist = XYhist;
CONDXY.XYprob = XYhist./nansum(XYhist(:));
CONDXY.meanYX = meanYX;
CONDXY.Xhist = Xhist;
CONDXY.pX = Xhist./nansum(Xhist);
CONDXY.Xbins = Xbins;
CONDXY.Ybins = Ybins;

%%
% figure
% imagesc(CONDXY.Xbins,CONDXY.Ybins,CONDXY.pYX')
% axis xy
end


function [output, fs] = eldar_reconstruction(inp_fs, input, time_skew)
    % Reconstruction of a signal from non-uniform samples

    N = length(time_skew); % number of samplers
    fs = inp_fs * N; % full sampling frequency
    T_Q = 1 / fs; % Nyquist sampling period
    T = N * T_Q; % single sampler period

    % index_mapping is used to reorded filters in case the first input
    % signal is actually delayed comparing to the second and not vice versa
    [time_skew, index_mapping] = sort(time_skew);

    H = construct_filters(N, T, time_skew);

    filtered = cell(N, 1);
    for i = 1:N
        % upsampling - according to the interpolation identity
        upsampled_input = upsample(input{index_mapping(i)}, N);
        filtered{i} = filter(H{i}, 1, upsampled_input);
    end

    min_len = min(cellfun('length', filtered));
    filtered_mat = zeros(min_len, N);
    for i=1:N
       filtered_mat(:, i) = filtered{i}(1:min_len);
    end
    output = real(sum(filtered_mat, 2)); % sum filterbank outputs
end

function filter_value = get_filter_value(N, T, a, time_skew, p, t)
    tp = time_skew(p + 1);
    sine_product_elements = ones(N, 1);
    for q = 0:N-1
       if q == p
           continue;
       end

       tq = time_skew(q + 1);
       sine_product_elements(q+1) = sin(pi*(t + tp - tq)/T);
    end
    sine_product = prod(sine_product_elements);
    filter_value = a(p + 1) * sinc((t)/T) * sine_product;
end

function H = construct_filters(N, T, tau)
    a = build_coefficients(N, T, tau);

    TAPS = 48;
    Tq = T/N;
    H = cell(N, 1);
    for p = 0:N-1
        H{p+1} = zeros(TAPS, 1);
        tp = tau(p+1);
        for n = 0:TAPS-1
            t = (n*Tq - tp);
            H{p+1}(n+1) = get_filter_value(N, T, a, tau, p, t);
        end

%         H{p+1}(tp/Tq+1) = 1;
        fvtool(H{p+1});
    end
end

function a = build_coefficients(N, T, tau)
    % compute a coefficients according to Sindhi-Prabhu
    a = ones(N, 1);
    for p = 1:N
        for q = 1:N
            if q ~= p
                a(p) = a(p) / sin(pi*(tau(p) - tau(q)) / T);
            end
        end
    end
end


function [P] = unmixP_NCM(X,E,Sigma,Parameters)
%% Input:
%        X - d-by-N HSI data, matrix
%        E - d-by-M endmember mean set, matrix
%        Sigma - d-by-d-by-M endmember covariance set, matrix
%  Output:
%        P - M-by-N proportion matrix
% Author: Alina Zare et al. Rewriten by Sheng Zou
% Department of Electrical and Computer Engineering, University of Florida
% 09/07/2017

%% Initialization of P
[d,N] = size(X);
M = size(E,2);
P = 1/M.*ones(M,N); % intialize proportion values to be 1/M

%Initialize all Likelihood and Prior Values
LogLikelihoodOld          = ComputeLogLikelihoodAll(X, E, P, Sigma, N);

for iteration = 2:Parameters.NumberIterations+1
    Y = randg(1, N, M) ;
    v = sum(Y,2);
    samples = (Y./repmat(v,[1,size(Y,2)]))';
    LogLikelihoodNew      = ComputeLogLikelihoodAll(X, E, samples, Sigma, N);
    Ratios                = exp(LogLikelihoodNew - LogLikelihoodOld);
    rands                 = rand(1,N);
    Vals                  = rands < Ratios;
    Vrep                  = repmat(Vals,M,1);
    P                     = samples.*Vrep  + P.*(1-Vrep);

    LogLikelihoodOld = (1-Vals).*LogLikelihoodOld + (Vals).*LogLikelihoodNew;
    if mod(iteration, round(Parameters.NumberIterations/10)) == 0
        disp(strcat('iteration = ',num2str(iteration)));
        disp(strcat('loglikelihood = ',num2str(sum(LogLikelihoodOld))));
    end
end

end

function [LogLikelihoodAll] = ComputeLogLikelihoodAll(X, E, P, cov, N)
% compute log likelihood of all points

term1 = zeros(1,N);
term2 = zeros(1,N);

for s = 1:size(E,2)
    statement(s)=isdiag(squeeze(cov(:,:,s))) && length(unique(diag(cov(:,:,s))))==1; % check if all the covariance matrices are diagonal and isotropic
end

if mean(statement) ==1 % all diagonal and isotropic
    for z = 1:size(P,1)
        a(z) = unique(diag(cov(:,:,z)));
    end
    term1 = -.5*size(X,1)*log(a*(P.^2));
    term2 = -.5*(sum((X-E*P).^2)./(a*(P.^2)));
else

    parfor t = 1:N
        P3D = zeros(1,1,size(E,2));
        P3D(:,:,1:size(E,2)) = P(:,t).^2;
        P3D_full = repmat(P3D,size(X,1),size(X,1));
        term1(t) = -.5*logdet(sum(P3D_full.*cov,3));
        term2(t) = -.5*(X(:,t)-E*P(:,t))'*(sum(P3D_full.*cov,3)\(X(:,t)-E*P(:,t)));
    end

end

LogLikelihoodAll = term1 + term2;
end


function [out] = interception_5(p1,p2,In)
%interception_5

% Copyright (C) 2019, 2021 Wouter J.M. Knoben, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.

% Flux function
% ------------------
% Description:  Interception excess after a combined absolute amount and fraction are intercepted
% Constraints:  f >= 0
% @(Inputs):    p1   - fraction that is not throughfall [-]
%               p2   - constnat interception and evaporation [mm/d]
%               In   - incoming flux [mm/d]

out = max(p1.*In-p2,0);

end


% STE_SWLP Stabilized weighted linear prediction using short-time-energy
% weighting
%   [A,w] = ste_swlp(s,p,m,k)
%
% Description
%   This function fits linear prediction coefficients to the analysis
%   frame using the basic form of stabilized weighted linear prediction
%   (SWLP) that weights each value of the squared prediction error by the
%   short-time energy (STE) of the previous samples.
%
% Inputs
%   s      : Speech signal frame [samples]
%   p      : Order of SWLP analysis
%   m      : Length of the STE window (default to p)
%   k      : Delay of the STE window (default to 1)
%
% Outputs
%   A      : Linear prediction inverse filter coefficients
%   w      : the STE weighting function
%
% Notes
%   SWLP generally gives smoother spectral shapes than the corresponding
%   weighted linear prediction (WLP) using the same weighting function.
%
% Example
%   A = ste_swlp(s,p) gives the linear predictive inverse filter
%   coefficients optimized using STE-SWLP
%
% References
%  [1] C. Magi, J. Pohjalainen, T. Bäckström and P. Alku, "Stabilised
%  weighted linear prediction", Speech Communication, vol. 51, no. 5, pp.
%  401411, 2009.
%  [2] J. Pohjalainen, H. Kallasjoki, K. J. Palomäki, M. Kurimo and P.
%  Alku, "Weighted linear prediction for speech analysis in noisy
%  conditions", in Proc. Interspeech, Brighton, UK, pp. 1315-1318,
%  2009.
%
% Copyright (c) 2013 Aalto University
%
% License
%  This file is under the LGPL license,  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. This file 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.
%
% This function is part of the Common Speech Processing Repository
% http://covarep.github.io/covarep/
%
% Octave Compatible
%
% Author
%  Jouni Pohjalainen jouni.pohjalainen@aalto.fi
%
% $Id <info set by the versioning system> $

function [A,w] = ste_swlp(s,p,m,k)

% handle the special case of all-zero frames
if all(s==0)
  s = eps*randn(size(s));
end

N = length(s);

% default value for the STE window length
if nargin<3
    m = p;
end

% default value for the STE window lag
if nargin<4
    k = 1;
end

% compute STE weighting function
w = stew(s,m,p,k)+eps;

w = w(1:(N+p));

% initialize partial weights for recursive computation (see [2], Eqs.
% (5)-(7), for the partial-weight formulation of SWLP)
Z = zeros(N+p,p+1);
Z(:,1) = sqrt(w);

% delayed and weighted versions of the signal
Y = zeros(N+p,p+1);
Y(:,1) = Z(:,1).*[s;zeros(p,1)];

% recursion for partial weights and weighting of differently lagged
% versions of the signal
for i1=1:p
    Z((i1+1):(N+p),i1+1) = max([ones(N+p-i1,1) sqrt(w((i1+1):(N+p))./w(i1:(N+p-1)))],[],2) .* Z(i1:(N+p-1),i1);
    Y(:,i1+1) = Z(:,i1+1) .* [zeros(i1,1);s;zeros(p-i1,1)];
end

% compute weighted autocorrelations
R = (Y'*Y)/N;

% solve the p predictor coefficients
A = R(2:end,2:end)\R(2:end,1);

% convert to inverse filter form
A = [1;-A]';

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function w = stew(x,m,p,k)
% STE weighting for an order p predictor using window of length m delayed
% by k samples
w = conv([zeros(k,1);x(:)].^2,ones(m,1));
w = [w;zeros(p-m,1)];


function yval = dif_val ( ntab, xtab, diftab, xval )

%*****************************************************************************80
%
%% DIF_VAL evaluates a divided difference polynomial at a point.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Carl de Boor,
%    A Practical Guide to Splines,
%    Springer Verlag, 1978.
%
%  Parameters:
%
%    Input, integer NTAB, the number of divided difference
%    coefficients in DIFTAB, and the number of points XTAB.
%
%    Input, real XTAB(NTAB), the X values upon which the
%    divided difference polynomial is based.
%
%    Input, real DIFTAB(NTAB), the divided difference
%    polynomial coefficients.
%
%    Input, real XVAL, the value where the polynomial
%    is to be evaluated.
%
%    Output, real YVAL, the value of the polynomial at XVAL.
%
  yval = diftab(ntab);
  for i = 1 : ntab-1
    yval = diftab(ntab-i) + ( xval - xtab(ntab-i) ) * yval;
  end

  return
end


function coef=framecoef2tf(F,coef)
%FRAMECOEF2TF  Convert coefficients to time-frequency plane
%   Usage: cout=framecoef2tf(F,cin);
%
%   `framecoef2tf(F,cin)` converts the frame coefficients *cin* into the
%   time-frequency plane layout. The frame object *F* must have been
%   created using |frame|.
%
%   The time-frequency plane layout is a matrix, where the first
%   dimension indexes frequency and the second dimension time. This is
%   similar to the output format from |dgt| and |wmdct|.
%
%   Not all types of frames support this coefficient conversion. The supported
%   types of frames are: `'dgt'`, `'dgtreal'`, `'dwilt'`, `'wmdct'`, `'ufilterbank'`,
%   `'ufwt'`,`'uwfbt'` and `'uwpfbt'`.
%
%   See also: frame, frametf2coef, framecoef2native

complainif_notenoughargs(nargin,2,'FRAMECOEF2TF');
complainif_notvalidframeobj(F,'FRAMECOEF2TF');

switch(F.type)
 case 'dgt'
  [MN,W]=size(coef);
  N=MN/F.M;
  coef=reshape(coef,[F.M,N,W]);
 case 'dgtreal'
  [MN,W]=size(coef);
  M2=floor(F.M/2)+1;
  N=MN/M2;
  coef=reshape(coef,[M2,N,W]);
 case 'dwilt'
  [MN,W]=size(coef);
  N=MN/F.M;
  coef=wil2rect(reshape(coef,[2*F.M,N/2,W]));
 case 'wmdct'
  [MN,W]=size(coef);
  N=MN/F.M;
  coef=reshape(coef,[F.M,N,W]);
 case 'ufilterbank'
  [MN,W]=size(coef);
  M=numel(F.g);
  N=MN/M;
  coef=permute(reshape(coef,[N,M,W]),[2,1,3]);
 case {'ufwt','uwfbt','uwpfbt'}
  coef = permute(F.coef2native(coef,size(coef)),[2,1,3]);
 otherwise
  error('%s: TF-plane layout not supported for this transform.',upper(mfilename));
end;


%
% Implementation of Exposure Fusion
%
% written by Tom Mertens, Hasselt University, August 2007
% e-mail: tom.mertens@gmail.com
%
% This work is described in
%   "Exposure Fusion"
%   Tom Mertens, Jan Kautz and Frank Van Reeth
%   In Proceedings of Pacific Graphics 2007
%
%
% Usage:
%   result = exposure_fusion(I,m);
%   Arguments:
%     'I': represents a stack of N color images (at double
%       precision). Dimensions are (height x width x 3 x N).
%     'm': 3-tuple that controls the per-pixel measures. The elements
%     control contrast, saturation and well-exposedness, respectively.
%
% Example:
%   'figure; imshow(exposure_fusion(I, [0 0 1]);'
%   This displays the fusion of the images in 'I' using only the well-exposedness
%   measure
%

function [R, W]= exposure_fusion(I,m)

r = size(I,1);
c = size(I,2);
N = size(I,4);

W = ones(r,c,N);

%compute the measures and combines them into a weight map
contrast_parm = m(1);
sat_parm = m(2);
wexp_parm = m(3);

if (contrast_parm > 0)
    W = W.*contrast(I).^contrast_parm;
end
if (sat_parm > 0)
    W = W.*saturation(I).^sat_parm;
end
if (wexp_parm > 0)
    W = W.*well_exposedness(I).^wexp_parm;
end

%normalize weights: make sure that weights sum to one for each pixel
W = W + 1e-12; %avoids division by zero
W = W./repmat(sum(W,3),[1 1 N]);

% create empty pyramid
pyr = gaussian_pyramid_(zeros(r,c,3));
nlev = length(pyr);

% multiresolution blending
for i = 1:N
    % construct pyramid from each input image
	pyrW = gaussian_pyramid_(W(:,:,i));
	pyrI = laplacian_pyramid_(I(:,:,:,i));

    % blend
    for l = 1:nlev
        w = repmat(pyrW{l},[1 1 3]);
        pyr{l} = pyr{l} + w.*pyrI{l};
    end
end

% reconstruct
R = reconstruct_laplacian_pyramid_(pyr);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% contrast measure
function C = contrast(I)
h = [0 1 0; 1 -4 1; 0 1 0]; % laplacian filter
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
    mono = rgb2gray(I(:,:,:,i));
    C(:,:,i) = abs(imfilter(mono,h,'replicate'));
end

% saturation measure
function C = saturation(I)
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
    % saturation is computed as the standard deviation of the color channels
    R = I(:,:,1,i);
    G = I(:,:,2,i);
    B = I(:,:,3,i);
    mu = (R + G + B)/3;
    C(:,:,i) = sqrt(((R - mu).^2 + (G - mu).^2 + (B - mu).^2)/3);
end

% well-exposedness measure
function C = well_exposedness(I)
sig = .2;
N = size(I,4);
C = zeros(size(I,1),size(I,2),N);
for i = 1:N
    R = exp(-.5*(I(:,:,1,i) - .5).^2/sig.^2);
    G = exp(-.5*(I(:,:,2,i) - .5).^2/sig.^2);
    B = exp(-.5*(I(:,:,3,i) - .5).^2/sig.^2);
    C(:,:,i) = R.*G.*B;
end


function [eigVec, eigVal] = dtiSplitTensor(tensor)
% Derive eigenvector and eigenvalues from the volume of tensor data
%
% [eigVec, eigVal] = dtiSplitTensor(tensor)
%
% The input tensor array is in XxYxZx6xN format
% The order of the value in the 4th dimension is [Dxx, Dyy, Dzz, Dxy, Dxz, Dyz])
%
% The routine returns a XxYxZx3x3xN volume of eigVec
% and                 a the XxYxZx3xN volume of eigVal arrays
%
% X,Y,Z are positions in the volume
% N is the number of subjects.
%
% SEE ALSO: dtiRebuildTensor
%
% HISTORY:
% 2003.12.08 ASH (armins@stanford.edu) Wrote it.
% 2004.02.03 DTM (merget@cs.stanford.edu) Sort eigVal from high to low
% 2004.02.17 ASH: added extra dimension for subjects
% 2005.01.06 ASH: truly added extra dimension for subjects
%
% The code is implemented in the mex file dtiSplitTensor.c. If you don't
% have a that file compiled for you system, then the (very slow) code below
% will be executed.  In one test, the following code ran in 2.85 minutes,
% and the compiled version ran in about 11 seconds.
%
% (c) Stanford VISTA Team 2003

disp('This function is mexified for speed- compile dtiSplitTensor.c.');

sz = size(tensor);
if (length(sz)<5),
    sz =[sz, 1];
end

% vec = zeros([sz(1:3), 3, 3, sz(5)]);
% val = zeros([sz(1:3), 3, sz(5)]);

h = mrvWaitbar(0, 'Computing tensors...');
for(x=1:sz(1))
    for(y=1:sz(2))
        for(z=1:sz(3))
            for(j=1:sz(5))
                D = [tensor(x, y, z, 1, j), tensor(x, y, z, 4, j), tensor(x, y, z, 5, j);
                     tensor(x, y, z, 4, j), tensor(x, y, z, 2, j), tensor(x, y, z, 6, j);
                     tensor(x, y, z, 5, j), tensor(x, y, z, 6, j), tensor(x, y, z, 3, j)];
                [vec, val] = eig(D);
                [val2, order] = sort(-diag(val));
                eigVec(x, y, z, :, :, j) = vec(:, order);
                eigVal(x, y, z, :, j) = -val2;
            end
        end
    end
    mrvWaitbar(x/sz(1),h);
end
close(h);

return;


function T = build_toep( c, k, n )
%
%  T = build_toep( c, k, n );
%
%  Given:
%    c - the nonzero part of a central column of a banded Toeplitz
%        matrix
%    k - index of c containing the diagonal element of T
%    n - dimension of the banded Toeplitz matrix
%
%  The banded Toeplitz matrix is constructed explicitly.
%

%  J. Nagy  2/11/02

m = length( c );

col = zeros(n,1);
row = col';
col(1:m-k+1,1) = c(k:m);
row(1,1:k) = c(k:-1:1)';
T = toeplitz( col, row );


function af = naca5gen(iaf)
%
% "naca5gen" Generates the NACA 5 digit airfoil coordinates with desired no.
% of panels (line elements) on it.
%      Author : Divahar Jayaraman (j.divahar@yahoo.com)
%
% INPUTS-------------------------------------------------------------------
%       iaf.designation = NACA 5 digit designation (eg. '23012') - STRING !
%                 iaf.n = no of panels (line elements) PER SIDE (upper/lower)
% iaf.HalfCosineSpacing = 1 for "half cosine x-spacing"
%                       = 0 to give "uniform x-spacing"
%          iaf.wantFile = 1 for creating airfoil data file (eg. 'naca2412.dat')
%                       = 0 to suppress writing into a file
%       iaf.datFilePath = Path where the data  file has to be created
%                         (eg. 'af_data_folder/naca5digitAF/')
%                         use only forward slash '/' (Just for OS portability)
%
% OUTPUTS------------------------------------------------------------------
% Data:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%       af.x = x cordinate (nx1 array)
%       af.z = z cordinate (nx1 array)
%      af.xU = x cordinate of upper surface (nx1 array)
%      af.zU = z cordinate of upper surface (nx1 array)
%      af.xL = x cordinate of lower surface (nx1 array)
%      af.zL = z cordinate of lower surface (nx1 array)
%      af.xC = x cordinate of camber line (nx1 array)
%      af.zC = z cordinate of camber line (nx1 array)
%    af.name = Name of the airfoil
%  af.header = Airfoil name ; No of panels ; Type of spacing
%              (eg. 'NACA23012 : [50 panels,Uniform x-spacing]')
%
%
% File:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
% First line : Header eg. 'NACA23012 : [50 panels,Half cosine x-spacing]'
% Subsequent lines : (2*iaf.n+1) rows of x and z values
%
% Typical Inputs:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
% iaf.designation='23012';
% iaf.n=56;
% iaf.HalfCosineSpacing=1;
% iaf.wantFile=1;
% iaf.datFilePath='./'; % Current folder
% iaf.is_finiteTE=0;

% % [[Calculating key parameters-----------------------------------------]]
cld=str2num(iaf.designation(1))*(3/2)/10;
p=0.5*str2num(iaf.designation(2:3))/100;
t=str2num(iaf.designation(4:5))/100;

a0= 0.2969;
a1=-0.1260;
a2=-0.3516;
a3= 0.2843;

if iaf.is_finiteTE ==1
    a4=-0.1015; % For finite thick TE
else
    a4=-0.1036;  % For zero thick TE
end

% % [[Giving x-spacing---------------------------------------------------]]
if iaf.HalfCosineSpacing==1
    beta=linspace(0,pi,iaf.n+1)';
    x=(0.5*(1-cos(beta))); % Half cosine based spacing
    iaf.header=['NACA' iaf.designation ' : [' num2str(2*iaf.n) 'panels,Half cosine x-spacing]'];
else
    x=linspace(0,1,iaf.n+1)';
    iaf.header=['NACA' iaf.designation ' : [' num2str(2*iaf.n) 'panels,Uniform x-spacing]'];
end

yt=(t/0.2)*(a0*sqrt(x)+a1*x+a2*x.^2+a3*x.^3+a4*x.^4);

P=[  0.05     0.1     0.15    0.2     0.25  ];
M=[  0.0580   0.1260  0.2025  0.2900  0.3910];
K=[361.4     51.64   15.957   6.643   3.230 ];

m=spline(P,M,p);
k1=spline(M,K,m);

xc1=x(find(x<=p));
xc2=x(find(x>p));
xc=[xc1 ; xc2];

if p==0
    xu=x;
    yu=yt;

    xl=x;
    yl=-yt;

    zc=zeros(size(xc));
else
    yc1=(1/6)*k1*( xc1.^3-3*m*xc1.^2+m^2*(3-m)*xc1 );
    yc2=(1/6)*k1*m^3*(1-xc2);
    zc=(cld/0.3)*[yc1 ; yc2];

    dyc1_dx=(1/6)*k1*( 3*xc1.^2-6*m*xc1+m^2*(3-m) );
    dyc2_dx=repmat((1/6)*k1*m^3,size(xc2));
    dyc_dx=[dyc1_dx ; dyc2_dx];
    theta=atan(dyc_dx);

    xu=x-yt.*sin(theta);
    yu=zc+yt.*cos(theta);

    xl=x+yt.*sin(theta);
    yl=zc-yt.*cos(theta);
end
af.name=['NACA ' iaf.designation];

af.x=[flipud(xu) ; xl(2:end)];
af.z=[flipud(yu) ; yl(2:end)];

indx1=1:min( find(af.x==min(af.x)) );  % Upper surface indices
indx2=min( find(af.x==min(af.x)) ):length(af.x); % Lower surface indices
af.xU=af.x(indx1); % Upper Surface x
af.zU=af.z(indx1); % Upper Surface z
af.xL=af.x(indx2); % Lower Surface x
af.zL=af.z(indx2); % Lower Surface z

af.xC=xc;
af.zC=zc;

lecirFactor=0.8;
af.rLE=0.5*(a0*t/0.2)^2;

le_offs=0.5/100;
dyc_dx_le=(1/6)*k1*( 3*le_offs.^2-6*m*le_offs+m^2*(3-m) );
theta_le=atan(dyc_dx_le);
af.xLEcenter=af.rLE*cos(theta_le);
af.yLEcenter=af.rLE*sin(theta_le);

% % [[Writing iaf data into file------------------------------------------]]
if iaf.wantFile==1
    F1=iaf.header;
    F2=num2str([af.x af.z]);
    F=strvcat(F1,F2);
    fileName=[iaf.datFilePath 'naca' iaf.designation '.dat'];
    dlmwrite(fileName,F,'delimiter','')
end


function [g,B,mu]=BaylissTapering(sidelobedB,N,xyPoints,a)
%%BAYLISSTAPERING The Bayliss tapering is a set of complex amplitude
%          weights for a continuous circular (narrowband) aperture antenna
%          that will form a difference beam (odd symmetry about an axis)
%          and hold the four closest sidelobes to a desired level. Such a
%          tapering can be discretized and applied to the elements in a
%          circular phased array (An array of antenna elements can be
%          viewed as a discrete approximation to a continuous aperture).
%          This function will provide the tapering values at a set of
%          discrete points given by xyPoints (the origin is taken to be the
%          center of the aperture). The radius of the aperture can either
%          be provided or is taken as value of the farthest point provided.
%          This function also returns coefficients for one to efficiently
%          compute the tapering at points on their own. If xyPoints is
%          empty, only the coefficients are returned. The difference axis
%          generated by this function is the y-axis.
%
%INPUTS: sidelobedB The number of decibels of the ratio of the close-in
%             sidelobe voltages to the main lobe voltage. This must be a
%             negative number. A typical value is -30.
%           N The Bayliss tapering is computed using a certain number of
%             terms. Using too many terms can be undesirable as edge
%             illumination increases, as noted in [1]. If this parameter is
%             omitted or an empty matrix is passed, then the default of 17
%             is used. In [1], it is suggested that N be chosen to be
%             <2*a/lambda, where a is the radius of the aperture and
%             lambda the wavelength.
%    xyPoints A 2XnumPoints set of numPoints points in the aperture plane
%             at which the tapering values should be evaluated. If this
%             parameter is omitted or an empty matrix is passed, then an
%             empty matrix is returned for the output g. The center of the
%             aperture is taken to be the origin.
%           a The radius of the aperture. Tapering weights for points in
%             xyPoints outside of the aperture are taken to be zero. If
%             this parameter is omitted or an empty matrix is passed, then
%             the radius is taken to be the distance of the farthest point
%             from the origin in xyPoints.
%
%OUTPUTS: g The NX1 set of discretized Bayliss tapering values evaluated at
%           the points given in xyPoints. If xyPoints is omitted, then this
%           is an empty matrix. All Bayliss tapering values are imaginary.
%           The values are not normalized.
%     B, mu These two outputs can be used to evaluate the bayliss tapering
%           values at arbitrary points. B is an NX1 vector and mu is an
%           (N+1)X1 vector. Given a 2X1 point xy and a radius of the
%           aperture, set the normalized radius to p=pi*norm(xy)/a and
%           the Bayliss tapering weight g at the point is
%           g=(xy(1)/norm(xy))*sum(B.*besselj(1,mu(1:N)*p));
%
%This function implements the algorithm of [1] using the polynomial
%interpolation values in the table below Figure 4. This approximation means
%that low sidelobe patterns (-45 dB and below) will not have good fidelity
%sidelobes.
%
%EXAMPLE 1:
%Here, we evaluate the tapering values for 30dB down on a fine grid of
%points to plot what the imaginary part of the tapering weights looks
%like. The real part is all zero.
% numPoints=300;
% points1D=linspace(-1,1,numPoints);
% [X,Y]=meshgrid(points1D,points1D);
% %The Bayliss tapering weights, evaluated across the aperture. Points
% %outside the aperture are assigned a weight of 0. All Bayliss weights are
% %imaginary.
% xyPoints=[X(:)';Y(:)'];
% a=1;%Aperture radius=1.
% gBayliss=BaylissTapering(-30,17,xyPoints,a);
% gBayliss=reshape(gBayliss,numPoints,numPoints);
%
% figure(1)
% clf
% surface(X,Y,imag(gBayliss),'EdgeColor','None')
% colormap(jet(256))
% colorbar()
% view(45,45)
% light()
% axis square
% h1=xlabel('x');
% h2=ylabel('y');
% title('Bayliss Tapering Weight')
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
%
%EXAMPLE 2:
%Here, we consider the array response when using tapering values for 30dB
%sidelobes on a circular array with lambda/2 spacing between elements.
%First, we create a circular array. The element locations are given in
%terms of the wavelength lambda, so lambda will not appear in the
%equations for the sum beam.
% %First, we create a circular array. The element locations are given in
% %terms of the wavelength lambda, so lambda will not appear in the
% %equations for the sum beam.
% xyVals=getShaped2DLattice([25;25],'circular');
% %Get the tapering. It is -30dB and  nBar=17;
% N=17;
% sidelobedB=-30;
% g=BaylissTapering(sidelobedB,N,xyVals);
%
% %The tapering matrix
% T=diag(g);
%
% %Now, display the response with the tapering. We normalize it with
% %respect to the peak value and plot the result in decibels (power).
% [Rsp,U,V]=standardUVBeamPattern(T,xyVals,'NormPowGain');
%
% figure(1)
% clf
% surface(U,V,10*log10(Rsp),'EdgeColor','None')
% colormap(jet(256));
% caxis([-40,0])
% colorbar()
% view(45,30)
% light()
% axis square
% h1=xlabel('u');
% h2=ylabel('v');
% h3=zlabel('Response, Decibels');
% title('Bayliss Weighted Array Response')
% set(gca,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h1,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h2,'FontSize',14,'FontWeight','bold','FontName','Times')
% set(h3,'FontSize',14,'FontWeight','bold','FontName','Times')
%
%Note that the difference pattern produced has a line of symmetry about
%the y axis. To flip the symmetry axis (e.g. for a vertical difference
%beam), then simply use g=BaylissTapering(sidelobedB,N,flipud(xyVals));
%
%REFERENCES:
%[1] E. T. Bayliss, "Design of monopulse antenna difference patterns with
%    low sidelobes," The Bell System Technical Journal, vol. 47, no. 5, pp.
%    623-650, May-Jun. 1968.
%
%August 2016 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<2||isempty(N))
   N=17;
end

%The definition og the mu_m terms in Equation 6 in [1]. The first zero is
%the one indexed by 0 in the paper. Thus, this goes from mu_0 to mu_N.
mu=BesselJDerivZeros(1,N+1)/pi;

%This holds the coefficients for the interpolating polynomials given below
%Figure 4 in [1]. The polynomials all take the desired sidelobe level in
%decibels as an input parameter. The first row is for the term A, which
%is a translation of the SNR parameter to a parameter in the paper. The
%next four rows are xi_1 to xi_4, which are the locations of the first four
%zeroes in the modified pattern. The final row is for p_0, which is related
%to the point at which the peak of the asymptotic difference pattern=1.
polyCoeffTable=[0.30387530,-0.05042922,-0.00027989,-0.00000343,-0.00000002;
                0.98583020,-0.03338850, 0.00014064, 0.00000190, 0.00000001;
                2.00337487,-0.01141548, 0.00041590, 0.00000373, 0.00000001;
                3.00636321,-0.00683394, 0.00029281, 0.00000161, 0;
                4.00518423,-0.00501795, 0.00021735, 0.00000088, 0;
                0.47972120,-0.01456692,-0.00018739,-0.00000218,-0.00000001];

A  =polyCoeffTable(1,1)+sidelobedB*(polyCoeffTable(1,2)+sidelobedB*(polyCoeffTable(1,3)+sidelobedB*(polyCoeffTable(1,4)+sidelobedB*polyCoeffTable(1,5))));
xi1=polyCoeffTable(2,1)+sidelobedB*(polyCoeffTable(2,2)+sidelobedB*(polyCoeffTable(2,3)+sidelobedB*(polyCoeffTable(2,4)+sidelobedB*polyCoeffTable(2,5))));
xi2=polyCoeffTable(3,1)+sidelobedB*(polyCoeffTable(3,2)+sidelobedB*(polyCoeffTable(3,3)+sidelobedB*(polyCoeffTable(3,4)+sidelobedB*polyCoeffTable(3,5))));
xi3=polyCoeffTable(4,1)+sidelobedB*(polyCoeffTable(4,2)+sidelobedB*(polyCoeffTable(4,3)+sidelobedB*(polyCoeffTable(4,4)+sidelobedB*polyCoeffTable(4,5))));
xi4=polyCoeffTable(5,1)+sidelobedB*(polyCoeffTable(5,2)+sidelobedB*(polyCoeffTable(5,3)+sidelobedB*(polyCoeffTable(5,4)+sidelobedB*polyCoeffTable(5,5))));
%p0 =polyCoeffTable(6,1)+sidelobedB*(polyCoeffTable(6,2)+sidelobedB*(polyCoeffTable(6,3)+sidelobedB*(polyCoeffTable(6,4)+sidelobedB*polyCoeffTable(6,5))));

Z=zeros(N+1,1);
%Equation 15
Z(1)=0;%The Z(0) term
%Now, the moved zeros
Z(2)=xi1;
Z(3)=xi2;
Z(4)=xi3;
Z(5)=xi4;
for k=5:N
    %The location of the non-moved zeros as given by Equation 13.
    Z(k+1)=sqrt(A^2+k^2);
end
%Equation 16 in [1].
sigma=mu(N+1)/Z(N+1);

%No normalization is performed. We just use C=1.
C=1;

B=zeros(N,1);%The first entry is B_0
%Equation 24
for m=0:(N-1)
    num=prod(1-(mu(m+1)./(sigma*Z(2:N))).^2);
    denom=prod(1-(mu(m+1)./mu([1:m,(m+2):N])).^2);

    B(m+1)=-(C*1j*2*mu(m+1)^2/besselj(1,pi*mu(m+1)))*num/denom;
end

%If discretized tapering values are desired.
if(nargin>2&&~isempty(xyPoints))
    numPoints=size(xyPoints,2);

    if(nargin<4||isempty(a))
        %The maximum distance from the origin to a point is taken to be the
        %radius of the aperture.
        a2=max(sum(xyPoints.^2,1));
        a=sqrt(a2);
    end

    g=zeros(numPoints,1);
    for curPoint=1:numPoints
        rho2=sum(xyPoints(:,curPoint).^2,1);

        if(rho2<=a2)
            rho=sqrt(rho2);
            %The normalized radius at this point.
            p=pi*rho/a;

            x=xyPoints(1,curPoint);
            cosVal=x/rho;

            %Equation 7 in [1].
            g(curPoint)=cosVal*sum(B.*besselj(1,mu(1:N)*p));
        end
    end
else%If no tapering values are requested, return an empty matrix.
    g=[];
end
end

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