function [T2Hot1] = T2Hot1(X,alpha)
%Hotelling's T-Squared test for one multivariate sample.
%
%   Syntax: function [T2Hot1] = T2Hot1(X,alpha)
%
%     Inputs:
%          X - multivariate data matrix.
%      alpha - significance level (default = 0.05).
%
%     Output:
%          n - sample-size.
%          p - variables.
%          T2 - Hotelling's T-Squared statistic.
%          Chi-sqr. or F - the approximation statistic test.
%          df's - degrees' of freedom of the approximation statistic test.
%          P - probability that null Ho: is true.
%
%
%    Example: For the example given by Johnson and Wichern (1992, p. 183),
%             with 20 cases (n = 20) and three variables (p = 3). We are interested
%             to test if there is any difference against the expected mean vector
%             [4 50 10] at a significance level = 0.10.
%                      --------------    --------------
%                       x1   x2   x3      x1   x2   x3
%                      --------------    --------------
%                      3.7  48.5  9.3    3.9  36.9 12.7
%                      5.7  65.1  8.0    4.5  58.8 12.3
%                      3.8  47.2 10.9    3.5  27.8  9.8
%                      3.2  53.2 12.0    4.5  40.2  8.4
%                      3.1  55.5  9.7    1.5  13.5 10.1
%                      4.6  36.1  7.9    8.5  56.4  7.1
%                      2.4  24.8 14.0    4.5  71.6  8.2
%                      7.2  33.1  7.6    6.5  52.8 10.9
%                      6.7  47.4  8.5    4.1  44.1 11.2
%                      5.4  54.1 11.3    5.5  40.9  9.4
%                      --------------    --------------
%
%             Total data matrix must be:
%              X=[3.7 48.5 9.3;5.7 65.1 8.0;3.8 47.2 10.9;3.2 53.2 12.0;3.1 55.5 9.7;
%              4.6 36.1 7.9;2.4 24.8 14.0;7.2 33.1 7.6;6.7 47.4 8.5;5.4 54.1 11.3;
%              3.9 36.9 12.7;4.5 58.8 12.3;3.5 27.8 9.8;4.5 40.2 8.4;1.5 13.5 10.1;
%              8.5 56.4 7.1;4.5 71.6 8.2;6.5 52.8 10.9;4.1 44.1 11.2;5.5 40.9 9.4];
%
%     Calling on Matlab the function:
%             T2Hot1(X)
%       Immediately it ask:
%             -Do you have an expected mean vector? (y/n):
%            For this example we must to put:
%             y  (meaning 'yes')
%            Then it ask:
%             -Give me the expected mean vector:
%            Giving the mean vector:
%             [4 50 10]
%            Otherwise (n; meaning 'no') it consider a zero mean vector.
%
%       Answer is:
% ------------------------------------------------------------------------------------
% Sample-size    Variables      T2          F           df1          df2          P
% ------------------------------------------------------------------------------------
%      20            3         9.7388     2.9045          3           17        0.0649
% ------------------------------------------------------------------------------------
% Mean vectors results significant.
%
%
%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%             And the special collaboration of the post-graduate students of the 2002:2
%             Multivariate Statistics Course: Karel Castro-Morales, Alejandro Espinoza-Tenorio,
%             Andrea Guia-Ramirez.
%
%  Copyright (C) December 2002
%
%  References:
%
%  Johnson, R. A. and Wichern, D. W. (1992), Applied Multivariate Statistical Analysis.
%              3rd. ed. New-Jersey:Prentice Hall. pp. 180-181,199-200.
%

if nargin < 1,
    error('Requires at least one input argument.');
end;

if nargin < 2,
    alpha = 0.05;
end;

if (alpha <= 0 | alpha >= 1)
   fprintf('Warning: significance level must be between 0 and 1\n');
   return;
end;

[n,p]=size(X);

ask=input('Do you have an expected mean vector? (y/n): ','s');
if ask=='y'
   mu=input('Give me the expected mean vector: ');
else
   mu=zeros([1,p]);
end;

if n <= p,
   error('Warning: requires that sample-size (n) must be greater than the number of variables (p).');
   return;
else

   m=mean(X); %Mean vector from data matrix X.
   S=cov(X);  %Covariance matrix from data matrix X.
   T2=n*(m-mu)*inv(S)*(m-mu)'; %Hotelling's T-Squared statistic.

   if n >= 50 %Chi-square approximation.
      X2=T2;
      v=p; %Degrees of freedom.
      P=1-chi2cdf(X2,v); %Probability that null Ho: is true.
      disp(' ')
      fprintf('----------------------------------------------------------------------------\n');
      disp(' Sample-size    Variables      T2          Chi-sqr.         df          P')
      fprintf('----------------------------------------------------------------------------\n');
      fprintf('%8.i%13.i%15.4f%14.4f%11.i%14.4f\n\n',n,p,T2,X2,v,P);
      fprintf('----------------------------------------------------------------------------\n');
      if P >= alpha;
         disp('Mean vectors results not significant.');
      else
         disp('Mean vectors results significant.');
      end;
   else  %F approximation.
      F=(n-p)/((n-1)*p)*T2;
      v1=p;  %Numerator degrees of freedom.
      v2=n-p;  %Denominator degrees of freedom.
      P=1-fcdf(F,v1,v2);  %Probability that null Ho: is true.
      disp(' ')
      fprintf('-------------------------------------------------------------------------------------\n');
      disp(' Sample-size    Variables      T2          F           df1          df2          P')
      fprintf('-------------------------------------------------------------------------------------\n');
      fprintf('%8.i%13.i%15.4f%11.4f%9.i%14.i%14.4f\n\n',n,p,T2,F,v1,v2,P);
      fprintf('-------------------------------------------------------------------------------------\n');
      if P >= alpha;
         disp('Mean vectors results not significant.');
      else
         disp('Mean vectors results significant.');
      end;
   end;
end;

return;


%% (Internal) Calculate the median of absolute deviations from the median (MEDA)
%
%   meda = nanmeda(data)
%
% Arguments:
%
%      + data: data
%
% Output:
%
%      + meda:  median of absolute deviations from the median.
%
% Example:
%
% Author: Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar
% Version: 0.1 beta
% Last update: 14/5/2014
% Birthdate  : 21/4/2015
% Copyright 2008-2015
%
function meda = nanmeda(data)

median_data = nanmedian(data);
meda = nanmedian(abs(bsxfun(@minus, data, median_data)));


function [ as, bs, cs ] = sphere_triangle_vertices_to_sides ( r, v1, v2, v3 )

%*****************************************************************************80
%
%% SPHERE_TRIANGLE_VERTICES_TO_SIDES computes spherical triangle sides.
%
%  Discussion:
%
%    We can use the ACOS system call here, but the ARC_COSINE routine
%    will automatically take care of cases where the input argument is
%    (usually slightly) out of bounds.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 April 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real V1(3), V2(3), V3(3), the vertices of the spherical
%    triangle.
%
%    Output, real AS, BS, CS, the (geodesic) length of the sides
%    of the triangle.
%
  dim_num = 3;

  as = r * r8_acos ( v2(1:dim_num)' * v3(1:dim_num) / r.^2 );
  bs = r * r8_acos ( v3(1:dim_num)' * v1(1:dim_num) / r.^2 );
  cs = r * r8_acos ( v1(1:dim_num)' * v2(1:dim_num) / r.^2 );

  return
end


function f = vlmop2(x)

dim = 2;

transl = 1./sqrt(dim);
part1 = (x(:,1) - transl).^2 + (x(:,2) - transl).^2;
part2 = (x(:,1) + transl).^2 + (x(:,2) + transl).^2;

f(:,1) = 1 - exp( -part1 );
f(:,2) = 1 - exp( -part2 );


function [ mO ] = ImageFilteringFrequencyDomain( mI, mH, paddingMode )
% ----------------------------------------------------------------------------------------------- %
% [ mO ] = ImageFilteringFrequencyDomain( mI, mH, paddingMode )
% Applies Image Filtering in the Frequency Domain.
% Input:
%   - mI                -   Input Image.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - mH                -   Filtering Kernel.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - paddingMode       -   Padding Mode.
%                           Sets whether the padding is by Zeros,
%                           Symmetric, Replicate or Circular mode.
%                           Structure: Scalar.
%                           Type: 'Single' / 'Double'.
%                           Range: {1, 2, 3, 4}.
% Output:
%   - mI                -   Output Image.
%                           Structure: Matrix.
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
% References:
%   1.  MATLAB's 'imfilter()' - https://www.mathworks.com/help/images/ref/imfilter.html.
% Remarks:
%   1.  A
% TODO:
%   1.
%   Release Notes:
%   -   1.0.000     04/04/2019  Royi Avital
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

PADDING_MODE_ZEROS      = 1;
PADDING_MODE_SYMMETRIC  = 2;
PADDING_MODE_REPLICATE  = 3;
PADDING_MODE_CIRCULAR   = 4;

numRows     = size(mI, 1);
numCols     = size(mI, 2);

numRowsKernel = size(mH, 1);
numColsKernel = size(mH, 2);

radiusRows = floor(numRowsKernel / 2);
radiusCols = floor(numColsKernel / 2);

vPadRadius = [radiusRows; radiusCols];

switch(paddingMode)
    case(PADDING_MODE_ZEROS)
        % Size of the Linear Convolution Support
        numRowsL = numRows + numRowsKernel - 1;
        numColsL = numCols + numColsKernel - 1;

        % Equivalent of Full Linear Convolution (Zero Padding Built In).
        % This is due the fact padding with zeors at the end with symmetric
        % assumption and shifting yield correct result.
        mO = ifft2(fft2(mI, numRowsL, numColsL) .* fft2(mH, numRowsL, numColsL), 'symmetric');

        firstRowIDx = ceil((numRowsKernel + 1) / 2);
        firstColIDx = ceil((numColsKernel + 1) / 2);

        mO = mO(firstRowIDx:(firstRowIDx + numRows - 1), firstColIDx:(firstColIDx + numCols - 1));
    case({PADDING_MODE_SYMMETRIC, PADDING_MODE_REPLICATE})
        % Padding to apply "Linear Convolution" on the image pixels.
        mI = PadArray2D(mI, vPadRadius, paddingMode);

        numRowsPad = numRows + (2 * radiusRows);
        numColsPad = numCols + (2 * radiusCols);

        mHC = mH;
        mHC(numRowsPad, numColsPad) = 0;
        mHC = circshift(mHC, [-radiusRows, -radiusCols]);

        mO = ifft2(fft2(mI) .* fft2(mHC), 'symmetric');
        mO = mO((radiusRows + 1):(radiusRows + numRows), (radiusCols + 1):(radiusCols + numCols));
    case(PADDING_MODE_CIRCULAR)
        mHC = mH;
        mHC(numRows, numCols) = 0;
        mHC = circshift(mHC, [-radiusRows, -radiusCols]);

        mO = ifft2(fft2(mI) .* fft2(mHC), 'symmetric');
end

end


function a = c8mat_house ( n, x )

%*****************************************************************************80
%
%% C8MAT_HOUSE constructs a complex Householder elementary reflector matrix.
%
%  Formula:
%
%     A = I - ( 2 * X * hermitian ( X ) ) / ( conjg ( X ) * X )
%
%  Example:
%
%    N = 5, X = ( 1, 1, 1, 0, -1 )
%
%   1/2 -1/2 -1/2  0  1/2
%  -1/2  1/2 -1/2  0  1/2
%  -1/2 -1/2  1/2  0  1/2
%    0    0    0   1   0
%   1/2  1/2  1/2  0  1/2
%
%  Properties:
%
%    A is hermitian: hermitian ( A ) = A.
%
%    Because A is hermitian, it is normal.
%
%    Because A is normal, it is diagonalizable.
%
%    A is unitary: hermitian ( A ) * A = A * hermitian ( A ) = I.
%
%    inverse ( A ) = A.
%
%    det ( A ) = -1.
%
%    LAMBDA(1) = -1.
%
%    If X is the vector used to define A, then X is an eigenvector
%    of A associated with the eigenvalue of -1.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Input, complex X(N), the vector that defines the
%    Householder matrix.
%
%    Output, complex A(N,N), the matrix.
%
  a = c8mat_identity ( n );

  xdot = real ( x(1:n) * x(1:n)' );

  if ( 0.0 < xdot )

    for i = 1 : n
      for j = 1 : n
        a(i,j) = a(i,j) - 2.0 * x(i) * x(j)' / xdot;
      end
    end

  end

  return
end


function angle = i4_to_angle ( i )

%*****************************************************************************80
%
%% I4_TO_ANGLE maps integers to points on a circle.
%
%  Discussion:
%
%    The angles are intended to be used to select colors on a color
%    hexagon whose 6 vertices are red, yellow, green, cyan, blue,
%    magenta.
%
%  Example:
%
%     I   X      ANGLE
%
%     0   0/3      0
%     1   1/3    120
%     2   2/3    240
%
%     3   1/6     60
%     4   3/6    180
%     5   5/6    300
%
%     6   1/12    30
%     7   3/12    90
%     8   5/12   150
%     9   7/12   210
%    10   9/12   270
%    11  11/12   330
%
%    12   1/24    15
%    13   3/24    45
%    14   5/24    75
%    etc
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer I, the index of the desired color.
%
%    Output, real ANGLE, an angle, measured in degrees,
%    between 0 and 360.
%
  if ( 0 <= abs ( i ) && abs ( i ) <= 2 )

    angle = 120.0 * abs ( i );

  else

    i1 = i4_log_2 ( floor ( abs ( i ) / 3 ) );
    i2 = abs ( i ) + 1 - 3 * 2^i1;
    i3 = 2 * ( i2 - 1 ) + 1;
    i4 = 3 * 2^( i1 + 1 );

    angle = 360.0 * i3 / i4;

  end

  return
end


function d = bayesgauss(X,C,M,P)
%BAYESGAUSS Bayes classifier for Gaussian patterns.
%   D = BAYESGAUSS(X,C,M,P) computes Bayes Gaussian decision functions
%   of the n-dimensional patterns in the rows of X. C is an array of
%   size n-by-n-by-Nc containing Nc covariance matrices of size n-by-n,
%   where Nc is the number of classes. M is a matrix of size Nc-by-n,
%   whose rows are the corresponding mean vectors. A covariance matrix
%   and a mean vector must be specified for each class. X is of size
%   K-by-n, where K is the number of patterns to be classified. P is a
%   1-by-Nc vector containing the probabilities of occurrence of each
%   class. If P is not included in the argument, the classes are assumed
%   to be equally likely.
%
%   In the output, D is a column vector of length K. Its ith element is
%   the class number assigned to the ith vector in X during
%   classification.
%
%   Copyright 2002-2020 Gatesmark
%
%   This function, and other functions in the DIPUM Toolbox, are based
%   on the theoretical and practical foundations established in the
%   book Digital Image Processing Using MATLAB, 3rd ed., Gatesmark
%   Press, 2020.
%
%   Book website: http://www.imageprocessingplace.com
%   License: https://github.com/dipum/dipum-toolbox/blob/master/LICENSE.txt

% Verify the number of inputs.
narginchk(3,4)
n = size(C,1); % Dimension of patterns.

% Protect against the possibility that the class number is included
% as an (n + 1)th element of the vectors.
X = double(X(:,1:n));
% Number of pattern classes.
Nc = size(C,3);
% Number of patterns to classify.
K = size(X,1);
if nargin == 3
   P(1:Nc) = 1/Nc; % Classes assumed equally likely.
else
   if sum(P) ~= 1
      error('Elements of P must sum to 1.');
   end
end
% Compute the determinants.
DM = zeros(1,Nc); % Preallocate memory for loop speed.
for J = 1:Nc
   DM(J) = det(C(:,:,J));
end

% Evaluate the decision functions. Note the use of function mahalanobis
% discussed in Section 14.2.
D = zeros(K,Nc); % Preallocate memory for loop speed.
for J = 1:Nc
   Cm = C(:,:,J);
   Mm = M(J,:);
   L(1:K,1) = log(P(J));
   DET(1:K,1) = 0.5*log(DM(J));
   if P(J) == 0
      D(1:K,J) = -inf;
   else
      D(:,J) = L - DET - 0.5*mahalanobis(X,Cm,Mm);
   end
end

% Find the coordinates of the maximum value in each row. The location of
% a maximum gives the class of the corresponding pattern vector.
[i,j] = find(D == max(D,[],2));

% Re-use X. Its first element in a row is the pattern number, and the
% second is the class to which the pattern was assigned.
X = [i,j];

% Eliminate multiple classifications of the same patterns. Since the
% class assignment when two or more decision functions give the same
% value is arbitrary, we need to keep only one. Function unique
% eliminates duplicates and returns the array sorted by rows. This
% re-establishes the original order of the patterns.
[~,idx] = unique(X(:,1));
X = X(idx,:);
% X is now sorted, with the 2nd column giving the class of the pattern
% number in the 1st col.;  i.e., X(j,1) refers to the jth input pattern,
% and X(j,2) is its class number.

% Output the result of classification. d is a column vector with length
% equal to the total number of input patterns. The elements of d are the
% classes into which the patterns (in their original order) were
% classified.
d = X(:,2);


function X_rec = recoverData(Z, U, K)
%RECOVERDATA Recovers an approximation of the original data when using the
%projected data
%   X_rec = RECOVERDATA(Z, U, K) recovers an approximation the
%   original data that has been reduced to K dimensions. It returns the
%   approximate reconstruction in X_rec.
%

% You need to return the following variables correctly.
X_rec = zeros(size(Z, 1), size(U, 1));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the approximation of the data by projecting back
%               onto the original space using the top K eigenvectors in U.
%
%               For the i-th example Z(i,:), the (approximate)
%               recovered data for dimension j is given as follows:
%                    v = Z(i, :)';
%                    recovered_j = v' * U(j, 1:K)';
%
%               Notice that U(j, 1:K) is a row vector.
%
for i=1:size(Z, 1)
   v = Z(i,:)';

   X_rec(i,:) = v'*U(:,1:K)';

end

% =============================================================

end


function [X,names]=elipcyl
% [X,names]=elipcyl defines elliptic
% cylinder coordinates
syms et ps z real; names=[et ps z];
X=[cosh(et)*cos(ps);
   sinh(et)*sin(ps); z];


function [R, G, B] = Lab2RGB(L, a, b)
% function [R, G, B] = Lab2RGB(L, a, b)
% Lab2RGB takes matrices corresponding to L, a, and b in CIELab space
% and transforms them into RGB.  This transform is based on ITU-R
% Recommendation  BT.709 using the D65 white point reference.
% and the error in transforming RGB -> Lab -> RGB is approximately
% 10^-5.  By Mark Ruzon from C code by Yossi Rubner, 23 September 1997.
% Updated for MATLAB 5 28 January 1998.
% Fixed a bug in conversion back to uint8 9 September 1999.

if (nargin == 1)
  b = L(:,:,3);
  a = L(:,:,2);
  L = L(:,:,1);
end

% Thresholds
T1 = 0.008856;
T2 = 0.206893;

[M, N] = size(L);
s = M * N;
L = reshape(L, 1, s);
a = reshape(a, 1, s);
b = reshape(b, 1, s);

% Compute Y
fY = ((L + 16) / 116) .^ 3;
YT = fY > T1;
fY = (~YT) .* (L / 903.3) + YT .* fY;
Y = fY;

% Alter fY slightly for further calculations
fY = YT .* (fY .^ (1/3)) + (~YT) .* (7.787 .* fY + 16/116);

% Compute X
fX = a / 500 + fY;
XT = fX > T2;
X = (XT .* (fX .^ 3) + (~XT) .* ((fX - 16/116) / 7.787));

% Compute Z
fZ = fY - b / 200;
ZT = fZ > T2;
Z = (ZT .* (fZ .^ 3) + (~ZT) .* ((fZ - 16/116) / 7.787));

X = X * 0.950456;
Z = Z * 1.088754;

MAT = [ 3.240479 -1.537150 -0.498535;
       -0.969256  1.875992  0.041556;
        0.055648 -0.204043  1.057311];

RGB = max(min(MAT * [X; Y; Z], 1), 0);

R = reshape(RGB(1,:), M, N) * 255;
G = reshape(RGB(2,:), M, N) * 255;
B = reshape(RGB(3,:), M, N) * 255;

if ((nargout == 1) | (nargout == 0))
  R = uint8(round(cat(3,R,G,B)));
end


% Example 6.4: Regressor selection problem
% Section 6.3.1, Figure 6.7
% Original by Lieven Vandenberghe
% Adapted for CVX Argyris Zymnis - 10/2005
%
% Solves
%        minimize   ||A*x-b||_2
%        subject to card(x) <= k
%
% where card(x) denotes the number of nonzero elements in x,
% by first solving (for some value of alpha close to ||x_ln||_1)
%        minimize   ||A*x-b||_2
%        subject to ||x||_1 <= alpha
%
% and iteratively decreasing alpha so as to get card(x) = k
% The sparsity pattern is then fixed in A and b and
%        minimize   ||A*x-b||_2
%
% is solved

rand('state',0);
randn('state',0);

m = 10;
n = 20;

A = randn(m,n);
b = A*[randn(round(m/2),1); zeros(n-round(m/2),1)];
b = b + 0.1*norm(b)*randn(m,1);

if (1) %%%%%%%%%%%%

% tradeoff curve for heuristic
%
% min.  ||Ax-b||_2
% s.t.  ||x||_1 <= alpha

xln = A'*((A*A')\b);
lnorm = norm(xln,1);
nopts = 100;
alphas = linspace(0,lnorm,nopts);
residuals_heur = norm(b);
card_heur = 0;

for k=2:(nopts-1)
  alpha = alphas(k);

  cvx_begin quiet
    variable x(n)
    minimize(norm(A*x-b))
    subject to
        norm(x,1) <= alpha; %#ok
  cvx_end

  x(abs(x) < 1e-3*max(abs(x))) = 0; %#ok
  ind = find(abs(x));
  sparsity = length(ind);
  fprintf(1,'Current sparsity pattern k = %d \n',sparsity);
  x = zeros(n,1);  x(ind) = A(:,ind)\b;
  card_heur = [card_heur, sparsity]; %#ok
  residuals_heur = [residuals_heur, norm(A*x-b)]; %#ok
end;

obj1 = norm(b);
obj2 = 0;
obj1 %#ok

i=1;
for k=1:m-1
  if any(card_heur == k)
     obj2(i+1) = k; %#ok
     obj1(i+1) = min(residuals_heur(card_heur ==k));
     i=i+1;
  end;
end;
obj2(i) = m;  obj1(i) = 0;

end; %%%%%%%%%%%%%%%%%%%

% globally optimal tradeoff

if (1) %%%%%%%%%%%%%

bestx = zeros(n,m);
bestres = zeros(1,m);

for k=1:m-1
  k %#ok
  % enumerate sparsity patterns with exactly k nonzeros
  bestres(k) = Inf;
  ind = 1:k %#ok
  nocases = 1;
  done = 0;
  while ~done
     done = 1;
     for i=0:k-1
       if (ind(k-i) < n-i),
          ind(k-i:k) = ind(k-i)+(1:i+1);
          done = 0;
          break;
       end;
     end;
     if done, break; end;
     x = zeros(n,1);
     x(ind) = A(:,ind)\b;
     if (norm(A*x-b) < bestres(k)),
        bestres(k) = norm(A*x-b);
        bestx(:,k) = x;
     end;
     nocases = nocases + 1;
  end;
  nocases %#ok
  factorial(n)/(factorial(n-k)*factorial(k)) %#ok
end;

x = A\b;
bestres(m) = norm(A*x-b);
bestres = [norm(b) bestres];

end; %%%%%%%%%

figure
hold off
obj1dbl =[];
obj2dbl =[];
for i=1:length(obj1)-1
  obj1dbl = [obj1dbl, obj1(i), obj1(i)]; %#ok
  obj2dbl = [obj2dbl, obj2(i), obj2(i+1)]; %#ok
end;
obj1dbl = [obj1dbl, obj1(length(obj1))];
obj2dbl = [obj2dbl, obj2(length(obj1))];

bestobj1 = bestres;
bestobj2 = 0:m;
bestobj1dbl =[];
bestobj2dbl =[];
for i=1:length(bestobj1)-1
  bestobj1dbl = [bestobj1dbl, bestobj1(i), bestobj1(i)]; %#ok
  bestobj2dbl = [bestobj2dbl, bestobj2(i), bestobj2(i+1)]; %#ok
end;
bestobj1dbl = [bestobj1dbl, bestobj1(length(bestobj1))];
bestobj2dbl = [bestobj2dbl, bestobj2(length(bestobj1))];

plot(obj1dbl,obj2dbl,'-', bestobj1dbl, bestobj2dbl,'--');
hold on
plot(obj1,obj2,'o', bestobj1, bestobj2,'o');
axis([0 ceil(2*norm(b))/2 0 m+1])
xlabel('x');
ylabel('y');
hold off

%print -deps sparse_regressor_global_helv.eps
%save regressor_results


function [P, mx]=getpca(X, nsig)

%X: MxN matrix (M dimensions, N trials)
%Y: Y=P*X
%P: the transform matrix
%V: the variance vector

[M,N]=size(X);

mx   =  mean(X,2);
mx2  =  repmat(mx,1,N);

X=X-mx2;

CovX=X*X'/(N-1);

CovX  =  CovX - diag(nsig^2*ones(size(CovX,1),1));
ind = find(CovX<0);
CovX(ind) =0.0001;

[P,V]=eig(CovX);

V=diag(V);
[t,ind]=sort(-V);
% V=V(ind);
P=P(:,ind);
P=P';
% Y=P*X;

return;


function [ y, m, d, f ] = jed_to_ymdf_gregorian2 ( jed )

%*****************************************************************************80
%
%% JED_TO_YMDF_GREGORIAN2 converts a JED to a Gregorian YMDF date.
%
%  Discussion:
%
%    The theory behind this routine is very clean.  The Gregorian
%    calendar has cycles of 1, 4, 100 and 400 years, and we can
%    analyze a date by determining where it lies within these cycles.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 July 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Edward Reingold, Nachum Dershowitz, Stewart Clamen,
%    Calendrical Calculations, II: Three Historical Calendars,
%    Software - Practice and Experience,
%    Volume 23, Number 4, pages 383-404, April 1993.
%
%  Parameters:
%
%    Input, real JED, the Julian Ephemeris Date.
%
%    Output, integer Y, M, D, real F, the YMDF date.
%
  g1 = 365;
  g4 = 1461;
  g100 = 36524;
  g400 = 146097;

  jed_epoch = epoch_to_jed_gregorian ( );

  j = floor ( jed - jed_epoch );
  f1 = ( jed - jed_epoch ) - j;

  d0 = j;
  n400 = 0;

  while ( d0 < 0 )
    d0 = d0 + g400;
    n400 = n400 - 1;
  end

  n400 = n400 + floor ( d0 / g400 );
  d1 = i4_modp ( d0, g400 );

  n100 = floor ( d1 / g100 );
  d2 = i4_modp ( d1, g100 );

  n4 = floor ( d2 / g4 );
  d3 = i4_modp ( d2, g4 );

  n1 = floor ( d3 / g1 );
  d4 = i4_modp ( d3, g1 );

  if ( n100 == 4 || n1 == 4 )
    j1 = 366;
    y1 = 400 * n400 + 100 * n100 + 4 * n4 + n1;
  else
    j1 = d4 + 1;
    y1 = 400 * n400 + 100 * n100 + 4 * n4 + n1 + 1;
  end
%
%  Any year before 1 AD must be moved one year further back, since
%  this calendar does not include a year 0.
%
  y1 = y_astronomical_to_common ( y1 );

  [ y, m, d, f ] = yjf_to_ymdf_gregorian ( y1, j1, f1 );

  return
end


function oev = eci2orb1 (mu, r, v)

% convert eci state vector to six classical orbital
% elements via equinoctial elements

% input

%  mu = central body gravitational constant (km**3/sec**2)
%  r  = eci position vector (kilometers)
%  v  = eci velocity vector (kilometers/second)

% output

%  oev(1) = semimajor axis (kilometers)
%  oev(2) = orbital eccentricity (non-dimensional)
%           (0 <= eccentricity < 1)
%  oev(3) = orbital inclination (radians)
%           (0 <= inclination <= pi)
%  oev(4) = argument of perigee (radians)
%           (0 <= argument of perigee <= 2 pi)
%  oev(5) = right ascension of ascending node (radians)
%           (0 <= raan <= 2 pi)
%  oev(6) = true anomaly (radians)
%           (0 <= true anomaly <= 2 pi)

% Orbital Mechanics with MATLAB

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

pi2 = 2.0 * pi;

% position and velocity magnitude

rmag = norm(r);

vmag = norm(v);

% position unit vector

rhat = r / rmag;

% angular momentum vectors

hv = cross(r, v);

hhat = hv / norm(hv);

% eccentricity vector

vtmp = v / mu;

ecc = cross(vtmp, hv);

ecc = ecc - rhat;

% semimajor axis

sma = 1.0 / (2.0 / rmag - vmag * vmag / mu);

p = hhat(1) / (1.0 + hhat(3));

q = -hhat(2) / (1.0 + hhat(3));

const1 = 1.0 / (1.0 + p * p + q * q);

fhat(1) = const1 * (1.0 - p * p + q * q);
fhat(2) = const1 * 2.0 * p * q;
fhat(3) = -const1 * 2.0 * p;

ghat(1) = const1 * 2.0 * p * q;
ghat(2) = const1 * (1.0 + p * p - q * q);
ghat(3) = const1 * 2.0 * q;

h = dot(ecc, ghat);

xk = dot(ecc, fhat);

x1 = dot(r, fhat);

y1 = dot(r, ghat);

% orbital eccentricity

eccm = sqrt(h * h + xk * xk);

% orbital inclination

inc = 2.0 * atan(sqrt(p * p + q * q));

% true longitude

xlambdat = atan3(y1, x1);

% check for equatorial orbit

if (inc > 0.00000001)
    raan = atan3(p, q);
else
    raan = 0.0;
end

% check for circular orbit

if (eccm > 0.00000001)
    argper = mod(atan3(h, xk) - raan, pi2);
else
    argper = 0.0;
end

% true anomaly

tanom = mod(xlambdat - raan - argper, pi2);

% load orbital element vector

oev(1) = sma;
oev(2) = eccm;
oev(3) = inc;
oev(4) = argper;
oev(5) = raan;
oev(6) = tanom;


function p = binary_search(A,t)
%% Binary Search
% This function binary searches target value (t) in sorted (in increasing order) array A.
% Binary search compares the target value to the middle element of the
% array. If they are not equal, it determines the half part of array in which the taget might be existed,
% then changes the search range from left or right to half array range and
% repeat searching for this new range.
% If target can be found in array, this function returns its index.
% If target can not be found in array, it displays "target is not found in
% array"

array_length = length(A);
counter = 0;                                      % number of iteration in searching algorithm
L_SearchRange = 1;                                %initial search range
R_SearchRange = array_length;

while counter <= floor(log2(array_length))+1       %maximum iteration needed to find the target
mid = (L_SearchRange + R_SearchRange)/2;

if t == A(floor(mid))
    p = floor(mid);
    break
else if t > A(floor(mid))
        L_SearchRange = floor(mid)+1;
    else
        R_SearchRange = floor(mid)-1;
        if R_SearchRange == 0            %to stop searching when t is less than the minimum value of array
           counter = counter +1;
        end
    end
 counter = counter+1;
end
end
if counter > floor(log2(array_length))+1
    disp('target is not found in aray')
end
end


%% Example 9.18: Hermite expansion of Benes SDE
%
% Copyright:
%   2018 - Simo Särkkä and Arno Solin
%
% License:
%   This software is provided under the MIT License. See the accompanying
%   LICENSE file for details.

%% Plot the Hermite expansion example

    x0 = 1/2;
    trans_dens = @(xx,t) 1./sqrt(2*pi*t).*cosh(xx)./cosh(x0).*exp(-0.5*t).*exp(-1./(2*t).*(xx-x0).^2);

    %
    % % Symbolic solution (requires the Symbolic Math Toolbox)
    % syms x;
    % f = matlabFunction(tanh(x));
    % df = matlabFunction(diff(tanh(x),1));
    % d2f = matlabFunction(diff(tanh(x),2));
    % d3f = matlabFunction(diff(tanh(x),3));
    % d4f = matlabFunction(diff(tanh(x),4));
    % d5f = matlabFunction(diff(tanh(x),5));
    %

    f = @(x) tanh(x);
    df = @(x) 1 - tanh(x)^2;
    d2f = @(x) 2*tanh(x)*(tanh(x)^2 - 1);
    d3f = @(x) -2*(tanh(x)^2 - 1)^2 - 4*tanh(x)^2*(tanh(x)^2 - 1);
    d4f = @(x) 16*tanh(x)*(tanh(x)^2 - 1)^2 + 8*tanh(x)^3*(tanh(x)^2 - 1);
    d5f = @(x) -16*(tanh(x)^2 - 1)^3 - 16*tanh(x)^4*(tanh(x)^2 - 1) - 88*tanh(x)^2*(tanh(x)^2 - 1)^2;

    xx = -15:0.1:15;

    figure(1); clf; hold on

      % Solve at t=2
      t = 2;
      herm_x = herm_exp(f(x0),df(x0),d2f(x0),d3f(x0),d4f(x0),d5f(x0),t,xx,x0);

      % Exact density
      fill(xx,trans_dens(xx,t),1,'FaceColor',[.7 .7 .7],'EdgeColor',[.7 .7 .7])

      % Series approximation
      plot(xx,herm_x,'-k','LineWidth',1)

      ylim([-0.21 0.25]);
      legend('Exact density','Series approximation','Location','south');
      xlabel('$x$');
      ylabel('$p(x)$');

    figure(2); clf; hold on

      % Solve at t=5
      t = 5;
      herm_x = herm_exp(f(x0),df(x0),d2f(x0),d3f(x0),d4f(x0),d5f(x0),t,xx,x0);

      % Exact density
      fill(xx,trans_dens(xx,t),1,'FaceColor',[.7 .7 .7],'EdgeColor',[.7 .7 .7])

      % Series approximation
      plot(xx,herm_x,'-k','LineWidth',1)

      ylim([-0.21 0.25]);
      xlabel('$x$');
      ylabel('$p(x)$');


% EX_ARTICLE_SECTION_512: short example with a non-isoparametric approach, and a non-NURBS geometry.
%
% Example to solve the problem
%
%    - div ( grad (u)) = (8-9*sqrt(x.^2+y.^2)).*sin(2*atan(y./x))./(x.^2+y.^2)  in Omega
%                    u = 0                                                      on Gamma
%
% with                Omega = (1 < x^2+y^2 < 4) & (x > 0) & (y > 0)
% and exact solution      u = (x.^2+y.^2-3*sqrt(x.^2+y.^2)+2).*sin(2.*atan(y./x))
%
% This solves the example of Section 5.1.2 in the article
%
% C. De Falco, A. Reali, R. Vazquez
% GeoPDEs: a research tool for IsoGeometric Analysis of PDEs
%
% Copyright (C) 2009, 2010 Carlo de Falco
% Copyright (C) 2011, 2015 Rafael Vazquez
%
%    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/>.

geometry = geo_load ({@ring_polar_map, @ring_polar_map_der});

knots = kntuniform ([9 9], [4 4], [3 3]);
[qn, qw] = msh_set_quad_nodes (knots, msh_gauss_nodes ([5 5]));
msh = msh_cartesian (knots, qn, qw, geometry);

space = sp_bspline (knots, [4 4], msh);

mat = op_gradu_gradv_tp (space, space, msh);
rhs = op_f_v_tp (space, msh, @(x, y) (8-9*sqrt(x.^2+y.^2)).*sin(2*atan(y./x))./(x.^2+y.^2));

drchlt_dofs = [];
for iside = 1:4
  drchlt_dofs = union (drchlt_dofs, space.boundary(iside).dofs);
end
int_dofs = setdiff (1:space.ndof, drchlt_dofs);

u = zeros (space.ndof, 1);
u(int_dofs) = mat(int_dofs, int_dofs) \ rhs(int_dofs);

sp_to_vtk (u, space, geometry, [20 20], 'laplace_solution.vts', 'u')
err = sp_l2_error (space, msh, u, @(x,y)(x.^2+y.^2-3*sqrt(x.^2+y.^2)+2).*sin(2.*atan(y./x)))

%!demo
%! ex_article_section_512;

%!test
%! geometry = geo_load ({@ring_polar_map, @ring_polar_map_der});
%! knots = kntuniform ([9 9], [4 4], [3 3]);
%! [qn, qw] = msh_set_quad_nodes (knots, msh_gauss_nodes ([5 5]));
%! msh = msh_cartesian (knots, qn, qw, geometry);
%! space = sp_bspline (knots, [4 4], msh);
%! mat = op_gradu_gradv_tp (space, space, msh, @(x, y) ones (size (x)));
%! rhs = op_f_v_tp (space, msh, @(x, y) (8-9*sqrt(x.^2+y.^2)).*sin(2*atan(y./x))./(x.^2+y.^2));
%! drchlt_dofs = [];
%! for iside = 1:4
%! drchlt_dofs = union (drchlt_dofs, space.boundary(iside).dofs);
%! end
%! int_dofs = setdiff (1:space.ndof, drchlt_dofs);
%! u = zeros (space.ndof, 1);
%! u(int_dofs) = mat(int_dofs, int_dofs) \ rhs(int_dofs);
%! err = sp_l2_error (space, msh, u, @(x,y)(x.^2+y.^2-3*sqrt(x.^2+y.^2)+2).*sin(2.*atan(y./x)));
%! assert (msh.nel, 64)
%! assert (space.ndof, 144)
%! assert (err, 2.82510645627626e-07, 1e-16)


function S = eliminator(n, ROWS)
%
%ELIMINATOR
%
% Returns a matrix S that is called eliminator.
% S is a matrix such that S*A (assuming that this product
% exists) will not contain rows listed in row vector ROWS.
% Numbers of rows in ROWS can be unsorted.
%
% Example:
%     A = hilb(6);
%     S = eliminator(6, [4 6 2]);
%     B = S * A;
% Matrix B will contain rows 1, 3, 5 from the matrix A,
% matrix B will not contain rows 2, 4, 6 from matrix A.
%
% (C) 2000 Igor Podlubny, Blas Vinagre, Tomas Skovranek
%
% See:
% [1] I. Podlubny, A.Chechkin, T. Skovranek, YQ Chen,
%     B. M. Vinagre Jara, "Matrix approach to discrete
%     fractional calculus II: partial fractional differential
%     equations". http://arxiv.org/abs/0811.1355
% [2] R.G. Cooke, Infinite Matrices and Sequence Spaces,
%     MacMillan and Co., London, 1950. 347 pp.

S = eye(n);
r = sort(ROWS);
m = size(r,2);

for k = m:(-1):1
   if r(k)-1 == 0
        S = S((r(k)+1):(size(S,1)-k+1),:);
   elseif r(k) == size(S,1)
        S = S(1:(r(k)-1),:);
   else
        S = [S(1:(r(k)-1),:);  S((r(k)+1):(size(S,1)),:)];
   end
end


function pdf = bernoulli_pdf ( x, a )

%*****************************************************************************80
%
%% BERNOULLI_PDF evaluates the Bernoulli PDF.
%
%  Discussion:
%
%    PDF(X)(A) = A**X * ( 1.0D+00 - A )**( X - 1 )
%
%    X = 0 or 1.
%
%    The Bernoulli PDF describes the simple case in which a single trial
%    is carried out, with two possible outcomes, called "success" and
%    "failure"; the probability of success is A.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer X, the number of successes on a single trial.
%    X = 0 or 1.
%
%    Input, real A, the probability of success on one trial.
%    0.0D+00 <= A <= 1.0.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x < 0 )
    pdf = 0.0;
  elseif ( x == 0 )
    pdf = 1.0 - a;
  elseif ( x == 1 )
    pdf = a;
  else
    pdf = 0.0;
  end

  return
end


function pp = sphere_imp_point_project_3d ( r, center, p )

%*****************************************************************************80
%
%% SPHERE_IMP_POINT_PROJECT_3D projects a point onto an implicit sphere in 3D.
%
%  Discussion:
%
%    An implicit sphere in 3D satisfies the equation:
%
%      sum ( ( P(1:DIM_NUM) - CENTER(1:DIM_NUM) )**2 ) = R**2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real CENTER(3), the center of the sphere.
%
%    Input, real P(3), a point.
%
%    Output, real PP(3), the projected point.
%
  dim_num = 3;

  if ( r == 0.0 )

    pp(1:dim_num) = center(1:dim_num);

  elseif ( p(1:dim_num) == center(1:dim_num) )

    pp(1:dim_num) = center(1:dim_num) + r / sqrt ( dim_num );

  else

    norm = sqrt ( sum ( ( p(1:dim_num) - center(1:dim_num) ).^2 ) );

    pp(1:dim_num) = center(1:dim_num) + r * ( p(1:dim_num) - center(1:dim_num) ) / norm;

  end

  return
end


function w = w0_func(z,N)
% Based on:
% FADDEEVA   Faddeeva function
%   W = FADDEEVA(Z) is the Faddeeva function, aka the plasma dispersion
%   function, for each element of Z. The Faddeeva function is defined as:
%
%     w(z) = exp(-z^2) * erfc(-j*z)
%
%   where erfc(x) is the complex complementary error function.
%
%   W = FADDEEVA(Z,N) can be used to explicitly specify the number of terms
%   to truncate the expansion (see (13) in [1]). N = 16 is used as default.
%
%   Example:
%       x = linspace(-10,10,1001); [X,Y] = meshgrid(x,x);
%       W = faddeeva(complex(X,Y));
%       figure;
%       subplot(121); imagesc(x,x,real(W)); axis xy square; caxis([-1 1]);
%       title('re(faddeeva(z))'); xlabel('re(z)'); ylabel('im(z)');
%       subplot(122); imagesc(x,x,imag(W)); axis xy square; caxis([-1 1]);
%       title('im(faddeeva(z))'); xlabel('re(z)'); ylabel('im(z)');
%
%   Reference:
%   [1] J.A.C. Weideman, "Computation of the Complex Error Function," SIAM
%       J. Numerical Analysis, pp. 1497-1518, No. 5, Vol. 31, Oct., 1994
%       Available Online: http://www.jstor.org/stable/2158232

% Called by: crbs6.m, crbs7.m

if nargin<2, N = []; end
if isempty(N), N = 50; end

w = zeros(size(z)); % initialize output

%%%%%
% for purely imaginary-valued inputs, use erf as is if z is real
idx = real(z)==0; %
w(idx) = exp(-z(idx).^2).*erfc(imag(z(idx)));

if all(idx), return; end
idx = ~idx;

%%%%%
% for complex-valued inputs

% make sure all points are in the upper half-plane (positive imag. values)
idx1 = idx & imag(z)<0;
z(idx1) = conj(z(idx1));

M = 2*N;
M2 = 2*M;
k = (-M+1:1:M-1)'; % M2 = no. of sampling points.
L = sqrt(N/sqrt(2)); % Optimal choice of L.

theta = k*pi/M;
t = L*tan(theta/2); % Variables theta and t.
f = exp(-t.^2).*(L^2+t.^2);
f = [0; f]; % Function to be transformed.
a = real(fft(fftshift(f)))/M2; % Coefficients of transform.
a = flipud(a(2:N+1)); % Reorder coefficients.

Z = (L+1i*z(idx))./(L-1i*z(idx));
p = polyval(a,Z); % Polynomial evaluation.
w(idx) = 2*p./(L-1i*z(idx)).^2 + (1/sqrt(pi))./(L-1i*z(idx)); % Evaluate w(z).

% convert the upper half-plane results to the lower half-plane if necesary
w(idx1) = conj(2*exp(-z(idx1).^2) - w(idx1));

w=-w*sqrt(-1)*pi; % converts to 'w0_func' used in crbs_molecular.m


% Mathematics Q561696
% https://math.stackexchange.com/questions/561696
% Solving Non Negative Least Squares by Analogy with Least Squares (MATLAB)
% References:
%   1.  aa
% Remarks:
%   1.  sa
% TODO:
% 	1.  ds
% Release Notes
% - 1.0.000     05/08/2017
%   *   First release.

%% General Parameters

run('InitScript.m');

figureIdx           = 0; %<! Continue from Question 1
figureCounterSpec   = '%04d';

generateFigures = OFF;

%% Simulation Parameters

numRows = 4;
numCols = 3; %<! Number of Vectors - i (K in the question)

numIterations   = 10000;
stepSize        = 0.075;

%% Generate Data

mA = randn([numRows, numCols]);
vB = randn([numRows, 1]);

%% Solution by CVX

cvx_begin('quiet')
    cvx_precision('best');
    variable vX(numCols)
    minimize( square_pos(  norm(mA * vX - vB, 2) ) );
    subject to
        vX >= 0;
cvx_end

disp([' ']);
disp(['CVX Solution Summary']);
disp(['The CVX Solver Status - ', cvx_status]);
disp(['The Optimal Value Is Given By - ', num2str(cvx_optval)]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Solution by Projected Gradient Descent

vX = zeros([numCols, 1]);

for ii = 1:numIterations
    vX = vX - ((stepSize / sqrt(ii)) * mA.' * (mA * vX - vB));
    vX = max(vX, 0);
end

objVal = sum((mA * vX - vB) .^ 2);

disp([' ']);
disp(['Projected Gradient Solution Summary']);
disp(['The Optimal Value Is Given By - ', num2str(objVal)]);
disp(['The Optimal Argument Is Given By - [ ', num2str(vX.'), ' ]']);
disp([' ']);

%% Restore Defaults

% set(0, 'DefaultFigureWindowStyle', 'normal');
% set(0, 'DefaultAxesLooseInset', defaultLoosInset);


function [ w, seed ] = direction_uniform_nd ( dim_num, seed )

%*****************************************************************************80
%
%% DIRECTION_UNIFORM_ND generates a random direction vector in ND.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the dimension of the space.
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, real W(DIM_NUM), a random direction vector,
%    with unit norm.
%
%    Output, integer SEED, a seed for the random number generator.
%

%
%  Get N values from a standard normal distribution.
%
  [ w, seed ] = r8vec_normal_01 ( dim_num, seed );
%
%  Compute the length of the vector.
%
  norm = sqrt ( sum ( w(1:dim_num).^2 ) );
%
%  Normalize the vector.
%
  w(1:dim_num) = w(1:dim_num) / norm;

  return
end


function Cn = correlation_image(Y,sz,d1,d2,flag_norm, K)

% construct correlation image based on neighboing pixels
% Y: raw data
% sz: define the relative location of neighbours. it can be scalar, 2
%       element vector or a binary matrix
%       scalar: number of nearest neighbours, either 4 or 8, default 4
%       2 element vector: [rmin, rmax], the range of neighbours. the
%           distance between the neighbour and the pixel is d, dmin <= r <
%           dmax.
%       matrix: a squared matrix (2k+1)*(2k+1)indicating the location of neighbours
% d1,d2: spatial dimensions
% flag_norm: indicate whether Y has been normalized and centered ( 1 is
%   yes, 0 is no)
% K:  scalar, the rank of the random matrix for projection

% Author: Eftychios A. Pnevmatikakis, Simons Foundation, 2015
% with modifications from Pengcheng Zhou, Carnegie Mellon University, 2015.
% It uses convolution and random projection for speeding up the
% computation.

%% preprocess the raw data
if ~exist('flag_norm', 'var') || isempty(flag_norm)
    flag_norm = false;
end

if ~exist('sz', 'var') || isempty(sz)
    sz = [0,1,0; 1,0,1; 0,1,0];
end

% center data
Y = bsxfun(@minus, double(Y), mean(Y, ndims(Y)));
if ~ismatrix(Y)
    [d1, d2, T] = size(Y);
else
    T = size(Y, 2);
end

if exist('K', 'var') && (~isempty(K))
    Y = double(reshape(Y, [], T))*randn(T, K);
    % centering
    mY = mean(Y,2);
    Y = bsxfun(@minus, Y, mY);        % normalizing
    flag_norm = false;
end
if ~flag_norm
    sY = sqrt(mean(Y.*Y, ndims(Y)));
    sY(sY==0) = 1; % avoid nan values
    Y = bsxfun(@times, Y, 1./sY);
end
if ismatrix(Y)
    Y = reshape(Y, d1, d2, []);
end

%% construct a matrix indicating location of the matrix
if  isscalar(sz)
    if sz == 8      % 8 nearest neighbours
        sz = [1,1,1; 1,0,1; 1,1,1];
    elseif sz==4
        sz = [0,1,0; 1,0,1; 0,1,0];
    end
elseif length(sz(:)) == 2
    % the specified neighbours has a distance within the domain [dmin,
    % dmax)
    sz = ceil(sz);
    dmin = min(sz); dmax = max(sz);
    rsub = (-dmax+1):(dmax-1);      % row subscript
    csub = rsub;      % column subscript
    [cind, rind] = meshgrid(csub, rsub);
    R = sqrt(cind.^2+rind.^2);
    sz = (R>=dmin) .* (R<dmax);
end

%% compute the correlation
Yconv = imfilter(Y, sz);        % sum over the neighbouring pixels
MASK = imfilter(ones(d1,d2), sz);   % count the number of neighbouring pixels
Cn = mean(Yconv.*Y, 3)./MASK;   % compute correlation and normalize


function hermite_test01 ( )

%*****************************************************************************80
%
%% TEST01 uses f(x) = 1 + 2x + 3x^2 at x = 0, 1, 2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 May 2011
%
%  Author:
%
%    John Burkardt
%
  n = 3;

  x =  [ 0.0; 1.0;  2.0 ];
  y =  [ 1.0; 6.0; 17.0 ];
  yp = [ 2.0; 8.0; 14.0 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST01\n' );
  fprintf ( 1, '  HERMITE computes the Hermite interpolant to data.\n' );
  fprintf ( 1, '  Here, f(x) = 1 + 2x + 3x^2.\n' );

  hermite_demo ( n, x, y, yp );

  return
end


function [ n_data, a, b, n, fx ] = cos_power_int_values ( n_data )

%*****************************************************************************80
%
%% COS_POWER_INT_VALUES returns some values of the cosine power integral.
%
%  Discussion:
%
%    The function has the form
%
%      COS_POWER_INT(A,B,N) = Integral ( A <= T <= B ) ( cos(T) )^N dt
%
%    In Mathematica, the function can be evaluated by:
%
%      Integrate [ ( Cos[x] )^n, { x, a, b } ]
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 March 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Stephen Wolfram,
%    The Mathematica Book,
%    Fourth Edition,
%    Cambridge University Press, 1999,
%    ISBN: 0-521-64314-7,
%    LC: QA76.95.W65.
%
%  Parameters:
%
%    Input/output, integer N_DATA.  The user sets N_DATA to 0
%    before the first call.  On each call, the routine increments N_DATA by 1,
%    and returns the corresponding data; when there is no more data, the
%    output value of N_DATA will be 0 again.
%
%    Output, real A, B, the limits of integration.
%
%    Output, integer N, the power.
%
%    Output, real FX, the function value.
%
  n_max = 11;

  a_vec = [ ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00, ...
     0.00 ];
  b_vec = [ ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793, ...
     3.141592653589793 ];
  fx_vec = [ ...
     3.141592653589793, ...
     0.0, ...
     1.570796326794897, ...
     0.0, ...
     1.178097245096172, ...
     0.0, ...
     0.9817477042468104, ...
     0.0, ...
     0.8590292412159591, ...
     0.0, ...
     0.7731263170943632 ];
  n_vec = [ ...
     0, ...
     1, ...
     2, ...
     3, ...
     4, ...
     5, ...
     6, ...
     7, ...
     8, ...
     9, ...
    10 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    a = 0.0;
    b = 0.0;
    n = 0;
    fx = 0.0;
  else
    a = a_vec(n_data);
    b = b_vec(n_data);
    n = n_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end


%% Efficient subpixel image registration by cross-correlation.
% Registers two images (2-D rigid translation) within a  fraction
% of a pixel specified by the user. Instead of computing a zero-padded FFT
% (fast Fourier transform), this code uses selective upsampling by a
% matrix-multiply DFT (discrete FT) to dramatically reduce computation time and memory
% without sacrificing accuracy. With this procedure all the image points are used to
% compute the upsampled cross-correlation in a very small neighborhood around its peak. This
% algorithm is referred to as the single-step DFT algorithm in [1].
%
% [1] Manuel Guizar-Sicairos, Samuel T. Thurman, and James R. Fienup,
% "Efficient subpixel image registration algorithms," Opt. Lett. 33,
% 156-158 (2008).

%% Syntax
% The code receives the FFT of the reference and the shifted images, and an
% (integer) upsampling factor. The code expects FFTs with DC in (1,1) so do not use
% fftshift.
%
%    output = dftregistration(fft2(f),fft2(g),usfac);
%
% The images are registered to within 1/usfac of a pixel.
%
% output(1) is the normalized root-mean-squared error (NRMSE) [1] between f and
% g.
%
% output(2) is the global phase difference between the two images (should be
% zero if images are real-valued and non-negative).
%
% output(3) and output(4) are the row and column shifts between f and g respectively.
%
%    [output Greg] = dftregistration(fft2(f),fft2(g),usfac);
%
% Greg is an optional output, it returns the Fourier transform of the registered version of g,
% where the global phase difference [output(2)] is also compensated.

%% Obtain a reference and shifted images
% To illustrate the use of the algorithm, lets obtain a reference and a
% shifted image. First we read the reference image f(x,y)
f = im2double(imread('cameraman.tif'));
%%
% Define g(x,y) as a version of f(x,y) shifted by fractional values of a
% pixel and multiplied by a global phase.
deltar = 3.48574;
deltac = 8.73837;
phase = 2;
[nr,nc]=size(f);
Nr = ifftshift([-fix(nr/2):ceil(nr/2)-1]);
Nc = ifftshift([-fix(nc/2):ceil(nc/2)-1]);
[Nc,Nr] = meshgrid(Nc,Nr);
g = ifft2(fft2(f).*exp(i*2*pi*(deltar*Nr/nr+deltac*Nc/nc))).*exp(-i*phase);
figure(1);
subplot(1,2,1);
imshow(abs(f));
title('Reference image, f(x,y)')
subplot(1,2,2);
imshow(abs(g));
title('Shifted image, g(x,y)')
%%
% We have shifted the image by 8.73837 and 3.48574 pixels in the x and
% y direction, respectively, and added a phase of 2 radians to g(x,y). The shift
% was implemented by applying a linear phase on its
% FT, thus we have assumed that the images wrap around (features leaving one
% side of the window reappear on the opposite side) and that the image is band-limited
% (interpolated by a sinc function). Cross-correlation image registration by DFTs
% (both the matrix-multiply DFT and the zero-padded FFT) share these assumptions.
%
% This registration technique is well suited to compare images that are captured
% in Fourier domain (i.e. to evaluate an image reconstruction by holography
% or phase retrieval) which are strictly band-limited and exhibit the
% wrap-around effect.
%
% Even though the registration code assumes band-limited images that wrap around, we
% have obtained very good results when applying it to
% band-limited microscope images, and aliased imagery. That is when shifting
% the image brings in new content instead of wrapping it around or when the
% images are not band-limited.

%% Sample Image Registration
% dftregistration.m receives the FT of f and g and the upsampling factor.
% The code expects DC of the FTs at (1,1) so don't use fftshift.
%
% We now use the image registration code to register f and g within 0.01
% pixels by specifying an upsampling parameter of 100
[output Greg] = dftregistration(fft2(f),fft2(g),100);
display(output),
%%
% The pixel shift error (difference between the true and obtained shifts)
% is 0.0016 and 0.0043 in the x and y directions respectively. Well within
% the expected accuracy of 0.01. Notice that using the conventional zero-padded
% FFT approach with the same accuracy, would
% require computation of a 25,600x25,600 FFT, which would require more than
% 19 Gbytes of RAM and a very comfortable chair.
%
% The following plot shows the reference image and the registered image.
figure(1);
subplot(1,2,1);
imshow(abs(f));
title('Reference image, f(x,y)')
subplot(1,2,2);
imshow(abs(ifft2(Greg)));
title('Registered image, gr(x,y)')
%% Disclaimer
% I have made every effort to evaluate the proper working of this code
% under many different conditions. However, it is the responsibility of
% the user to ensure that this registration code is adequate for their
% application.
%
% Feel free to e-mail me with questions or comments.


function p = predict(Theta1, Theta2, X)
%PREDICT Predict the label of an input given a trained neural network
%   p = PREDICT(Theta1, Theta2, X) outputs the predicted label of X given the
%   trained weights of a neural network (Theta1, Theta2)

% Useful values
m = size(X, 1);
num_labels = size(Theta2, 1);

% You need to return the following variables correctly
p = zeros(size(X, 1), 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned neural network. You should set p to a
%               vector containing labels between 1 to num_labels.
%
% Hint: The max function might come in useful. In particular, the max
%       function can also return the index of the max element, for more
%       information see 'help max'. If your examples are in rows, then, you
%       can use max(A, [], 2) to obtain the max for each row.
%

X = [ones(m, 1) X];
t1 = sigmoid(X * Theta1');
t1 = [ones(m, 1) t1];

t2 = sigmoid( t1 * Theta2');

[~, p] = max(t2, [], 2);

end


function M = morans_I(grid,W,s)
% PURPOSE: calculate global Moran's I for an input grid (matrix) by calculating all
%          local Moran's I for a given moving windows size using a weight matrix.
% -------------------------------------------------------------------
% USAGE: M = moransI(grid, W, s);
% where: [grid] is the matrix to analyse
%        [W] is the normalized weight matrix of the size the local Moran's
%            I will be calculated for (uneven sized!)
%        [s] is an optional flag to use zscores of input values for
%        calculation. Set to 'true' if zscores of local grid should be
%        calculated. Leave blank if not desired or input values are already
%        standardized.
% -------------------------------------------------------------------------
% OUTPUTS:
%        [M] matrix of all local Moran's I
% -------------------------------------------------------------------
% NOTES: Weight matrix needs to be 'moving window' style, not contiguity
%        matrix: Moran's I is calculated and weighted for neighbours to center cell.
%        Matrix needs to be normalized (weights sum to 1) and center cell weight
%        will be set to 0 if not already. Uses localmoran.m
%        -> Use nanmean(M(:)) to get the average global Moran's I.
%
% See Anselin (1995, 'LISA.', Geogr. Analysis 27(2),p.93f) for details on
% standardized variables in calculation of local Moran's I.
%
% EXAMPLE:  M = moransI(rand(20,20),ones(5,5),'true')
%
% Felix Hebeler, Geography Dept.,de University Zurich, March 2006.

%% Check if standardising should be done
if exist('s','var')
    if strcmp(s,'true');
        grid=zscore(grid);
    elseif strcmp(s,'false')
        %do nothing
    else
        error('Invalid option for s: set [true] to calculated zscores to determine local Moran or leave blank if values are already standardized.');
    end
end
if (mod(size(W,1),2)| mod(size(W,2),2))~=1
   error('Weight matrix W needs to have uneven size (eg. 5x5)')
end
%% Do local Morans I calc of the grid.
M = NaN(size(grid,1),size(grid,2));
wsx=floor(size(W,1)/2);
wsy=floor(size(W,2)/2);
% Do local morans I calc for moving window ws
for row=1+wsy:1:size(grid,1)-wsy;
    for col=1+wsx:1:size(grid,2)-wsx;
        M(row,col) = get_moran(grid(row-wsx:row+wsx,col-wsy:col+wsy),W);
    end
end

%% calculate local Moran's I
function m=get_moran(raster,W)
ncols= size(raster,2);
nrows= size(raster,1);
zi = raster(ceil(nrows/2),ceil(ncols/2));%  value of center cell (note: no weight applied!)
if (isnan(zi));
    m=NaN;
    return;
end;
raster=raster.* W; % Weight values in window
raster(ceil(nrows/2),ceil(ncols/2))=0; %set center cell to zero to exclude zi from sum
zj = nansum(raster(:)); % sum of weighted values excluding zi
m = zi * zj; % calculate local Moran's I and return


function [dcos] = triang2(pp,tt)
%TRIANG2 calc. enclosed angles for a 2-simplex triangulation
%embedded in the two-dimensional plane.
%   [ADEG] = TRIANG2(VERT,TRIA) returns the enclosed angles
%   associated with each triangle, where ADEG is a T-by-3
%   array of the angles subtended at each vertex, VERT is a
%   V-by-2 array of XY coordinates, and TRIA is a T-by-3 ar-
%   ray of vertex indexing, where each row defines a triang-
%   le, such that VERT(TRIA(II,1),:), VERT(TRIA(II,2),:) and
%   VERT(TRIA(II,3),:) are the coordinates of the II-TH tri-
%   angle. Angles are returned in degrees.
%
%   See also TRISCR2, TRIAREA, TRIBAL2

%   Darren Engwirda : 2017 --
%   Email           : de2363@columbia.edu
%   Last updated    : 08/07/2018

%---------------------------------------------- basic checks
    if (~isnumeric(pp) || ~isnumeric(tt) )
        error('triang2:incorrectInputClass' , ...
            'Incorrect input class.') ;
    end

%---------------------------------------------- basic checks
    if (ndims(pp) ~= +2 || ndims(tt) ~= +2 )
        error('triang2:incorrectDimensions' , ...
            'Incorrect input dimensions.');
    end
    if (size(pp,2)~= +2 || size(tt,2) < +3 )
        error('triang2:incorrectDimensions' , ...
            'Incorrect input dimensions.');
    end

    nnod = size(pp,1) ;

%---------------------------------------------- basic checks
    if (min(min(tt(:,1:3))) < +1 || ...
            max(max(tt(:,1:3))) > nnod )
        error('triang2:invalidInputs', ...
            'Invalid TRIA input array.') ;
    end

%----------------------------------- compute enclosed angles
    dcos = zeros(size(tt,1),3) ;

    ev12 = pp(tt(:,2),:)-pp(tt(:,1),:) ;
    ev23 = pp(tt(:,3),:)-pp(tt(:,2),:) ;
    ev31 = pp(tt(:,1),:)-pp(tt(:,3),:) ;

    lv11 = sqrt(sum(ev12.^2,2));
    lv22 = sqrt(sum(ev23.^2,2));
    lv33 = sqrt(sum(ev31.^2,2));

    ev12 = ev12 ./ ...
        lv11(:,ones(1,size(pp,2)));
    ev23 = ev23 ./ ...
        lv22(:,ones(1,size(pp,2)));
    ev31 = ev31 ./ ...
        lv33(:,ones(1,size(pp,2)));

    dcos(:,1) = sum(-ev12.*ev23,2);
    dcos(:,2) = sum(-ev23.*ev31,2);
    dcos(:,3) = sum(-ev31.*ev12,2);

    dcos(:,1) = max(-1.,dcos(:,1));
    dcos(:,1) = min(+1.,dcos(:,1));
    dcos(:,2) = max(-1.,dcos(:,2));
    dcos(:,2) = min(+1.,dcos(:,2));
    dcos(:,3) = max(-1.,dcos(:,3));
    dcos(:,3) = min(+1.,dcos(:,3));

    dcos = acos(dcos) * 180. / pi ;

end


function vecCross = crossMat(vec)
%
% Computes the cross-product matrix of a 3x1 vector
%
    if(size(vec,1) ~= 3 || size(vec,2) ~= 1)
        error('Input vector must be 3x1');
    end

    vecCross = [ 0, 		-vec(3), 	vec(2);
				 vec(3),	0,			-vec(1);
				 -vec(2),	vec(1),		0        ];
end


function [tfr,t,f]=tfrideal(iflaws,t,N,trace)
%TFRIDEAL Ideal TFR for given instantaneous frequency laws.
%	[TFR,T,F]=TFRIDEAL(IFLAWS,T,N,TRACE) generates the ideal
%	time-frequency representation corresponding to the
%	instantaneous frequency laws of the components of a signal.
%
%	IFLAWS : (M,P)-matrix where each column corresponds to
%		 the instantaneous frequency law of an (M,1)-signal,
%		 These P signals do not need to be present at the same time.
%		 The values of IFLAWS must be between 0 and 0.5.
%	T      : the time instant(s)      (default : 1:M).
%	N      : number of frequency bins (default : M).
%	TRACE  : if nonzero, the progression of the algorithm is shown
%                                         (default : 0).
%	TFR    : output time-frequency matrix, of size (N,length(t)).
%		 If nargout=0, a contour plot of TFR is automatically
%		 displayed on the screen.
%	F      : vector of normalized frequencies.
%
%	Example :
%         N=140; t=0:N-1; [x1,if1]=fmlin(N,0.05,0.3);
%         [x2,if2]=fmsin(70,0.35,0.45,60);
%         if2=[zeros(35,1)*NaN;if2;zeros(35,1)*NaN];
%         tfrideal([if1 if2]);
%
%	See also PLOTIFL, PLOTSID, and all the time-frequency
%        representations listed in the CONTENTS file (TFR*)

%	O. Lemoine, F. Auger - March, April 1996.
%	Copyright (c) 1996 by CNRS (France).
%
%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2 of the License, or
%  (at your option) any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; if not, write to the Free Software
%  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

if (nargin==0),
 error('at least one parameter required');
end;

[ifrow,ifcol]=size(iflaws);

if (nargin==1),
 t=1:ifrow; N=ifrow; trace=0;
elseif (nargin==2),
 N=ifrow; trace=0;
elseif (nargin==3),
 trace=0;
end;

[trow,tcol]=size(t);
if (trow~=1),
 error('T must only have one row');
end;

tfr=zeros(N,tcol);

if any(any(iflaws>0.5)) | any(any(iflaws<0)),
 error('The values of IFLAWS must be between 0 and 0.5');
end

if trace, disp('Ideal time-frequency distribution'); end;

for icol=1:tcol,
 if trace, disprog(icol,tcol,10); end;
 ti= t(icol);
 for fi=1:ifcol,
  if isnan(iflaws(ti,fi)),
   tfr(fi,icol)=NaN;
  else
   tfr(round(iflaws(ti,fi)*2*(N-1))+1,icol)=1;
  end
 end
end;

if (nargout==0),
 f=(0:N-1)/(2*N);
 axes(gca); contour(t,f,tfr,1,'k');
 xlabel('Time'); ylabel('Normalized frequency');
 title('Ideal time-frequency representation');
 grid;
elseif (nargout==3),
 f=(0.5*(0:N-1)/N)';
end;


function exactness_test015 ( )

%*****************************************************************************80
%
%% EXACTNESS_TEST015 tests Fejer Type 1 rules for Legendre integrals.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 May 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'EXACTNESS_TEST015\n' );
  fprintf ( 1, '  Test Fejer Type 1 rules on Legendre integrals.\n' );
  fprintf ( 1, '  Density function rho(x) = 1.\n' );
  fprintf ( 1, '  Region: -1 <= x <= +1.\n' );
  fprintf ( 1, '  Exactness: N   for N odd,\n' );
  fprintf ( 1, '             N-1 for N even.\n' );

  for n = 1 : 5

    [ x, w ] = fejer1_set ( n );
    if ( mod ( n, 2 ) == 1 )
      p_max = n + 1;
    else
      p_max = n;
    end
    legendre_exactness ( n, x, w, p_max );

  end

  return
end


function [f, e] = fv(B, nk, thmax, noplot)
%FV     Field of values (or numerical range).
%       FV(A, NK, THMAX) evaluates and plots the field of values of the
%       NK largest leading principal submatrices of A, using THMAX
%       equally spaced angles in the complex plane.
%       The defaults are NK = 1 and THMAX = 16.
%       (For a `publication quality' picture, set THMAX higher, say 32.)
%       The eigenvalues of A are displayed as `x'.
%       Alternative usage: [F, E] = FV(A, NK, THMAX, 1) suppresses the
%       plot and returns the field of values plot data in F, with A's
%       eigenvalues in E.   Note that NORM(F,INF) approximates the
%       numerical radius,
%                 max {abs(z): z is in the field of values of A}.

%       Theory:
%       Field of values FV(A) = set of all Rayleigh quotients. FV(A) is a
%       convex set containing the eigenvalues of A.  When A is normal FV(A) is
%       the convex hull of the eigenvalues of A (but not vice versa).
%               z = x'Ax/(x'x),  z' = x'A'x/(x'x)
%               => REAL(z) = x'Hx/(x'x),   H = (A+A')/2
%       so      MIN(EIG(H)) <= REAL(z) <= MAX(EIG(H)),
%       with equality for x = corresponding eigenvectors of H.  For these x,
%       RQ(A,x) is on the boundary of FV(A).
%
%       Based on an original routine by A. Ruhe.
%
%       References:
%       R. A. Horn and C. R. Johnson, Topics in Matrix Analysis, Cambridge
%            University Press, 1991; sec. 1.5.
%       A. S. Householder, The Theory of Matrices in Numerical Analysis,
%            Blaisdell, New York, 1964; sec. 3.3.
%       C. R. Johnson, Numerical determination of the field of values of a
%            general complex matrix, SIAM J. Numer. Anal., 15 (1978),
%            pp. 595-602.

if nargin < 2 | isempty(nk), nk = 1; end
if nargin < 3 | isempty(thmax), thmax = 16; end
thmax = thmax - 1;  % Because code below uses thmax + 1 angles.

iu = sqrt(-1);
[n, p] = size(B);
if n ~= p, error('Matrix must be square.'), end
f = [];
z = zeros(2*thmax+1,1);
e = eig(B);

% Filter out cases where B is Hermitian or skew-Hermitian, for efficiency.
if isequal(B,B')

   f = [min(e) max(e)];

elseif isequal(B,-B')

   e = imag(e);
   f = [min(e) max(e)];
   e = iu*e; f = iu*f;

else

for m = 1:nk

   ns = n+1-m;
   A = B(1:ns, 1:ns);

   for i = 0:thmax
      th = i/thmax*pi;
      Ath = exp(iu*th)*A;               % Rotate A through angle th.
      H = 0.5*(Ath + Ath');             % Hermitian part of rotated A.
      [X, D] = eig(H);
      [lmbh, k] = sort(real(diag(D)));
      z(1+i) = rq(A,X(:,k(1)));         % RQ's of A corr. to eigenvalues of H
      z(1+i+thmax) = rq(A,X(:,k(ns)));  % with smallest/largest real part.
   end

   f = [f; z];

end
% Next line ensures boundary is `joined up' (needed for orthogonal matrices).
f = [f; f(1,:)];

end
if thmax == 0; f = e; end

if nargin < 4

   ax = cpltaxes(f);
   plot(real(f), imag(f))      % Plot the field of values
   axis(ax);
   axis('square');

   hold on
   plot(real(e), imag(e), 'x')    % Plot the eigenvalues too.
   hold off

end

function z = rq(A,x)
%RQ      Rayleigh quotient.
%        RQ(A,x) is the Rayleigh quotient of A and x, x'*A*x/(x'*x).

z = x'*A*x/(x'*x);


function y = geo_mean( x, dim, w )

%GEO_MEAN   Geometric mean.
%   Y=GEO_MEAN(X), where X is a vector, computes the geometrix mean of X. If any
%   of the elements of X are negative, then Y=-Inf. Otherwise, it is equivalent
%   to Y=PROD(X).^(1/LENGTH(X)). All elements must be real.
%
%   For matrices, GEO_MEAN(X) is a row vector containing the geometric means of
%   the columns. For N-D arrays, GEO_MEAN(X) is an array of the geometric means
%   taken along the first non-singleton dimension of X.
%
%   GEO_MEAN(X,DIM) takes the geometric mean along the dimension DIM of X.
%
%   GEO_MEAN(X,DIM,W), where W is a vector of nonnegative integers, computes a
%   weighted geometric mean Y = PROD(X.^W)^(1/SUM(W)). This is more efficient
%   than replicating the values of X W times. Note that W must be a vector,
%   even if X is a matrix, and its length must be the same as SIZE(X,DIM).
%
%   Disciplined convex programming information:
%       GEO_MEAN is concave  and nondecreasing; therefore, when used in CVX
%       specifications, its argument must be concave.

%
% Check arguments
%

error( nargchk( 1, 3, nargin ) );
if ~isreal( x ),
    error( 'First argument must be real.' );
elseif nargin < 2,
    dim = cvx_default_dimension( size( x ) );
elseif ~cvx_check_dimension( dim ),
    error( 'Second argument must be a positive integer.' );
end
sx = size( x );
nx = sx( dim );

%
% Third argument check
%

if nargin < 3 || isempty( w ),
    w = [];
elseif numel( w ) ~= length( w ) || ~isnumeric( w ) || ~isreal( w ) || any( w < 0 ) || any( w ~= floor( w ) ),
    error( 'Third argument must be a vector of nonnegative integers.' );
elseif length( w ) ~= nx,
    error( 'Third argument must be a vector of length %d.', nx );
else
    w = reshape( w, 1, nx );
end

if nx == 0,
    sx( dim ) = 1;
    y = ones( sx );
else
    if nx == 1,
        y = x;
    elseif isempty( w ) || ~any( diff( w ) ),
        y = exp( sum( log( max( x, realmin ) ), dim ) * ( 1 / nx ) );
    elseif dim == 1,
        y = exp( w * log( max( x, realmin ) ) * ( 1 / sum( w ) ) );
    else
        pvec = [ dim, 1 : dim - 1, dim + 1 : ndims( x ) ];
        y = ipermute( exp( w * log( max( permute( x, pvec ), realmin ) ) * ( 1 / sum( w ) ) ), pvec );
    end
    xmin = min( x, [], dim );
    y( xmin <  0 ) = -Inf;
    y( xmin == 0 ) = 0;
end

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


%--- help for rsindex ---
%
% RSINDEX Relative Strength Index (RSI).
%
%  Syntax:
%
%    index = rsindex(Data)
%    index = rsindex(Data,WindowSize)
%
%  Description:
%
%    RSINDEX calculates the Relative Strength Index (RSI) from the series of
%    closing stock prices. By default, RSI values are based on a 14-period window.
%
%  Input Argument:
%
%    Data    - A vector, table, or timetable. For matrix input, Data is an
%              M-by-1 vector of closing prices. Timetables and tables with M
%              rows contain variables named 'Close' (case insensitive).
%
%  Optional Input Argument:
%
%    WindowSize          - Positive integer scalar indicating the moving window
%                          size for relative strength index. The default is 14.
%
%  Output Argument:
%
%    index   - Relative StrengthIndex with the same number of rows (M) and
%              type as the input data.
%
%  Note:
%    The RS factor is calculated by dividing the average of the gains by the
%    average of the losses within a specified period.
%
%          RS = (average gains) / (average losses)
%
%    Also, the first value of RSI, RSI(1), is a NaN in order to preserve the
%    dimensions of CLOSEP.
%
%  Example:
%               load SimulatedStock.mat
%               index = rsindex(TMW)
%               index = rsindex(TMW,14)
%
%    See also NEGVOLIDX, POSVOLIDX.
%
%    Reference: Murphy, John J., Technical Analysis of the Futures Market,
%               New York Institute of Finance, 1986, pp. 295-302
%
%    Reference page in Doc Center
%       doc rsindex
%
%    Other functions named rsindex
%
%       fints/rsindex
%


function p = part_table ( n )

%*****************************************************************************80
%
%% PART_TABLE tabulates the number of partitions of N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Donald Kreher, Douglas Simpson,
%    Combinatorial Algorithms,
%    CRC Press, 1998,
%    ISBN: 0-8493-3988-X,
%    LC: QA164.K73.
%
%  Parameters:
%
%    Input, integer N, the integer to be partitioned.
%    N must be positive.
%
%    Output, integer P(1:N+1), P(I+1) is the number of partitions of I.
%
  offset = 1;

  p = zeros ( n + 1, 1 );

  p(0+offset) = 1;
  p(1+offset) = 1;

  for i = 2 : n

    sign = 1;
    psum = 0;
    w = 1;
    j = 1;
    wprime = w + j;

    while ( w < n )

      if ( 0 <= i - w )
        if ( sign == 1 )
          psum = psum + p(i-w+offset);
        else
          psum = psum - p(i-w+offset);
        end
      end

      if ( wprime <= i )

        if ( sign == 1 )
          psum = psum + p(i-wprime+offset);
        else
          psum = psum - p(i-wprime+offset);
        end

      end

      w = w + 3 * j + 1;
      j = j + 1;
      wprime = w + j;
      sign = - sign;

    end

    p(i+offset) = psum;

  end

  return
end


function f = f_function ( x )

%*****************************************************************************80
%
%% F_FUNCTION evaluates the right hand side of the finite element system.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 March 2011
%
%  Author:
%
%    Jeff Borggaard, John Burkardt, Catalin Trenchea, Clayton Webster
%
%  Parameters:
%
%    Input, real X(*), the evaluation points.
%
%    Output, real F(*), the function values.
%
  f = - 15*x.^4 + 3*x.^2 - 6*x;

  return
end


function [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
% minboundrect: Compute the minimal bounding rectangle of points in the plane
% usage: [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
%
% arguments: (input)
%  x,y - vectors of points, describing points in the plane as
%        (x,y) pairs. x and y must be the same lengths.
%
%  metric - (OPTIONAL) - single letter character flag which
%        denotes the use of minimal area or perimeter as the
%        metric to be minimized. metric may be either 'a' or 'p',
%        capitalization is ignored. Any other contraction of 'area'
%        or 'perimeter' is also accepted.
%
%        DEFAULT: 'a'    ('area')
%
% arguments: (output)
%  rectx,recty - 5x1 vectors of points that define the minimal
%        bounding rectangle.
%
%  area - (scalar) area of the minimal rect itself.
%
%  perimeter - (scalar) perimeter of the minimal rect as found
%
%
% Note: For those individuals who would prefer the rect with minimum
% perimeter or area, careful testing convinces me that the minimum area
% rect was generally also the minimum perimeter rect on most problems
% (with one class of exceptions). This same testing appeared to verify my
% assumption that the minimum area rect must always contain at least
% one edge of the convex hull. The exception I refer to above is for
% problems when the convex hull is composed of only a few points,
% most likely exactly 3. Here one may see differences between the
% two metrics. My thanks to Roger Stafford for pointing out this
% class of counter-examples.
%
% Thanks are also due to Roger for pointing out a proof that the
% bounding rect must always contain an edge of the convex hull, in
% both the minimal perimeter and area cases.
%
%
% See also: minboundcircle, minboundtri, minboundsphere
%
%
% default for metric
if (nargin<3) || isempty(metric)
  metric = 'a';
elseif ~ischar(metric)
  error 'metric must be a character flag if it is supplied.'
else
  % check for 'a' or 'p'
  metric = lower(metric(:)');
  ind = strmatch(metric,{'area','perimeter'});
  if isempty(ind)
    error 'metric does not match either ''area'' or ''perimeter'''
  end

  % just keep the first letter.
  metric = metric(1);
end

% preprocess data
x=x(:);
y=y(:);

% not many error checks to worry about
n = length(x);
if n~=length(y)
  error 'x and y must be the same sizes'
end

% if var(x)==0

% start out with the convex hull of the points to
% reduce the problem dramatically. Note that any
% points in the interior of the convex hull are
% never needed, so we drop them.
if n>3

    %%%%%%%%%%%%%%%%%%%%%%%%%
    if (var(x)== 0|| var(y)==0)
        if var(x)== 0
            x = [x-1;x(1); x+1 ];
            y = [y ;y(1);y];
            flag = 1;
        else
            y = [y-1;y(1); y+1 ];
            x = [x ;x(1);x];
            flag = 1;
        end

    else
        flag = 0;
     %%%%%%%%%%%%%%%%%%%%%%
    edges = convhull(x,y);  % 'Pp' will silence the warnings

    end

  % exclude those points inside the hull as not relevant
  % also sorts the points into their convex hull as a
  % closed polygon

  %%%%%%%%%%%%%%%%%%%%
  if flag == 0
  %%%%%%%%%%%%%%%%%%%%

  x = x(edges);
  y = y(edges);
  %%%%%%%%%%%%%%%%%%
  end
  %%%%%%%%%%%%%
  % probably fewer points now, unless the points are fully convex
  nedges = length(x) - 1;
elseif n>1
  % n must be 2 or 3
  nedges = n;
  x(end+1) = x(1);
  y(end+1) = y(1);
else
  % n must be 0 or 1
  nedges = n;
end

% now we must find the bounding rectangle of those
% that remain.

% special case small numbers of points. If we trip any
% of these cases, then we are done, so return.
switch nedges
  case 0
    % empty begets empty
    rectx = [];
    recty = [];
    area = [];
    perimeter = [];
    return
  case 1
    % with one point, the rect is simple.
    rectx = repmat(x,1,5);
    recty = repmat(y,1,5);
    area = 0;
    perimeter = 0;
    return
  case 2
    % only two points. also simple.
    rectx = x([1 2 2 1 1]);
    recty = y([1 2 2 1 1]);
    area = 0;
    perimeter = 2*sqrt(diff(x).^2 + diff(y).^2);
    return
end
% 3 or more points.

% will need a 2x2 rotation matrix through an angle theta
Rmat = @(theta) [cos(theta) sin(theta);-sin(theta) cos(theta)];

% get the angle of each edge of the hull polygon.
ind = 1:(length(x)-1);
edgeangles = atan2(y(ind+1) - y(ind),x(ind+1) - x(ind));
% move the angle into the first quadrant.
edgeangles = unique(mod(edgeangles,pi/2));

% now just check each edge of the hull
nang = length(edgeangles);
area = inf;
perimeter = inf;
met = inf;
xy = [x,y];
for i = 1:nang
  % rotate the data through -theta
  rot = Rmat(-edgeangles(i));
  xyr = xy*rot;
  xymin = min(xyr,[],1);
  xymax = max(xyr,[],1);

  % The area is simple, as is the perimeter
  A_i = prod(xymax - xymin);
  P_i = 2*sum(xymax-xymin);

  if metric=='a'
    M_i = A_i;
  else
    M_i = P_i;
  end

  % new metric value for the current interval. Is it better?
  if M_i<met
    % keep this one
    met = M_i;
    area = A_i;
    perimeter = P_i;

    rect = [xymin;[xymax(1),xymin(2)];xymax;[xymin(1),xymax(2)];xymin];
    rect = rect*rot';
    rectx = rect(:,1);
    recty = rect(:,2);
  end
end
% get the final rect

% all done

end % mainline end


function prob_test005 ( )

%*****************************************************************************80
%
%% TEST005 tests ANGLIT_MEAN, ANGLIT_SAMPLE, ANGLIT_VARIANCE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 April 2009
%
%  Author:
%
%    John Burkardt
%
  nsample = 1000;
  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST005\n' );
  fprintf ( 1, '  For the Anglit PDF:\n' );
  fprintf ( 1, '  ANGLIT_MEAN computes the mean;\n' );
  fprintf ( 1, '  ANGLIT_SAMPLE samples;\n' );
  fprintf ( 1, '  ANGLIT_VARIANCE computes the variance.\n' );

  mean = anglit_mean ( );
  variance = anglit_variance ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  PDF mean =     %14f\n', mean );
  fprintf ( 1, '  PDF variance = %14f\n', variance );

  for i = 1 : nsample
    [ x(i), seed ] = anglit_sample ( seed );
  end

  mean = r8vec_mean ( nsample, x );
  variance = r8vec_variance ( nsample, x );
  xmax = max ( x(1:nsample) );
  xmin = min ( x(1:nsample) );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Sample size =     %6d\n', nsample );
  fprintf ( 1, '  Sample mean =     %14f\n', mean );
  fprintf ( 1, '  Sample variance = %14f\n', variance );
  fprintf ( 1, '  Sample maximum =  %14f\n', xmax );
  fprintf ( 1, '  Sample minimum =  %14f\n', xmin );

  return
end


function a = vand1_inverse ( n, x )

%*****************************************************************************80
%
%% VAND1_INVERSE returns the inverse of the VAND1 matrix.
%
%  Formula:
%
%    A(I,J) = coefficient of X^(J-1) in I-th Lagrange basis polynomial.
%
%  Example:
%
%    N = 5,
%    X = ( 2, 3, 4, 5, 6 )
%
%     15.00  -14.25    4.96  -0.75   0.04
%    -40.00   44.67  -17.33   2.83  -0.17
%     45.00  -54.00   22.75  -4.00   0.25
%    -24.00   30.00  -13.33   2.50  -0.17
%      5.00   -6.42    2.96  -0.58   0.04
%
%  Properties:
%
%    The sum of the entries of A is
%
%      1 - product ( 1 <= I <= N ) ( 1 - 1 / X(I) ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 October 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real X(N), the values that define A.
%
%    Output, real A(N,N), the matrix.
%
  a = zeros ( n, n );

  for i = 1 : n
    for j = 1 : n
      if ( j == 1 )
        a(i,j) = 1.0;
      else
        a(i,j) = 0.0;
      end
    end
  end

  for i = 1 : n

    index = 0;

    for k = 1 : n

      if ( k ~= i )

        index = index + 1;

        for j = index + 1: - 1 : 1

          a(i,j) = - x(k) * a(i,j) / ( x(i) - x(k) );

          if ( 1 < j )
            a(i,j) = a(i,j) + a(i,j-1) / ( x(i) - x(k) );
          end

        end

      end

    end

  end

  return
end


function x=isleap(Year)
%ISLEAP True for leap year.
%     ISLEAP(Year) returns 1 if Year is a leap year and 0 otherwise.
%     ISLEAP is only set for gregorian calendar, so Year >= 1583
%
% Syntax: 	ISLEAP(YEAR)
%
%     Inputs:
%           YEAR - Year of interest (default = current year).
%           You can input a vector of years.
%     Outputs:
%           Logical vector.
%
%      Example:
%
%           Calling on Matlab the function: isleap
%
%           Answer is: 0
%
%
%           Calling on Matlab the function: x=isleap([2007 2008])
%
%           Answer is:
%           x = 0 1
%
%           Created by Giuseppe Cardillo
%           giuseppe.cardillo-edta@poste.it
%           Modified after Simon Jan suggestions
% To cite this file, this would be an appropriate format:
% Cardillo G. (2007) Isleap: a simple routine to test if a year is a leap
% year.
% http://www.mathworks.com/matlabcentral/fileexchange/14172

%Input Error handling
switch nargin
    case 0
         c=clock; Year=c(1); clear c
    case 1
        if ~isvector(Year) || ~all(isnumeric(Year)) || ~all(isfinite(Year)) || isempty(Year)
            error('Warning: Year values must be numeric and finite')
        end
        if ~isequal(Year,round(Year))
            error('Warning: Year values must be integer')
        end
        L=Year-1583;
        if L(L<0)
            error('Warning: Every value of Year must be >1582')
        end
    otherwise
        error('stats:Isleap:TooMuchInputs','Year must be a scalar or a vector.');
end

% The Gregorian calendar has 97 leap years every 400 years:
% Every year divisible by 4 is a leap year.
% However, every year divisible by 100 is not a leap year.
% However, every year divisible by 400 is a leap year after all.
% So, 1700, 1800, 1900, 2100, and 2200 are not leap years,
% but 1600, 2000, and 2400 are leap years.
x = ~mod(Year, 4) & (mod(Year, 100) | ~mod(Year, 400));
return


function ex2 (n)
%EX2: create an n-by-n 2D mesh, four different ways

% Example:
%   ex2
% See also: cs_demo

%   Copyright 2006-2007, Timothy A. Davis.
%   http://www.cise.ufl.edu/research/sparse

if (nargin < 1)
    n = 30 ;
end

subplot (1,2,1) ;

% method 1: create an n-by-n 2D mesh for the 2nd difference operator
tic
ii = zeros (5*n^2, 1) ;
jj = zeros (5*n^2, 1) ;
xx = zeros (5*n^2, 1) ;
k = 1 ;
for j = 0:n-1
    for i = 0:n-1
        s = j*n+i + 1 ;
        ii (k:k+4) = [(j-1)*n+i j*n+(i-1) j*n+i j*n+(i+1) (j+1)*n+i ] + 1 ;
        jj (k:k+4) = [s s s s s] ;
        xx (k:k+4) = [-1 -1 4 -1 -1] ;
        k = k + 5 ;
    end
end

% remove entries beyond the boundary
keep = find (ii >= 1 & ii <= n^2 & jj >= 1 & jj <= n^2) ;
ii = ii (keep) ;
jj = jj (keep) ;
xx = xx (keep) ;
A = sparse (ii,jj,xx) ;
t1 = toc ; disp (t1) ;
% subplot (2,2,1) ;
spy (A)
title (sprintf ('%d-by-%d 2D mesh\n', n, n)) ;

% method 2, using no for loops
tic
nn = 1:n^2 ;
i2 = [nn-n ; nn-1 ; nn ; nn+1 ; nn+n] ;
j2 = repmat (nn, 5, 1) ;
x2 = repmat ([-1 -1 4 -1 -1]', 1, n^2) ;
keep = find (i2 >= 1 & i2 <= n^2 & j2 >= 1 & j2 <= n^2) ;
i2 = i2 (keep) ;
j2 = j2 (keep) ;
x2 = x2 (keep) ;
C = sparse (i2,j2,x2) ;
t2 = toc ; disp (t2) ;

% subplot (2,2,2) ; plot (j2) ;
% title ('2D fast j2') ;
disp (A-C) ;

any (ii-i2)
any (jj-jj)

% method 3: create an n-by-n-by-n 3D mesh for the 2nd difference operator
tic
[A, keep, ii, jj, xx] = mesh3d1 (n) ;
ii = ii (keep) ;
jj = jj (keep) ;
xx = xx (keep) ;
t3 = toc ; disp (t3) ;
tic
E = sparse (ii,jj,xx) ;
t3b = toc ; disp (t3b) ;
subplot (1,2,2) ; spy (E) ;
title (sprintf ('%d-by-%d-by-%d 3D mesh\n', n, n, n)) ;

% method 4, using no for loops
tic
nn = 1:n^3 ;
i2 = [nn-n^2 ; nn-n ; nn-1 ; nn ; nn+1 ; nn+n ; nn+n^2] ;
j2 = repmat (nn, 7, 1) ;
x2 = repmat ([-1 -1 -1 6 -1 -1 -1]', 1, n^3) ;
keep = find (i2 >= 1 & i2 <= n^3 & j2 >= 1 & j2 <= n^3) ;
i2 = i2 (keep) ;
j2 = j2 (keep) ;
x2 = x2 (keep) ;
t4 = toc ; disp (t4) ;
tic
F = sparse (i2,j2,x2) ;
t4b = toc ; disp (t4b) ;
disp (E-F) ;


% EX_MAXWELL_SRC_PERIODIC_SQUARE: solve Maxwell source problem in the unit square.

% 1) PHYSICAL DATA OF THE PROBLEM
clear problem_data
% Physical domain, defined as NURBS map given in a text file
problem_data.geo_name = 'geo_square.txt';
% The domain must also have the right continuity conditions on the periodic
%  sides, otherwise the convergence rate may deteriorate.
%  See the example in ex_laplace_square_periodic.

% Type of boundary conditions
problem_data.nmnn_sides     = [];
problem_data.drchlt_sides   = [3 4];
problem_data.periodic_directions = [1];

% Physical parameters
problem_data.c_stiff = @(x, y) ones(size(x));
problem_data.c_mass  = @(x, y) pi^2 * ones(size(x));

% Source and boundary terms
problem_data.f = @(x, y) cat(1, zeros (1, size (x, 1), size (x, 2)), ...
                             reshape (17*pi^2*sin(4*pi*x), [1, size(x)]));
problem_data.g = @(x, y, ind) zeros (2, size (x, 1), size (x, 2));
problem_data.h = @(x, y, ind) zeros (2, size (x, 1), size (x, 2));

% Exact solution (optional)
problem_data.uex     = @(x, y) cat(1, zeros (1, size (x, 1), size (x, 2)), ...
                                      reshape ( sin(4*pi*x), [1, size(x)]));
problem_data.curluex = @(x, y) 4*pi*cos(4*pi*x);

% 2) CHOICE OF THE DISCRETIZATION PARAMETERS
clear method_data
method_data.degree     = [3 3];     % Degree of the bsplines
method_data.regularity = [2 2];     % Regularity of the splines
method_data.nsub       = [9 9];   % Number of subdivisions
method_data.nquad      = [4 4];     % Points for the Gaussian quadrature rule

% 3) CALL TO THE SOLVER
[geometry, msh, space, u] = solve_maxwell_src (problem_data, method_data);

% 4) POST-PROCESSING
vtk_pts = {linspace(0, 1, 30), linspace(0, 1, 30)};
% 4.1) EXPORT TO PARAVIEW
output_file = 'maxwell_square_periodic_Deg3_Reg2_Sub8';
fprintf ('The result is saved in the file %s \n \n', output_file);
sp_to_vtk (u, space, geometry, vtk_pts, output_file, 'u')

% 4.2) Plot in Matlab. Comparison with the exact solution
[eu, F] = sp_eval (u, space, geometry, vtk_pts);
[X, Y]  = deal (squeeze(F(1,:,:)), squeeze(F(2,:,:)));
eu2     = problem_data.uex (X, Y);

subplot(1,2,1)
quiver (X, Y, squeeze(eu(1,:,:)), squeeze(eu(2,:,:)))
axis equal tight
title('Computed solution')
ylim([0,1]); xlim([0,1]);
subplot(1,2,2)
quiver (X, Y, squeeze(eu2(1,:,:)), squeeze(eu2(2,:,:)))
axis equal tight
title('Exact solution')
ylim([0,1]); xlim([0,1]);

[error_hcurl, error_l2] = ...
    sp_hcurl_error (space, msh, u, problem_data.uex, problem_data.curluex)


%% Defining Tensorial Properties
%
% Physical laws describe the relationship between physical properties. The
% most simplest laws are linear ones and are of the form
%
% $$ y = \mathbf A x $$
%
% where $x$ and $y$ are the physical properties and $\mathbf A$ is a
% material constant. In a typical example $y$ could be the force applied to
% a spring, $x$ the displacement and $A$ describes the stiffnes of the
% spring which is essentially Hooks law.
%
% As soon as we consider more general forces and displacements they can not
% be described anymore by scalar numbers $x$ and $y$ but vectors or
% matrices are required. In its most general form the displacment is
% describes by a <strainTensor.html strain matrix> $\sigma_{ij}$ and the
% force is described by a stiffness matrix $\varepsilon_{kl}$. In this setting
% the linear relationship between the two matrices is described by the
% <complianceTensor.complianceTensor.html compliance tensor> $\mathbf
% C_{ijkl}$ which can be seen as a 4 dimensional generalization of a matrix.
%
% More, general a tensor of rank $r$ is a "matrix" of dimension $r$. If
% $r=0$ we speek of scalars, if $r=1$ these are vectors and for $r=2$ they
% are classical $3 \times 3$ matrices.
%
% In the following we explain how tensors of arbitrary rank can be defined
% in MTEX. Independent of the rank any tensor is represented in MTEX by a
% variable of type @tensor.
%
%
%% Scalars (tensors of zero rank)
%
% In physics, properties like temperature or density are not connected
% to any specific direction of the body they are measured. These
% non-directional physical quantities are called scalars, and they are
% defined by a single number. In MTEX, a scalar is defined by:

M = 5;
t = tensor(M,'rank',0)

%% Vectors (tensors of first rank)
%
% In contrast to scalars, other physical quantities can only be defined in
% reference to a specific direction. If we need to specify completely the
% mechanical force acting into a point for example, we need to specify
% the magnitude and its direction. As an alternative, we can choose three
% mutually perpendicular axes (A1,A2 and A3) and give the vector components
% along them. In MTEX, this is done by:

t = tensor([1;2;3],'rank',1)

%%
% where 1, 2 and 3 are the components related to the axes A1, A2 and A3.
% As rank 1 tensors are essentialy vectors we can freely convert tensors to
% @vector3d and vice verca.

% define a tensor from a vector
t = tensor(vector3d.X)

% convert a tensor into a vector
vector3d(t)

%% Matrices (tensors of second rank)
%
% We have now to expand the idea of a vector to three-dimensional space.
% Let's take the example of stress (force per unit of area). Imagine a cube
% of material subjected to load as shown below. As can be seen, one can
% measure ther stresses in this cube in various directions, and in various
% planes. These measurements will for a second rank sensor, where each
% component is associated with a pair of axes, taken in an specific order.
% The generalized second rank stress tensor can be written as
%
% $$
% \sigma_{ij} =
% \left[\begin{array}{ccc}
% \sigma_{11} & \sigma_{12} & \sigma_{13}  \\
% \sigma_{21} & \sigma_{22} & \sigma_{23}  \\
% \sigma_{31} & \sigma_{32} & \sigma_{33}  \\
% \end{array}\right]
% $$
%
% In MTEX, a second-rank tensor where only the main diagonal components are
% of interest is defined as

t = tensor(diag([1,2,3]), 'rank',2)

%%
% If all the components are of interest, the definition is as follow

M = [1     0.75  0.5;...
     0.75  1     0.25;...
     0.5   0.25  1];

t = tensor(M,'rank',2)

%% Tensors (tensors of third rank)
%
% Smart materials are materials that have one or more properties that
% change significantly under external stimuli. A typical example is the
% voltage resulting to applied stress that certain materials have, named
% piezoeletric effect. This property is described as a third rank tensor
% that relates induced electric displacement vector to the second-order
% stress tensor. This is expressed in the form $P_i=d_{ijk} \sigma_{jk}$.
% In MTEX, a third rank tensor can be described as

M =[[-1.9222  1.9222    0   -0.1423     0         0    ];...
    [   0        0      0       0     0.1423    3.8444];...
    [   0        0      0       0       0         0    ]];

t = tensor(M,'rank',3)

%% Tensors (tensors of fourth rank)
%
% Fourth rank tensors are tensors that describe the relation between 2
% second rank tensors. A typical example is the tensor describing the
% elastic properties of materials, which translate the linear relationship
% between the second rank stress and infinitesimal strain tensors. The
% Hooke's Law describing the shape changes in a material subject to stress
% can be written as $\sigma_{ij}=c_{ijkl} \epsilon_{kl}$, where $c_{ijkl}$
% is a fourth rank tensor.
%
% The four indices (ijkl) of the elastic tensor have values between 1 and
% 3, so that there are $3^4=81$ coefficients. As the stress and strain
% tensors are symmetric, both stress and strain second rank tensors only
% have 6 independent values rather than 9. In addition, crystal symmetry
% reduces even more the number of independent components on the elastic
% tensor, from 21 in the case of triclinic phases, to 3 in the case of
% cubic materials. In MTEX, a fourth rank tensor can be defined as:

M = [[320   50  50   0     0     0];...
    [  50  320  50   0     0     0];...
    [  50   50 320   0     0     0];...
    [   0    0   0  64     0     0];...
    [   0    0   0   0    64     0];...
    [   0    0   0   0     0    64]];

C = tensor(M,'rank',4)

%%
% Note the repetition in values in this matrix is related to crystal
% symmetry, in this case, a cubic example, where only $C_{11}$, $C_{12}$
% and $C_{44}$ are independent components.
%
%% Specific tensors
%
% MTEX includes specific classes for the following tensors.
%
% || *name* || *rank* || *symbol* || *name* || *rank* || *symbol* ||
% || @complianceTensor || 4 || $S_{ijkl}$ || @stiffnessTensor || 4 || $C_{ijkl}$ ||
% || @strainTensor || 2 || $\sigma_{ij}$  || @stressTensor || 2 || $\varepsilon_{ij}$ ||
% || @strainRateTensor || 2 || $E$ || @velocityGradientTensor || 2 || $L$ ||
% || @curvatureTensor || 2 || $\kappa_{ij}$ || @deformationGradientTensor || 2 || $F$ ||
% || @refractiveIndexTensor || 2 || $\chi$ || @ChristoffelTensor || 2 || $M_{ij}$ ||
% || @dislocationDensityTensor || 2 || $\alpha$  || <SchmidTensor.html |SchmidTensor|> || 2 || $M_{ij}$ ||
% || <tensor.leviCivita.html |leviCivita|> || 3 || $\varepsilon_{ijk}$ || @spinTensor || 2 || $\Omega$ ||
%
% Those specific tensors are defined by the syntax

M = [0 0 0;...
  0 0 0; ...
  0 0 1];

e = strainTensor(M)

%%
% In many cases shortcuts exist like

e = stressTensor.uniaxial(vector3d.Z)

%%
% The advantage of using these specific tensor classes is that some tensor
% operations like <stressTensor/calcShearStress.html |calcShearStress(e)|>
% are defined only for specific tensor classes.
%
%% Predefined tensors
%
% For certain applications, one may want to have a tensor where all the
% components are 1. In MTEX this is computed as

t = tensor.ones('rank',2)

%%
% *Identity tensor*
%
% The Identity tensor is a second order tensor that has ones n the main
% diagonal and zeros otherwise. The identity matrix has some special
% properties, including (i) When multiplied by itself, the result is itself
% and (ii) rows and columns are linearly independent. In MTEX, this matrix
% can be computed as

t = tensor.eye('rank',2)

%%
% *Random tensors*
%
% One can also define a tensor in which the components are pseudorandom, by
% using the function |<tensor.rand.html tensor.rand>|

t = tensor.rand('rank',2)

%%
% *The Levi Civita tensor*
%
% The Levi-Civita symbol $\epsilon_{ijk}$ is a third rank tensor and is
% defined by 0, if $i=j$, $j=k$ or $k=1$, by 1, if $(i,j,k)=(1,2,3)$,
% $(2,3,1)$ or $(3,1,2)$ and by $-1$, if $(i,j,k)=(3,2,1)$, $(1,3,2)$ or
% $(2,1,3)$. The Levi-Civita symbol allows the cross product of two vectors
% in 3D Euclidean space and the determinant of a square matrix to be
% expressed in Einstein's index notation. With MTEX the Levi Civita tensor
% is expressed as

t = tensor.leviCivita


function [yUpdate, PInvUpdate]=infoFilterUpdate(yPred,PInvPred,z,R,H)
%%INFOFILTERUPDATE Perform the measurement update step in the standard
%                  linear information filter. Using an information filter
%                  means that instead of propagating a state x and its
%                  covariance matrix P, one propagates inv(P) and
%                  y=inv(P)*x.
%
%INPUTS: yPred The xDimX1 predicted information state. The information
%              state is the inverse covariance matrix times the target
%              state.
%     PInvPred The xDimXxDim inverse of the predicted state covariance
%              matrix.
%            z The zDimX1 vector measurement.
%            R The zDimXzDim measurement covariance matrix. This must be
%              positive definite.
%            H The zDimXxDim measurement matrix for a linear measurement
%              model. That is z=H*x+w, where w is measurement noise having
%              covariance matrix R.
%
%OUTPUTS: yUpdate The xDimX1 updated (posterior) information state vector.
%      PInvUpdate The updated xDimXxDim inverse state covariance matrix.
%
%The information filter is algebraically equivalent to the standard linear
%Kalman filter, but allows for track propagation with very uncertain
%states, such as when starting tracks. The implementation of the update
%given here is from the flow chart given in Appendix H of [1].
%
%The standard information filter has the implied linear measurement
%equation
%z=H*x+w
%where z is the measurement, w is the zero-mean Gaussian measurement noise
%with covariance matrix R and x is the true state. However, instead of
%propagating the true state x with its covariance matrix P, the information
%filter propagates
%y=inv(P)*x
%and instead of propagating the true covariance matrix P, it propagates
%PInv=inv(P)
%which means that the filter can be used even when PInv is singular.
%
%More information on information filtering is given in Chapter 7.2 of [2].
%
%EXAMPLE:
%In this example, we feed two measurements to the information filter and
%show that the result has a consistent NEES and the RMSE is the same as the
%second measurement.
% T=1;%Sample period.
% numRuns=1000;
% %Parameters for the noise process dynamics and measurement.
% H=[eye(2,2),zeros(2,2)];
% zDim=size(H,1);
% xDim=size(H,2);
% R=diag([40;40]);
% SR=chol(R,'lower');
%
% %Statistics for the initial state.
% x0Mean=[1e3;0;75;-50];
% x0Cov=diag([1e3^2;100^2;25^2;25^2]);
% x0S=chol(x0Cov,'lower');
%
% %Parameters for the state dynamics.
% q=processNoiseSuggest('PolyKal-ROT',9.8,1);
% F=FPolyKal(T,xDim,1);
% Q=QPolyKal(T,xDim,1,q);
% SQ=chol(Q,'lower');
%
% RMSEMeas=0;
% RMSE=0;
% NEES=0;
% for curRun=1:numRuns
%     %Draw the initial state.
%     x1True=x0Mean+x0S*randn(xDim,1);
%     %Get the first measurement.
%     z1=H*x1True+SR*randn(zDim,1);
%
%     x2True=F*x1True+SQ*randn(xDim,1);
%     z2=H*x2True+SR*randn(zDim,1);
%
%     %Two-point initialization.
%     y0=zeros(xDim,1);
%     PInv0=zeros(xDim,xDim);
%     [yUpdate,PInvUpdate]=infoFilterUpdate(y0,PInv0,z1,R,H);
%     [yPred, PInvPred]=infoFilterDiscPred(yUpdate,PInvUpdate,F,Q);
%     [yUpdate,PInvUpdate]=infoFilterUpdate(yPred,PInvPred,z2,R,H);
%     xEst2=PInvUpdate\yUpdate;
%
%     diff=xEst2-x2True;
%     NEES=NEES+diff'*PInvUpdate*diff;
%     RMSE=RMSE+sum(diff(1:2).^2);
%     diff=z2-x2True(1:2);
%     RMSEMeas=RMSEMeas+sum(diff(1:2).^2);
% end
% RMSEMeas=sqrt(RMSEMeas/numRuns)
% RMSE=sqrt(RMSE/numRuns)
% NEES=NEES/(xDim*numRuns)
%One will see that RMSEMeas equal RMSE, because with just two measurements,
%one cannot smmooth the position estimate syet. Additionally, NEES will be
%close to 1 indicating covariance consistency.
%
%REFERENCES:
%[1] David F. Crouse , "Basic tracking using nonlinear 3D monostatic and
%    bistatic measurements," IEEE Aerospace and Electronic Systems
%    Magazine, vol. 29, no. 8, Part II, pp. 4-53, Aug. 2014.
%[2] Y. Bar-Shalom, X. R. Li, and T. Kirubarajan, Estimation with
%    Applications to Tracking and Navigation. New York: John Wiley and
%    Sons, Inc, 2001.
%
%September 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

    yUpdate=yPred+H'/R*z;
    PInvUpdate=PInvPred+H'/R*H;
    %Ensure symmetry
    PInvUpdate=(PInvUpdate+PInvUpdate')/2;
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.