function [theCombo,recurData]=getNextCapacitatedCombo(param1,numBins,totalItems)
%%GETNEXTCAPACITATEDCOMBO Get the next combination of placing totalItems
%               items into numBins unlabeled bins where each bin can hold
%               numPerBin items. If numPerBin=1, then this is just
%               generating standard combinations of numBins items taken
%               from a total of totalItems. The capacitated combinations
%               are equivalent to putting totalItems labeled balls into
%               numBins unlabeled bins such that each bin holds numPerBin
%               items and the ordering of the items in the bins does not
%               matter.
%
%INPUTS: param1 If the first combination is desired, then more than one
%               input must be given and param1=numPerBin, the number of
%               items in each bin. Otherwise, param1=recurData, the second
%               output of the function from the last call.
%       numBins This input should only be provided if the first capacitated
%               combination in the sequence is desired. This is the number
%               of bins (of capacity numPerBin) into which things can be
%               placed.
%    totalItems This input can only be given when the first combination is
%               desired. This is the total number of items that can be
%               assigned. If numBins is provided, but this is omitted or an
%               empty matrix is passed, then a value of numBins*numPerBin
%               is used, the minimum allowed value.
%
%OUTPUTS: theCombo The numPerBinXnumBins next capacitated combination. If
%                  the final capacitated combination has been passed, then
%                  an empty matrix is returned.
%        recurData A data structure that can be passed back to this
%                  function to get the next combination.
%
%The algorithm is the same as that used in genAllCapacitatedCombos. See the
%comments to genAllCapacitatedCombos for more information. The total number
%of capaciatted combinations is given by numCapacitatedCombos.
%
%EXAMPLE:
%This example just shows that the capacitated combinations produced by this
%function come in the same order as those produced by the function
%genAllCapacitatedCombos. When run, it collects the combinations by
%repeatedly calling this function and then asserts that they are all equal
%what genAllCapacitatedCombos returns. The result shoud be true, so there
%should be no error.
% numPerBin=2;
% numBins=4;
% totalItems=4*2+2;
%
% totalCapCombos=numCapacitatedCombos(numPerBin,numBins,totalItems);
% allCapCombos=zeros(numPerBin,numBins,totalCapCombos);
%
% [theCombo,recurData]=getNextCapacitatedCombo(numPerBin,numBins,totalItems);
% allCapCombos(:,:,1)=theCombo;
%
% for comboIdx=2:totalCapCombos
%     [theCombo,recurData]=getNextCapacitatedCombo(recurData);
%     allCapCombos(:,:,comboIdx)=theCombo;
% end
%
% allBatchCombos=genAllCapacitatedCombos(numPerBin,numBins,totalItems);
% assert(all(allCapCombos(:)==allBatchCombos(:)))
%The assertion should not raise an error.
%
%July 2019 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin>=2)
    if(nargin<3||isempty(totalItems))
        totalItems=param1*numBins;
    end

    %If this is the first capacitated combination, then create the
    %recurData structure for the first time.
    numPerBin=param1;

    %The total number of items to assign in combinations across the bins.
    n=numBins*numPerBin;

    %Save the values in recurData that do not change with the iterations.
    recurData=[];
    recurData.numPerBin=numPerBin;
    recurData.numBins=numBins;
    recurData.n=n;
    recurData.totalItems=totalItems;

    %Special case for standard combinations.
    if(numPerBin==1)
        curIdxCombos=1:numBins;
        recurData.curIdxCombos=curIdxCombos;
        theCombo=curIdxCombos;
        recurData.curBin=1;
        recurData.curSet=1;
        recurData.curCombos=[];
        recurData.idxLists=[];
        recurData.backtracking=[];

        I=1:n;
        recurData.I=getNextCombo(I,totalItems,1);
        return
    end

    curIdxCombos=zeros(numPerBin,numBins);
    curCombos=zeros(numPerBin-1,numBins);

    %This holds the indices that can be assigned in each bin and in subsequent
    %bins.
    idxLists=zeros(n,numBins);
    idxLists(:,1)=1:n;

    curSet=1;
    curBin=1;
    backtracking=false;
    %When n~=totalItems, after each base capacitated combination is
    %generated, we have to go through all combinations of indices that make
    %up the combinations. This is the current index combination. When
    %empty, it means that we haven't gotten a base capacitated combination
    %yet.
    I=[];
    recurData.I=I;
else
    recurData=param1;

    if(isempty(recurData))
       theCombo=[];
       return;
    end

    %Extract the values that change on each iteration.
    curIdxCombos=recurData.curIdxCombos;
    curCombos=recurData.curCombos;
    idxLists=recurData.idxLists;
    curSet=recurData.curSet;
    curBin=recurData.curBin;
    backtracking=recurData.backtracking;
    I=recurData.I;
end

%Get the values that do not change between calls.
numPerBin=recurData.numPerBin;
numBins=recurData.numBins;
n=recurData.n;
totalItems=recurData.totalItems;
numPerBinM1=numPerBin-1;

if(~isempty(I))
    %Just get the next combination of indices to the capcitated combination
    %and return that.
    theCombo=reshape(I(curIdxCombos),[numPerBin,numBins]);

    %If past the final combination, then I is an empty matrix and it will
    %know to go onto the next capacitated base combination.
    I=getNextCombo(I,totalItems,1);
    recurData.I=I;
    return
elseif(numPerBin==1)
    %The special case of standard combos.
    theCombo=[];
    return;
end

while(curBin>0)
    %This is the number of elements that can be assigned in the current
    %bin including making a hard assignment on the first index.
    numInIdx=n-(curBin-1)*numPerBin;

    if(backtracking==false)
        %We are just entering this bin.
        %The first element in each bin is fixed to the first index in the
        %idxList.
        curIdxCombos(1,curBin)=idxLists(1,curBin);

        %In this level, we have to go through all combinations of the
        %remaining n-curBin*(numPerBin-1); unassigned elements of
        %idxLists(:,curBin) in this bin. Each time an assignment is made in
        %this bin, those elements are removed from idxLists going into the
        %next higher level so that we never get repeats.
        curIdxCombos(2:numPerBin,curBin)=idxLists(2:numPerBin,curBin);
        %Current combination of the indices in idxLists in this bin.
        curCombos(:,curBin)=1:numPerBinM1;

        if(curBin==numBins)
            %If we are in the final bin, then save the combo and move to
            %the previous bin. In practice, subsequent calls to this
            %function will nto go to the previous bin until all
            %combinations of index assignments (via I) are assigned.
            I=1:n;
            theCombo=curIdxCombos;
            curSet=curSet+1;

            backtracking=true;
            curBin=curBin-1;

            %Save the values that change during iteration to recurData
            %before returning.
            recurData.curIdxCombos=curIdxCombos;
            recurData.curCombos=curCombos;
            recurData.idxLists=idxLists;
            recurData.curSet=curSet;
            recurData.curBin=curBin;
            recurData.backtracking=backtracking;
            recurData.I=getNextCombo(I,totalItems,1);
            return;
        else
            %Otherwise, set idxLists for the next level and move to the
            %next bin.numInIdxNext
            numInIdxNext=numInIdx-numPerBin;
            idxLists(1:numInIdxNext,curBin+1)=idxLists((numPerBin+1):numInIdx,curBin);

            curBin=curBin+1;
        end
    else
        %If here, we are backtracking.

        %We subtract 1 because we have made a hard assignment on the first
        %index.
        nextCombo=getNextCombo(curCombos(:,curBin),numInIdx-1,1);
        if(isempty(nextCombo))
            %Continue backtracking.
            curBin=curBin-1;
            continue;
        end
        %Otherwise, record the current combination.
        curCombos(:,curBin)=nextCombo;

        %Record the indices for the current combination.
        nextCombo=nextCombo+1;
        curIdxCombos(2:numPerBin,curBin)=idxLists(nextCombo,curBin);

        %Now, set the values in idxLists at the next bin level to those
        %that are in idxLists but not in nextCombo. We note that the
        %indices are given in increasing order and that the first index is
        %skipped because we know it is assigned.
        curAssignedIdx=2;
        curNextIdx=1;
        for curListIdx=2:numInIdx
            if(idxLists(curListIdx,curBin)==curIdxCombos(curAssignedIdx,curBin))
                curAssignedIdx=curAssignedIdx+1;
                if(curAssignedIdx>numPerBin)
                    %Then all of the rest of the indices are assigned.
                    numInIdxNext=numInIdx-numPerBin;
                    idxLists(curNextIdx:numInIdxNext,curBin+1)=idxLists((curListIdx+1):numInIdx,curBin);
                    break;
                end
            else
                idxLists(curNextIdx,curBin+1)=idxLists(curListIdx,curBin);
                curNextIdx=curNextIdx+1;
            end
        end

        %Go to the next bin.
        curBin=curBin+1;
        backtracking=false;
    end
end

%If we get here, we passed the final combiantion.
theCombo=[];
recurData=[];
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.


function v = r8vec_house_column ( n, a_vec, k )

%*****************************************************************************80
%
%% R8VEC_HOUSE_COLUMN defines a Householder premultiplier that "packs" a column.
%
%  Discussion:
%
%    The routine returns a vector V that defines a Householder
%    premultiplier matrix H(V) that zeros out the subdiagonal entries of
%    column K of the matrix A.
%
%       H(V) = I - 2 * v * v'
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 January 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix A.
%
%    Input, real A_VEC(N,1), column K of the matrix A.
%
%    Input, integer K, the column of the matrix to be modified.
%
%    Output, real V(N,1), a vector of unit L2 norm which defines an
%    orthogonal Householder premultiplier matrix H with the property
%    that the K-th column of H*A is zero below the diagonal.
%

%
%  Destroy all row vectors!
%
  a_vec = a_vec(:);

  v(1:n,1) = 0.0;

  if ( k < 1 || n <= k )
    return
  end

  s = sqrt ( sum ( a_vec(k:n,1).^2 ) );

  if ( s == 0.0 )
    return
  end

  if ( a_vec(k,1) < 0.0 )
    v(k,1) = a_vec(k,1) - abs ( s ) ;
  else
    v(k,1) = a_vec(k,1) + abs ( s );
  end
  v(k+1:n,1) = a_vec(k+1:n,1);
%
%  Normalize V.
%
  s = sqrt ( sum ( v(k:n,1).^2 ) );

  v(k:n,1) = v(k:n,1) / s;

  return
end


function [ q_min, q_max, q_ave, q_area ] = q_measure ( n, z, triangle_order, ...
  triangle_num, triangle_node )

%*****************************************************************************80
%
%% Q_MEASURE determines the triangulated pointset quality measure Q.
%
%  Discussion:
%
%    The Q measure evaluates the uniformity of the shapes of the triangles
%    defined by a triangulated pointset.
%
%    For a single triangle T, the value of Q(T) is defined as follows:
%
%      TAU_IN = radius of the inscribed circle,
%      TAU_OUT = radius of the circumscribed circle,
%
%      Q(T) = 2 * TAU_IN / TAU_OUT
%        = ( B + C - A ) * ( C + A - B ) * ( A + B - C ) / ( A * B * C )
%
%    where A, B and C are the lengths of the sides of the triangle T.
%
%    The Q measure computes the value of Q(T) for every triangle T in the
%    triangulation, and then computes the standard deviation of this
%    set of values:
%
%      Q_MEASURE = min ( all T in triangulation ) Q(T)
%
%    In an ideally regular mesh, all triangles would have the same
%    equilateral shape, for which Q = 1.  In a good mesh, 0.5 < Q.
%
%    Given the 2D coordinates of a set of N nodes, stored as Z(1:2,1:N),
%    a triangulation is a list of NT triples of node indices that form
%    triangles.  Generally, a maximal triangulation is expected, namely,
%    a triangulation whose image is a planar graph, but for which the
%    addition of any new triangle would mean the graph was no longer planar.
%    A Delaunay triangulation is a maximal triangulation which maximizes
%    the minimum angle that occurs in any triangle.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 June 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Per-Olof Persson and Gilbert Strang,
%    A Simple Mesh Generator in MATLAB,
%    SIAM Review,
%    Volume 46, Number 2, pages 329-345, June 2004.
%
%  Parameters:
%
%    Input, integer N, the number of points.
%
%    Input, real Z(DIM_NUM,N), the points.
%
%    Input, integer TRIANGLE_ORDER, the order of the triangles.
%
%    Input, integer TRIANGLE_NUM, the number of triangles.
%
%    Input, integer TRIANGLE_NODE(TRIANGLE_ORDER,TRIANGLE_NUM), the triangulation.
%
%    Output, real ( kind = 8 ) Q_MIN, Q_MAX, the minimum and maximum values
%    of Q over all triangles.
%
%    Output, real ( kind = 8 ) Q_AVE, the average value of Q.
%
%    Output, real ( kind = 8 ) Q_AREA, the average value of Q, weighted by
%    the area of each triangle.
%
  q_min = r8_huge ( );
  q_max = - r8_huge ( );
  q_ave = 0.0;
  q_area = 0.0;
  area_total = 0.0;

  for triangle = 1 : triangle_num

    a_index = triangle_node(1,triangle);
    b_index = triangle_node(2,triangle);
    c_index = triangle_node(3,triangle);

    ab_length = sqrt ( ...
        ( z(1,a_index) - z(1,b_index) )^2 ...
      + ( z(2,a_index) - z(2,b_index) )^2 );

    bc_length = sqrt ( ...
        ( z(1,b_index) - z(1,c_index) )^2 ...
      + ( z(2,b_index) - z(2,c_index) )^2 );

    ca_length = sqrt ( ...
        ( z(1,c_index) - z(1,a_index) )^2 ...
      + ( z(2,c_index) - z(2,a_index) )^2 );

    q = ( bc_length + ca_length - ab_length ) ...
      * ( ca_length + ab_length - bc_length ) ...
      * ( ab_length + bc_length - ca_length ) ...
      / ( ab_length * bc_length * ca_length );

    x1 = z(1,triangle_node(1,triangle));
    y1 = z(2,triangle_node(1,triangle));
    x2 = z(1,triangle_node(2,triangle));
    y2 = z(2,triangle_node(2,triangle));
    x3 = z(1,triangle_node(3,triangle));
    y3 = z(2,triangle_node(3,triangle));

    area = 0.5 * abs ( x1 * ( y2 - y3 ) ...
                     + x2 * ( y3 - y1 ) ...
                     + x3 * ( y1 - y2 ) );

    q_min = min ( q_min, q );
    q_max = max ( q_max, q );
    q_ave = q_ave + q;
    q_area = q_area + q * area;

    area_total = area_total + area;

  end

  q_ave = q_ave / triangle_num;

  if ( 0.0 < area_total )
    q_area = q_area / area_total;
  else
    q_area = 0.0;
  end

  return
end


clear all, close all, clc
A = imread('../../CH01_SVD/DATA/dog.jpg');
B = rgb2gray(A);

%%
n = 2; w = 'db1'; [c,s] = wavedec2(B,n,w);
plotwavelet2(c,s,2,'db1',128,'square');
colormap gray
axis off
axis tight
set(gcf,'Position',[100 100 600 800])
set(gcf,'PaperPositionMode','auto')
print('-dpng', '-loose', '../figures/2DWavelet_Square');

%%
n = 3; w = 'sym2'; [c,s] = wavedec2(B,n,w);
[H1,V1,D1] = detcoef2('all',c,s,1);
A1 = appcoef2(c,s,'haar',1);
V1img = wcodemat(V1,255,'mat',1);
H1img = wcodemat(H1,255,'mat',1);
D1img = wcodemat(D1,255,'mat',1);
A1img = wcodemat(A1,255,'mat',1);
imagesc(A1img)
figure
[H2,V2,D2] = detcoef2('all',c,s,2);
A2 = appcoef2(c,s,'haar',2);
V2img = wcodemat(V2,255,'mat',2);
H2img = wcodemat(H2,255,'mat',2);
D2img = wcodemat(D2,255,'mat',2);
A2img = wcodemat(A2,255,'mat',2);
imagesc(V2img)
figure
colormap(gray); rv = length(gray);
plotwavelet2(c,s,3,'haar',rv,'square')

figure
subplot(2,2,1)
imagesc(A1img)

subplot(2,2,2)
imagesc(V1img)

subplot(2,2,3)
imagesc(H1img)

subplot(2,2,4)
imagesc(D1img)


function fx = p18_fun ( n, x )

%*****************************************************************************80
%
%% P18_FUN evaluates the integrand for problem 18.
%
%  Integral:
%
%    Integral ( 0 <= x < +oo ) x^2 * exp ( - x / 2^beta ) dx
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 December 2011
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Robert Piessens, Elise de Doncker-Kapenga,
%    Christian Ueberhuber, David Kahaner,
%    QUADPACK: A Subroutine Package for Automatic Integration,
%    Springer, 1983, page 84.
%
%  Parameters:
%
%    Input, integer N, the number of points.
%
%    Input, real X(N), the point at which the integrand
%    is to be evaluated.
%
%    Output, real FX(N), the value of the integrand at X.
%
  beta = 1.0;

  fx(1:n) = x(1:n).^2 .* exp ( - x(1:n) / 2^beta );

  return
end


function ex4bvp
%EX4BVP  Example 4 of the BVP tutorial.
%   This is a nerve impulse model considered in Example 7.1 of
%   R. Seydel, From Equilibrium to Chaos, Elsevier, 1988.  The
%   differential equations
%
%      y1' = 3*(y1 + y2 - 1/3*y1^3 + lambda)
%      y2' = -(y1 - 0.7 + 0.8*y2)/3
%
%   are to be solved subject to periodic boundary conditions
%
%      y1(0) = y1(T)
%      y2(0) = y2(T)
%
%   This is an example of non-separated boundary conditions, meaning
%   that some conditions involve values of the solution at both ends
%   of the interval.  Periodic boundary conditions are a common source
%   of such problems.  BVP4C is unusual in that it accepts problems
%   with non-separated boundary conditions.
%
%   The parameter lambda has the value -1.3 in the text cited.  The
%   period T is unknown, which is to say that the length of the
%   interval is not known. Such problems require some preparation.
%   By scaling the independent variable to tau = t/T the problem is
%   posed on the fixed interval [0,1]. When this is done, T becomes
%   an unknown parameter, but BVP4C provides for unknown parameters.

% Copyright 2002, The MathWorks, Inc.

%  Periodic functions evaluated in EX4INIT are used as a guess for the
%  solution on a crude mesh of 5 equally spaced points.  A guess of 2*pi
%  is provided for the unknown parameter T.
solinit = bvpinit(linspace(0,1,5),@ex4init,2*pi);

options = bvpset('stats','on');

sol = bvp4c(@ex4ode,@ex4bc,solinit,options);
T = sol.parameters;

%  The independent variable needs to be rescaled to its original value
%  before plotting the solution.  The initial guess is also plotted.
figure
plot(T*sol.x,sol.y(1,:),T*solinit.x,solinit.y(1,:),'o')
legend('solution found','initial guess');
axis([0 T -2.2 2]);
title('Nerve impulse model');
ylabel('solution y_1(t)');
xlabel(['Periodic solution with period ',num2str(sol.parameters,4)]);

% --------------------------------------------------------------------------

function v = ex4init(x)
%EX4INIT  Guess function for Example 4 of the BVP tutorial.
%   V = EX4INIT(X) returns a column vector V that is a guess for y(x).
v = [ sin(2*pi*x)
      cos(2*pi*x)];

% --------------------------------------------------------------------------

function dydt = ex4ode(t,y,T);
%EX4ODE  ODE funcion for Example 4 of the BVP tutorial.
dydt = [ 3*T*(y(1) + y(2) - 1/3*(y(1)^3) - 1.3);
         (-1/3)*T*(y(1) - 0.7 + 0.8*y(2)) ];

% --------------------------------------------------------------------------

function res = ex4bc(ya,yb,T)
%EX4BC  Boundary conditions for Example 4 of the BVP tutorial.
res = [ya(1) - yb(1)
       ya(2) - yb(2)
       T*(-1/3)*(ya(1) - 0.7 + 0.8*ya(2)) - 1];


% Euclidean projection on a rectangle
% Section 8.1.1, Boyd & Vandenberghe "Convex Optimization"
% Joelle Skaf - 10/07/05
%
% The projection of x0 on a rectangle C = {x | l <= x <= u} is given by
%           minimize || x - x0 ||^2
%               s.t.    l <= x <= u
% It is also given by P_C(x0)_k = l_k       if  x0_k <= l_k
%                                 x0_k      if  l_k <= x0_k <= u_k
%                                 u_k       if  x0_k >= u_k

% Input data: generate vectors l and u such that l < 0 < u
n  = 10;
l  = -rand(n,1);
u  = rand(n,1);
x0 = randn(n,1);

% Analytical solution
fprintf(1,'Computing the analytical solution ...');
pc_x0 = x0;
pc_x0(find(x0<=l)) = l(find(x0<=l));
pc_x0(find(x0>=u)) = u(find(x0>=u));
fprintf(1,'Done! \n');

% Solution via QP
fprintf(1,'Computing the optimal solution by solving a QP ...');

cvx_begin quiet
    variable x(n)
    minimize ( norm(x-x0) )
    x <= u;
    x >= l;
cvx_end

fprintf(1,'Done! \n');

% Verification
disp('-----------------------------------------------------------------');
disp('Verifying that the analytical solution and the solution obtained via QP are equal: ');
[pc_x0 x]


function area = triangle_area ( vert1, vert2, vert3 )

%*****************************************************************************80
%
%% TRIANGLE_AREA returns the area of a triangle.
%
%  Licensing:
%
%    This code is distributed under the GNU GPL license.
%
%  Modified:
%
%    26 June 2014
%
%  Author:
%
%    Original FORTRAN77 version by Hong Xiao, Zydrunas Gimbutas.
%    This MATLAB version by John Burkardt.
%
%  Reference:
%
%    Hong Xiao, Zydrunas Gimbutas,
%    A numerical algorithm for the construction of efficient quadrature
%    rules in two and higher dimensions,
%    Computers and Mathematics with Applications,
%    Volume 59, 2010, pages 663-676.
%
%  Parameters:
%
%    Input, real VERT1(2), VERT2(2), VERT3(2), the vertices of
%    the triangle.
%
%    Output, real AREA, the area of the triangle.
%
  area = 0.5 * ...
    ( ...
        ( vert2(1) - vert1(1) ) * ( vert3(2) - vert1(2) ) ...
      - ( vert3(1) - vert1(1) ) * ( vert2(2) - vert1(2) ) ...
    );

  return
end


function [ x, seed ] = circular_normal_sample ( a, b, seed )

%*****************************************************************************80
%
%% CIRCULAR_NORMAL_SAMPLE samples the Circular Normal PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 January 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real A(2), a parameter of the PDF, the mean value.
%
%    Input, real B, a parameter of the PDF, the standard deviation.
%
%    Input/output, integer SEED, a seed for the random
%    number generator.
%
%    Output, real X(2), a sample of the PDF.
%
  [ v1, seed ] = r8_uniform_01 ( seed );
  [ v2, seed ] = r8_uniform_01 ( seed );

  r = sqrt ( - 2.0 * log ( v1 ) );

  x(1) = a(1) + b * r * cos ( 2.0 * pi * v2 );
  x(2) = a(2) + b * r * sin ( 2.0 * pi * v2 );

  return
end


function f = bohach2 ( m, x )

%*****************************************************************************80
%
%% BOHACH2 evaluates the Bohachevsky function #2.
%
%  Discussion:
%
%    The minimizer is
%
%      X* = [ 0.0, 0.0 ]
%      F(X*) = 0.0
%
%    Suggested starting point:
%
%      X = [ 0.6, 1.3 ];
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Zbigniew Michalewicz,
%    Genetic Algorithms + Data Structures = Evolution Programs,
%    Third Edition,
%    Springer Verlag, 1996,
%    ISBN: 3-540-60676-9,
%    LC: QA76.618.M53.
%
%  Parameters:
%
%    Input, integer M, the number of variables.
%
%    Input, real X(M), the argument of the function.
%
%    Output, real F, the value of the function at X.
%
  f =       x(1) * x(1) ...
    + 2.0 * x(2) * x(2) ...
    - 0.3 * cos ( 3.0 * pi * x(1) ) * cos ( 4.0 * pi * x(2) ) ...
    + 0.3;

  return
end


function [X,W]=simplexquad(varargin)

% simplexquad.m - Gaussian Quadrature for an n-dimensional simplex.
%
% Construct Gauss points and weights for a n-dimensional simplex
% domain with vertices specified by the n*(n-1) matrix vert. Where each
% row contains the coordinates (x1,...,xn) for a vertex. The order of
% the quadrature scheme in each dimension must be the same in this
% implementation.
%
% Sample Usage:
%
% [X,W]=simplexquad(n,vert); % Specify the vertices
% [X,W]=simplexquad(n,dim);  % Specify the dimension and use unit simplex
%
% X will be a matrix for which the jth column are the grid points in each
% coordinate xj.
%
% Note: The standard n-dimensional simplex has vertices specified
%       vert=eye(n+1,n).
%
% The first four simplexes are
%
% n | Domain
% --|------------
% 1 | Interval
% 2 | Triangle
% 3 | Tetrahedron
% 4 | Pentatope
%
% Written by: Greg von Winckel
% Contact: gregvw(at)math(dot)unm(dot)edu
% http://math.unm.edu/~gregvw

nargin=length(varargin);

if nargin~=2
    error('simplexquad takes two input arguments');
end

N=varargin{1};

if length(N)~=1
    error('First argument must be a scalar');
end

if N~=abs(round(N-1))+1;
    error('Number of Gauss points must be a natural number');
end

if length(varargin{2})==1  % Dimension specified
    n=varargin{2};

    if n~=abs(round(n-1))+1;
        error('Dimension must be a natural number');
    end

    m=n+1; vert=eye(m,n);
else                      % Vertices specified
    vert=varargin{2};
    [m,n]=size(vert);

    if m~=n+1
        error('The matrix of vertices must have n+1 rows and n columns');
    end
end

Nn=N^n;

if n==1 % The 1-D simplex is only an interval
    [q,w]=rquad(N,0); len=diff(vert);
    X=vert(1)+len*q;  W=abs(len)*w;

else % Find quadrature rules for higher dimensional domains

    for k=1:n
        [q{k},w{k}]=rquad(N,n-k);
    end

    [Q{1:n}]=ndgrid(q{:}); q=reshape(cat(n,Q{:}),Nn,n);
    [W{1:n}]=ndgrid(w{:}); w=reshape(cat(n,W{:}),Nn,n);

    map=eye(m); map(2:m,1)=-1; c=map*vert;
    W=abs(det(c(2:m,:)))*prod(w,2);

    qp=cumprod(q,2); e=ones(Nn,1);
    X=[e [(1-q(:,1:n-1)),e].*[e,qp(:,1:n-2),qp(:,n)]]*c;
end

function [x,w]=rquad(N,k)

k1=k+1; k2=k+2; n=1:N;  nnk=2*n+k;
A=[k/k2 repmat(k^2,1,N)./(nnk.*(nnk+2))];
n=2:N; nnk=nnk(n);
B1=4*k1/(k2*k2*(k+3)); nk=n+k; nnk2=nnk.*nnk;
B=4*(n.*nk).^2./(nnk2.*nnk2-nnk2);
ab=[A' [(2^k1)/k1; B1; B']]; s=sqrt(ab(2:N,2));
[V,X]=eig(diag(ab(1:N,1),0)+diag(s,-1)+diag(s,1));
[X,I]=sort(diag(X));
x=(X+1)/2; w=(1/2)^(k1)*ab(1,2)*V(1,I)'.^2;


function divdif_test05 ( )

%*****************************************************************************80
%
%% DIVDIF_TEST05 tests DIF_TO_R8POLY and DIF_SHIFT_ZERO.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    07 October 2006
%
%  Author:
%
%    John Burkardt
%
  maxtab = 10;

  fprintf ( 1, '\n' );
  fprintf ( 1, 'DIVDIF_TEST05\n' );
  fprintf ( 1, '  DIF_TO_R8POLY converts a difference table to a\n' );
  fprintf ( 1, '  polynomial;\n' );
  fprintf ( 1, '  DIF_SHIFT_ZERO shifts a divided difference\n' );
  fprintf ( 1, '  table to all zero abscissas;\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  These are equivalent operations!\n' );
  fprintf ( 1, '\n' );
%
%  Set XTAB, YTAB to X, F(X)
%
  ntab = 4;

  xtab1 = r8vec_indicator ( ntab );

  ytab1(1:ntab) = xtab1(1:ntab).^3 - 2.0 * xtab1(1:ntab).^2 ...
    + 3.0 * xtab1(1:ntab) - 4.0;

  xtab2 = r8vec_indicator ( ntab );

  ytab2(1:ntab) = xtab2(1:ntab).^3 - 2.0 * xtab2(1:ntab).^2 ...
    + 3.0 * xtab2(1:ntab) - 4.0;
%
%  Compute and display the finite difference table.
%
  diftab1 = data_to_dif_display ( ntab, xtab1, ytab1 );

  diftab2 = data_to_dif_display ( ntab, xtab2, ytab2 );
%
%  Examine corresponding polynomial.
%
  dif_print ( ntab, xtab1, diftab1, '  The divided difference polynomial:' );
%
%  Shift to zero.
%
  [ xtab1, diftab1 ] = dif_shift_zero ( ntab, xtab1, diftab1 );

  r8poly_print ( ntab, diftab1, '  Using DIF_SHIFT_ZERO' );
%
%  Shift to zero.
%
  c = dif_to_r8poly ( ntab, xtab2, diftab2 );

  r8poly_print ( ntab, c, '  Using DIF_TO_R8POLY' );

  return
end


function b = isPerpendicular(v1, v2, varargin)
%ISPERPENDICULAR Check orthogonality of two vectors
%
%   B = isPerpendicular(V1, V2)
%   where V1 and V2 are two 1-by-2 row arrays, returns 1 if the vectors are
%   perpendicular, and 0 otherwise.
%
%   Also works when V1 and V2 are two N-by-2 arrays with same number of
%   rows. In this case, return a N-by-1 array containing 1 at the positions
%   of perpendicular vectors.
%
%   Also works when one of V1 or V2 is 1-by-2 and the other one is a N-by-2
%   array. In this case the result has size N-by-1.
%
%   B = isPerpendicular(V1, V2, ACCURACY)
%   specifies accuracy of numerical tests, default is 1e-14.
%
%
%   Example
%   isPerpendicular([1 2 1], [2 4 2])
%   ans =
%       1
%
%   isPerpendicular([1 2 1], [1 3 2])
%   ans =
%       0
%
%   See also
%   vectors2d, isParallel, lines2d
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2006-04-25
% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas).

%   HISTORY
%   2007-09-18 copy from isPerpendicular, adapt to any dimension, and add
%       psb to specify precision
%   2009-09-21 fix bug for array of 3 vectors
%   2011-01-20 replace repmat by ones-indexing (faster)
%   2017-08-31 use normalized vectors

% default accuracy
acc = 1e-14;
if ~isempty(varargin)
    acc = abs(varargin{1});
end

% normalize vectors
v1 = normalizeVector(v1);
v2 = normalizeVector(v2);

% adapt size of inputs
n1 = size(v1, 1);
n2 = size(v2, 1);
if n1 ~= n2
    if n1 == 1
        v1 = v1(ones(n2, 1), :);
    elseif n2==1
        v2 = v2(ones(n1, 1), :);
    else
        error('Inputs must either have same size, or one must be scalar');
    end
end

% performs test
b = abs(dot(v1, v2, 2)) < acc;


function traj = ScrewTrajectory(Xstart, Xend, Tf, N, method)
% *** CHAPTER 9: TRAJECTORY GENERATION ***
% Takes Xstart: The initial end-effector configuration,
%       Xend: The final end-effector configuration,
%       Tf: Total time of the motion in seconds from rest to rest,
%       N: The number of points N > 1 (Start and stop) in the discrete
%          representation of the trajectory,
%       method: The time-scaling method, where 3 indicates cubic
%               (third-order polynomial) time scaling and 5 indicates
%               quintic (fifth-order polynomial) time scaling.
% Returns traj: The discretized trajectory as a list of N matrices in SE(3)
%               separated in time by Tf/(N-1). The first in the list is
%               Xstart and the Nth is Xend .
% This function calculates a trajectory corresponding to the screw motion
% about a space screw axis.
% Example Input:
%
% clear; clc;
% Xstart = [[1 ,0, 0, 1]; [0, 1, 0, 0]; [0, 0, 1, 1]; [0, 0, 0, 1]];
% Xend = [[0, 0, 1, 0.1]; [1, 0, 0, 0]; [0, 1, 0, 4.1]; [0, 0, 0, 1]];
% Tf = 5;
% N = 4;
% method = 3;
% traj = ScrewTrajectory(Xstart, Xend, Tf, N, method)
%
% Output:
% traj =
%    1.0000         0         0    1.0000
%         0    1.0000         0         0
%         0         0    1.0000    1.0000
%         0         0         0    1.0000
%
%    0.9041   -0.2504    0.3463    0.4410
%    0.3463    0.9041   -0.2504    0.5287
%   -0.2504    0.3463    0.9041    1.6007
%         0         0         0    1.0000
%
%    0.3463   -0.2504    0.9041   -0.1171
%    0.9041    0.3463   -0.2504    0.4727
%   -0.2504    0.9041    0.3463    3.2740
%         0         0         0    1.0000
%
%   -0.0000    0.0000    1.0000    0.1000
%    1.0000   -0.0000    0.0000   -0.0000
%    0.0000    1.0000   -0.0000    4.1000
%         0         0         0    1.0000

timegap = Tf / (N - 1);
traj = cell(1, N);
for i = 1: N
    if method == 3
        s = CubicTimeScaling(Tf, timegap * (i - 1));
    else
        s = QuinticTimeScaling(Tf, timegap * (i - 1));
    end
    traj{i} = Xstart * MatrixExp6(MatrixLog6(TransInv(Xstart) * Xend) * s);
end
end


function [log_rad,angle]=base(m,n)
% Compute radius and angle matrix base for a given size of m,n
% Input:
%       m:  number of rows
%       n:  number of cols
% Output:
%   log_rad:    radius matrix, store the distance between a pixel and
%               the center of matrix
%     angle:    angle matrix, store the angle of a pixel

ctrm=ceil(m/2);
ctrn=ceil(n/2);

% x span from -m/2 to m/2 with interval 2/m
[x,y] = meshgrid(( (1:m)-ctrm)/(m/2),( (1:n)-ctrn)/(n/2));

% radius matrix
rad = sqrt(x.^2 + y.^2);
rad(m/2,n/2) =  rad(m/2,n/2-1);
log_rad  = log2(rad);

% angle matrix
angle = atan2(y,x);


%................................................................

function stiffness=formStiffness2D(GDof,numberElements,...
    elementNodes,numberNodes,nodeCoordinates,D,thickness)

% compute stiffness matrix
% for plane stress Q4 elements

stiffness=zeros(GDof);

% 2 by 2 quadrature
[gaussWeights,gaussLocations]=gauss2d('2x2');

for e=1:numberElements
  numNodePerElement = length(elementNodes(e,:));
  numEDOF = 2*numNodePerElement;
  elementDof=zeros(1,numEDOF);
  for i = 1:numNodePerElement
      elementDof(2*i-1)=2*elementNodes(e,i)-1;
      elementDof(2*i)=2*elementNodes(e,i);
  end

  % cycle for Gauss point
  for q=1:size(gaussWeights,1)
    GaussPoint=gaussLocations(q,:);
    xi=GaussPoint(1);
    eta=GaussPoint(2);

% shape functions and derivatives
    [shapeFunction,naturalDerivatives]=shapeFunctionQ4(xi,eta);

% Jacobian matrix, inverse of Jacobian,
% derivatives w.r.t. x,y
    [Jacob,invJacobian,XYderivatives]=...
        Jacobian(nodeCoordinates(elementNodes(e,:),:),naturalDerivatives);

%  B matrix
    B=zeros(3,numEDOF);
    B(1,1:2:numEDOF)       = XYderivatives(:,1)';
    B(2,2:2:numEDOF)  = XYderivatives(:,2)';
    B(3,1:2:numEDOF)       = XYderivatives(:,2)';
    B(3,2:2:numEDOF)  = XYderivatives(:,1)';

% stiffness matrix
    stiffness(elementDof,elementDof)=...
        stiffness(elementDof,elementDof)+...
        B'*D*thickness*B*gaussWeights(q)*det(Jacob);
  end
end


%Geometry domain
L=15; H=1; B=1; A=H*B; I = B*H^3/12;
interval = nrbline ([0 0],[L 0]);
problem_data.geo_name = interval;

%Boundary conditions
%Left end: Sliding restraint + concentrated force
%Right end: Simple support + moment
problem_data.drchlt1_ends = [false true]; %deflections, homogeneous
problem_data.drchlt2_ends = [true false]; %rotation angles, homogeneous
problem_data.nmnn1_ends   = [true false]; %forces
problem_data.nmnn2_ends   = [false true]; %moments

M(1) = 0; M(2) = 10;
P = 3;
problem_data.M = M; %moment values
problem_data.P = P; %force value

f_c = 0.5;
problem_data.f = @(x) f_c * sin(pi*x/L); %distributed loading

%Physical parameters
E   = 210000;
problem_data.EI = @(x) E * I* ones (size (x));

% Discretization parameters
method_data.degree     = 3;     % Degree of the basis functions
method_data.regularity = 2;     % Regularity of the basis functions
method_data.nsub       = 20;     % Number of subdivisions
method_data.nquad      = 5;     % Points for the Gaussian quadrature rule

% Solving
[geometry, msh, space, w] = solve_BE_Beam (problem_data, method_data);

%Postprocessing
%Exact solution
c1 = (L*f_c+P*pi)/(pi*E*I);
c2 = -(L^2*f_c+L*P*pi+M(2)*pi)/(pi*E*I);
c3 = -f_c*L^3/(pi^3*E*I);
c4 = L^2*(2*L^2*pi^2*f_c+2*L*P*pi^3+3*M(2)*pi^3+6*L^2*f_c)/(pi^3*E*I*6);

w_ex = @(x) f_c*sin(pi*x/L)/E/I*(L/pi)^4 + c1*x.^3/6 + c2*x.^2/2 + c3*x + c4;
%Gradient of exact solution
gradwex = @(x) f_c*cos(pi*x/L)/E/I*(L/pi)^3 + c1*x.^2/2 + c2*x + c3;
%Hessian of exact solution
hesswex = @(x) -f_c*sin(pi*x/L)/E/I*(L/pi)^2 + c1*x + c2;

%L2, H1 and H2 norms of error

[errh2, errh1, errl2] = sp_h2_error (space, msh, w, w_ex, gradwex, hesswex);
errors = [errh2, errh1, errl2]
[normh2, normh1, norml2] = sp_h2_error (space, msh, zeros (size (w)), w_ex, gradwex, hesswex);
relative_errors = [errh2/normh2, errh1/normh1, errl2/norml2]

[eu, F] = sp_eval (w, space, geometry, 100);
han = figure;
plot(F,eu,F,w_ex(F),'--')
legend('FEM-solution', 'Exact solution')
xlabel('x')
ylabel('w')

%!test
%! ex_BE_beam_static
%! close (han)
%! assert (errors, [1.65638054386650e-06 1.95594407043227e-07 4.14113201313776e-08], 2e-11);
%! assert (relative_errors, [1.31307379889248e-06 1.55064145756187e-07 3.30097917469054e-08], 2e-11);


function [energy, kinetic, potential] = energy_3_link(z,P)
%[ENERGY, KINETIC, POTENTIAL] = ENERGY_3_LINK(Z,P)
%
%FUNCTION:  This function computes the energy of a double
%    pendulum.
%INPUTS:
%
%
%OUTPUTS:
%    energy = [1 X nTime] vector of total energy
%    kinetic = [1 X nTime] vector of kinetic energy
%    potential = [1 X nTime] vector of potential energy
%
%NOTES:
%    This file was automatically generated by writeEnergy.m

g  = P.g ; %gravity
m1 = P.m(1); % Link 1 mass
m2 = P.m(2); % Link 2 mass
m3 = P.m(3); % Link 3 mass
l1 = P.l(1); % Link 1 length
l2 = P.l(2); % Link 2 length
l3 = P.l(3); % Link 3 length
I1 = P.I(1); % Link 1 moment of inertia about its center of mass
I2 = P.I(2); % Link 2 moment of inertia about its center of mass
I3 = P.I(3); % Link 3 moment of inertia about its center of mass
d1 = P.d(1); % Link 1 distance between center of mass and parent joint
d2 = P.d(2); % Link 2 distance between center of mass and parent joint
d3 = P.d(3); % Link 3 distance between center of mass and parent joint

th1 = z(1,:);
th2 = z(2,:);
th3 = z(3,:);

dth1 = z(4,:);
dth2 = z(5,:);
dth3 = z(6,:);

kinetic = (I1.*dth1.^2)./2 + (I2.*dth2.^2)./2 + (I3.*dth3.^2)./2 + (m1.*(d1.^2.*dth1.^2.*cos(th1).^2 + d1.^2.*dth1.^2.*sin(th1).^2))./2 + (m2.*((dth1.*l1.*cos(th1) + d2.*dth2.*cos(th2)).^2 + (d2.*dth2.*sin(th2) + dth1.*l1.*sin(th1)).^2))./2 + (m3.*((dth1.*l1.*cos(th1) + dth2.*l2.*cos(th2) + d3.*dth3.*cos(th3)).^2 + (d3.*dth3.*sin(th3) + dth1.*l1.*sin(th1) + dth2.*l2.*sin(th2)).^2))./2;
potential = g.*m3.*(d3.*sin(th3) + l1.*sin(th1) + l2.*sin(th2)) + g.*m2.*(d2.*sin(th2) + l1.*sin(th1)) + d1.*g.*m1.*sin(th1);
energy = potential + kinetic;

end


function E = r8mat_expm3 ( A )

%*****************************************************************************80
%
%% R8MAT_EXPM3 approximates the matrix exponential using an eigenvalue approach.
%
%  Discussion:
%
%    exp(A) = V * D * V
%
%    where V is the matrix of eigenvectors of A, and D is the diagonal matrix
%    whose i-th diagonal entry is exp(lambda(i)), for lambda(i) an eigenvalue
%    of A.
%
%    This function is accurate for matrices which are symmetric, orthogonal,
%    or normal.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2011
%
%  Author:
%
%    Cleve Moler, Charles Van Loan
%
%  Reference:
%
%    Cleve Moler, Charles VanLoan,
%    Nineteen Dubious Ways to Compute the Exponential of a Matrix,
%    Twenty-Five Years Later,
%    SIAM Review,
%    Volume 45, Number 1, March 2003, pages 3-49.
%
%  Parameters:
%
%    Input, real A(N,N), the matrix.
%
%    Output, real E(N,N), the estimate for exp(A).
%
  [ V, D ] = eig ( A );
  E = V * diag ( exp ( diag ( D ) ) ) / V;

  return
end


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];
temp = sigmoid(X * Theta1');
temp = [ones(m, 1) temp];
r = sigmoid(temp * Theta2');
for i = 1:m
    [~, temp] = max(r(i, :));
    p(i) = temp;
end

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

end


function n = hex_grid_01_n ( nodes_per_layer )

%*****************************************************************************80
%
%% HEX_GRID_01_N computes the number of unit square hex grid points.
%
%  Discussion:
%
%    This routine determines the value of N, the number of
%    hex grid points, from the fundamental hexagonal grid
%    parameter NODES_PER_LAYER.
%
%    A hexagonal grid is defined in the unit square [0,1] x [0,1].
%
%    All nodes of the grid lie on one of LAYERS horizontal lines.
%    The first of these lines is the X axis, and each successive
%    line is HY units higher.
%
%    On all the odd numbered lines, there are NODES_PER_LAYER points,
%    equally spaced from 0 to 1, with a spacing of HX.
%
%    On the even numbered lines, there are NODES_PER_LAYER-1 points,
%    whose values are the midpoints of successive intervals on
%    an odd numbered line.  (The grid is staggered).
%
%    HY = HX * sqrt ( 3 ) / 2.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 March 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NODES_PER_LAYER, the number of grid points on the first
%    horizontal layer of points.
%
%    Output, integer N, the number of hex grid points.
%
  if ( nodes_per_layer < 1 )

    n = 0;

  elseif ( nodes_per_layer == 1 )

    n = 1;

  else

    layers = hex_grid_01_layers ( nodes_per_layer );

    n = nodes_per_layer       * floor ( ( layers + 1 ) / 2 ) + ...
      ( nodes_per_layer - 1 ) * floor ( ( layers     ) / 2 );

  end

  return
end


function fx = p25_fun ( n, x )

%*****************************************************************************80
%
%% P25_FUN evaluates the integrand for problem 25.
%
%  Interval:
%
%    0 <= x <= 1.
%
%  Integrand:
%
%    ln ( abs ( x - 0.7 ) )
%
%  Exact Integral:
%
%    0.3 * ln ( 0.3 ) + 0.7 * ln ( 0.7 ) - 1
%
%  Approximate Integral (20 digits):
%
%    -1.6108643020548934630
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 November 2009
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Kendall Atkinson,
%    An Introduction to Numerical Analysis,
%    Prentice Hall, 1984, page 303.
%
%  Parameters:
%
%    Input, integer N, the number of evaluation points.
%
%    Input, real X(N), the evaluation points.
%
%    Output, real FX(N), the integrand values.
%
  fx = log ( abs ( x - 0.7 ) );

  return
end


clear;
clc
close all;

%% EXAMPLE 2.5(a)
 lat = deg2rad(45);
 lon = deg2rad(45);
 hgt = 0;

 vel_ned = [5 5 5]';
 a_ned = [5 0 0]';
 w_ned = [0.001 0 0]';

[R_meridian, R_transverse, Cecef2ned, Cecef2enu]= ch_earth(lat, lon, hgt);

Cned2ecef = Cecef2ned'

%% Velocity transformation
vel_ecef = Cned2ecef *vel_ned;
vel_ecef
%% Acceleration transformation
a_ecef = Cned2ecef*a_ned;
a_ecef
%% Angular rate transformation
w_ecef = Cned2ecef*w_ned;
w_ecef

%% EXAMPLE 2.5(b)
vel_ecef = [-8.53553391 -1.4644609 4.44089E-16]';
a_ecef = [-2.5 -2.5 3.535534]';
w_ecef = [-0.0005 -0.0005 0.000708]';
lat = deg2rad(45);
lon = deg2rad(45);
h = 0;
[~, ~, Cecef2ned, ~]= ch_earth(lat, lon, hgt);

%% Velocity transformation
v_ned = Cecef2ned*vel_ecef;
v_ned
%% Acceleration transformation
a_ned = Cecef2ned*a_ecef;
a_ned
%% Angular rate transformation
w_ned = Cecef2ned*w_ecef;
w_ned


%DEMO_OFDM  Demo of Gabor systems used for OFDM
%
%   This demo shows how to use a Gabor Riesz basis for OFDM.
%
%   We want to transmit a signal consisting of 0's and 1's through a
%   noisy communication channel. This is accomplished in the following
%   steps in the demo:
%
%     1) Convert this digital signal into complex valued coefficients by
%        QAM modulation.
%
%     2) Construct the signal to be transmitted by an inverse Gabor
%        transform of the complex coefficients
%
%     3) "Transmit" the signal by applying a spreading operator to the
%        signal and adding white noise
%
%     4) Convert the received signal into noisy coefficients by a Gabor
%        transform
%
%     5) Convert the noisy coefficients into bits by inverse QAM.
%
%   Some simplifications used to make this demo simple:
%
%     * We assume that the whole spectrum is available for transmission.
%
%     * The window and its dual have full length support. This is not
%       practical, because all data would have to be processed at once.
%       Instead, an FIR should be used, with both the window and its dual
%       having a short length.
%
%     * The window is periodic. The data at the very end interferes with
%       the data at the very beginning. A simple way to solve this is to
%       transmit zeros at the beginning and at the end, to flush the system
%       properly.
%
%   .. figure::
%
%      Received coefficients.
%
%      This figure shows the distribution in the complex plane of the
%      received coefficients. If the channel was perfect, all the points
%      should appear at the complex roots of unity (1,i,-1 and -i). This
%      demo is random, so everytime it is run it produces a new plot, and
%      the error rate may vary.
%

disp('Type "help demo_ofdm" to see a description of how this demo works.');
%% ----------- setup of signal and transmission system --------------------

% Number of channels to use
M=20;

% Time-distance between succesive transmission. This must be
% larger than M, otherwise the symbols will interfere.
a=24;

% Number of bits to transmit, must be divisable by 2*M
nbits=16000;

% Length (in samples) of transmitted signal.
L=nbits/(2*M)*a;

% We choose an orthonormal window.
g=gabtight(a,M,L);

%% ----------- Setup of communication channel ---------------------------

% Larger means more random
howrandom=.3;

% Rate of decay away from (1,1). Larger means smaller spread (faster decay).
spreaddecay=1.2;

% Noiselevel for the channel.
noiselevel=0.05;

% Define the symbol of the spreading operator
symbol=sparse(L,L);
for ii=1:3
  for jj=1:3
    symbol(ii,jj)=(1-abs(randn(1)*howrandom))*exp(-(ii+jj-1)*spreaddecay);
  end;
end;

% Make the symbol conserve real signals.
symbol=(symbol+involute(symbol))/2;

% Make sure that energy is conserved
symbol=symbol/sum(abs(symbol(:)));

%% ------------ Convert input data into analog signal -------------------

% Create a random stream of bits.
inputdata=round(rand(nbits,1));

% QAM modulate it
transmitdata=qam4(inputdata);

% Create the signal to be tranmitted
f=idgt(reshape(transmitdata,M,[]),g,a);

% --- transmission of signal - influence of the channel ----------

% Apply the underspread operator.
f=spreadop(f,symbol);

% add white noise.
noise = ((randn(size(f))-.5)+i*(randn(size(f))-.5));
f=f+noise*noiselevel/norm(noise)*norm(f);

% --- reconstruction of received signal ------------------------

% Obtain the noisy coefficients from the transmitted signal
receivedcoefficients = dgt(f,g,a,M);

% Convert the analog signal to the digital coefficients by inverse QAM
receivedbits=iqam4(receivedcoefficients(:));

%% --- visualization and print output -------------------------

% Plot the coefficients in the complex plane.
figure(1);
plot(receivedcoefficients(:),'.');
axis([-1 1 -1 1]);

% Test for errors.

disp(' ');
disp('Number of faulty bits:');
faulty=sum(abs(receivedbits-inputdata))

disp(' ');
disp('Error rate:');
faulty/nbits


function f = local_xy ( x , y )

%*****************************************************************************80
%
%% LOCAL_XY computes the local minimum function.
%
%  Discussion:
%
%    This function has a local minimum:
%
%      X* = (  0.28581..., 0.27936...), F(X*) = 5.9225...
%
%    and a global minimum:
%
%      X* = (  -21.026653..., -36.760090...), F(X*) = 0.
%
%    Suggested starting point:
%
%      X = ( 1, 1 ), F(X) = 3.33 * 10^6.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    12 February 2008
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    David Himmelblau,
%    Applied Nonlinear Programming,
%    McGraw Hill, 1972,
%    ISBN13: 978-0070289215,
%    LC: T57.8.H55.
%
%  Parameters:
%
%    Input, real X, Y, the argument of the function.
%
%    Output, real F, the value of the function at (X,Y).
%
  f = ( x^2 + 12 * y - 1 )^2 ...
    + ( 49 * x^2 + 49 * y^2 + 84 * x + 2324 * y - 681 )^2;

  return
end


function loc=RLSloc(X)
%Syntax: loc=RLSloc(X)
%_____________________
%
% Calculates the Reweighterd Least Squares (RLS) location parameter
% of the columns of a matrix X. If X is a vector, it returns the RLS
% location parameter of its components. If X is a scalar, it returns
% X.
%
% loc is the RLS estimated vector of locations.
% X is the matrix with the data sets.
%
% Reference:
% Rousseeuw PJ, Leroy AM (1987): Robust regression and outlier detection. Wiley.
%
%
% Alexandros Leontitsis
% Institute of Mathematics and Statistics
% University of Kent at Canterbury
% Canterbury
% Kent, CT2 7NF
% U.K.
%
% University e-mail: al10@ukc.ac.uk (until December 2002)
% Lifetime e-mail: leoaleq@yahoo.com
% Homepage: http://www.geocities.com/CapeCanaveral/Lab/1421
%
% Sep 3, 2001.

if nargin<1 | isempty(X)==1
   error('Not enough input arguments.');
else
   % If X is a row vector make it a column vector
   if size(X,1)==1
      X=X';
   end
   % n is the length of the data set
   n=size(X,1);
end

% For a single data point there is no need to proceed
if n==1
   loc=X;
else
   % Find the LMS location parameter
   l=LMSloc(X);
   % Find the LMS scale parameter
   s=LMSsca(X);

   % Calculate the location parameter for every column of X
   for i=1:size(X,2);
      r=X(:,i)-l(i);
      if s(i)==0
         w=1:n;
      else
         w=find(abs(r)/s(i)<=2.5);
      end
      loc(i)=mean(X(w,i));
   end
end


function [neighborIds neighborDistances] = kNearestNeighbors(dataMatrix, queryMatrix, k)
%--------------------------------------------------------------------------
% Program to find the k - nearest neighbors (kNN) within a set of points.
% Distance metric used: Euclidean distance
%
% Usage:
% [neighbors distances] = kNearestNeighbors(dataMatrix, queryMatrix, k);
% dataMatrix  (N x D) - N vectors with dimensionality D (within which we search for the nearest neighbors)
% queryMatrix (M x D) - M query vectors with dimensionality D
% k           (1 x 1) - Number of nearest neighbors desired
%
% Example:
% a = [1 1; 2 2; 3 2; 4 4; 5 6];
% b = [1 1; 2 1; 6 2];
% [neighbors distances] = kNearestNeighbors(a,b,2);
%
% Output:
% neighbors =
%      1     2
%      1     2
%      4     3
%
% distances =
%          0    1.4142
%     1.0000    1.0000
%     2.8284    3.0000
%--------------------------------------------------------------------------

neighborIds = zeros(size(queryMatrix,1),k);
neighborDistances = neighborIds;

numDataVectors = size(dataMatrix,1);
numQueryVectors = size(queryMatrix,1);
for i=1:numQueryVectors,
    dist = sum((repmat(queryMatrix(i,:),numDataVectors,1)-dataMatrix).^2,2);
    [sortval sortpos] = sort(dist,'ascend');
    neighborIds(i,:) = sortpos(1:k);
    neighborDistances(i,:) = sqrt(sortval(1:k));
end


function f = local ( x )

%*****************************************************************************80
%
%% LOCAL computes the local function.
%
%  Discussion:
%
%    This function has a local minimizer:
%
%      X* = ( 0.2858054412..., 0.2793263206...), F(X*) = 5.9225...
%
%    and a global minimizer:
%
%      X* = ( -21.02667179..., -36.75997872...), F(X*) = 0.
%
%    Suggested starting point for local minimizer:
%
%      X = ( 1, 1 ), F(X) = 3.33 * 10^6.
%
%    Suggested starting point for global minimizer:
%
%      X = ( -15, -35), F(X) = 1.49 * 10^8.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    David Himmelblau,
%    Applied Nonlinear Programming,
%    McGraw Hill, 1972,
%    ISBN13: 978-0070289215,
%    LC: T57.8.H55.
%
%  Parameters:
%
%    Input, real X(2), the argument of the function.
%
%    Output, real F, the value of the function at X.
%
  if ( length ( x ) ~= 2 )
    error ( 'Error: function expects a two dimensional input\n' );
  end

  f = ( x(1)^2 + 12 * x(2) - 1 )^2 ...
    + ( 49 * x(1)^2 + 49 * x(2)^2 + 84 * x(1) + 2324 * x(2) - 681 )^2;

  return
end


function [ vX, paramLambda ] = SolveLsNormConst( mA, vB, normConst )
% ----------------------------------------------------------------------------------------------- %
%[ vX ] = SolveLsNormConst( mA, vB, normConst )
% Solves norm constrained Least Squares problem by finding the optimal Dual
% Variable (paramLambda) of the KKT Conditions by succesively solving
% Tikhonov Regularized Least Squares problems.
% The objective Funciton is given by:
% \arg \min_{x} \frac{1}{2} {\left\| A x - b \right\|}_{2}^{2}
% subject to {\left\| x \right\|}_{2} \leq normSquaredConst
% Input:
%   - mA                -   Input Matrix.
%                           The given matrix of the problem 0.5 || A x - b|| ^ 2.
%                           Structure: Vector (Column Vector).
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
%   - vB                -   Input Vector.
%                           The given vector of the problem 0.5 || A x - b|| ^ 2.
%                           Structure: Scalar.
%                           Type: 'Single' / 'Double'.
%                           Range: {1, 2, ...}.
%   - normConst         -   Norm Constraint.
%                           The solution must obey || x || <= normConst.
%                           Structure: Scalar.
%                           Type: 'Single' / 'Double'.
%                           Range: (0, inf).
% Output:
%   - vX                -   Solution Vector.
%                           The optimal solution of the problem 0.5 || A x
%                           - b || ^ 2 subject to || x || <= normConst.
%                           Structure: Vector (Column Vector).
%                           Type: 'Single' / 'Double'.
%                           Range: (-inf, inf).
% References
%   1.  See - https://stats.stackexchange.com/questions/401212.
% Remarks:
%   1.  T
% TODO:
%   1.  U
% Release Notes:
%   -   1.0.000     14/04/2019
%       *   First realease version.
% ----------------------------------------------------------------------------------------------- %

paramLambda = 0; %<! Initialization

vX = pinv(mA) * vB;
mI = eye(size(vX, 1));

mAA = mA.' * mA;
mAb = mA.' * vB;

if(norm(vX, 2) <= normConst)
    return;
end

hObjFun = @(paramLambda) norm((mAA + (2 * paramLambda * mI)) \ mAb, 2) - normConst;

paramLambda = fzero(hObjFun, paramLambda);

vX = (mAA + (2 * paramLambda * mI)) \ mAb;

end


function length = polyloop_length_nd ( dim_num, nk, pk )

%*****************************************************************************80
%
%% POLYLOOP_LENGTH_ND computes the length of a polyloop in ND.
%
%  Discussion:
%
%    A polyloop of order NK is the geometric structure consisting of
%    the NK line segments that lie between successive elements of a list
%    of NK points, with the last point joined to the first.
%
%    Warning: I just made up the word "polyloop".
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 March 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer DIM_NUM, the spatial dimension.
%
%    Input, integer NK, the number of points defining the polyloop.
%
%    Input, real PK(DIM_NUM,NK), the points defining the polyloop.
%
%    Output, real LENGTH, the length of the polyloop.
%
  length = 0.0;

  for i = 2 : nk + 1

    if ( i <= nk )
      j = i;
    else
      j = 1;
    end if

    length = length + sqrt ( sum ( ( pk(1:dim_num,j) - pk(1:dim_num,i-1) ).^2 ) );

  end

  return
end


function error_frobenius = inverse_error ( n, a, b )

%*****************************************************************************80
%
%% INVERSE_ERROR determines the error in an inverse matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 October 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, real A(N,N), the matrix.
%
%    Input, real B(N,N), the inverse.
%
%    Output, real ERROR_FROBENIUS, the Frobenius norm
%    of (A*B-I) + (B*A-I).
%
  error_frobenius = norm ( a * b - eye ( n ), 'fro' ) ...
                  + norm ( b * a - eye ( n ), 'fro' );

  return
end


function mu = truncgaussmf(z,a,b,s)
%TRUNCGAUSSMF Truncated Gaussian membership function.
%   MU = TRUNCGAUSSMF(Z,A,B,S) computes a truncated Gaussian fuzzy
%   membership function. Z is the input variable and can be a vector of
%   any length. A, B, and S are scalar shape parameters. A and B have to
%   be ordered such that A <= B.
%
%       MU = exp(-(Z - B).^2/(2*s^2))   abs(Z - B) <= (B - A)
%       MU = 0                          otherwise
%
%   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

mu = zeros(size(z));

c = a + 2*(b - a);
range = (a <= z) & (z <= c);
mu(range) = exp(-(z(range) - b).^2/(2*s^2));


function value = r8mat_norm_fro ( m, n, a )

%*****************************************************************************80
%
%% R8MAT_NORM_FRO returns the Frobenius norm of an R8MAT.
%
%  Discussion:
%
%    The Frobenius norm is defined as
%
%      value = sqrt ( sum ( 1 <= I <= M ) sum ( 1 <= j <= N ) A(I,J)**2 )
%
%    The matrix Frobenius norm is not derived from a vector norm, but
%    is compatible with the vector L2 norm, so that:
%
%      vec_norm_l2 ( A * x ) <= mat_norm_fro ( A ) * vec_norm_l2 ( x ).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    24 April 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, the number of rows in A.
%
%    Input, integer N, the number of columns in A.
%
%    Input, real A(M,N), the matrix whose Frobenius
%    norm is desired.
%
%    Output, real VALUE, the Frobenius norm of A.
%
  value = sqrt ( sum ( sum ( a(1:m,1:n).^2 ) ) );

  return
end


function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
%GRADIENTDESCENTMULTI Performs gradient descent to learn theta
%   theta = GRADIENTDESCENTMULTI(x, y, theta, alpha, num_iters) updates theta by
%   taking num_iters gradient steps with learning rate alpha

% Initialize some useful values
m = length(y); % number of training examples
n = size(X , 2);
J_history = zeros(num_iters, 1);

for iter = 1:num_iters

    % ====================== YOUR CODE HERE ======================
    % Instructions: Perform a single gradient step on the parameter vector
    %               theta.
    %
    % Hint: While debugging, it can be useful to print out the values
    %       of the cost function (computeCostMulti) and gradient here.
    %

	H = X * theta;
	T = zeros(n , 1);
	for i = 1 : m,
		T = T + (H(i) - y(i)) * X(i,:)';
	end

	theta = theta - (alpha * T) / m;

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

    % Save the cost J in every iteration
    J_history(iter) = computeCostMulti(X, y, theta);

end

end


function y = nanstd(x, flag, dim)
% nanstd - Standard deviation ignoring NaNs
%
% Synopsis:
%   y = nanstd(x)
%   y = nanstd(x,flag)
%   y = nanstd(x,flag,dim)
%
% Arguments:
%   x: Matrix or vector
%   flag: Logical. Default: false (normalize by N-1). If true: normalize by N
%       (produce the second moment about the mean)
%   dim: Dimension along which to operate
%
% Returns:
%   y: Standard deviation along the chosen dimension
%
% Description:
%   nanstd(X) returns the standard deviation treating NaNs
%   as missing values.
%   For vectors, nanstd(X) is the standard deviation of the
%   non-NaN elements in X.  For matrices, nanstd(X) is a row
%   vector containing the standard deviation of each column,
%   ignoring NaNs.
%
% Examples:
%   nanstd([1 2 NaN]) returns 0.7071 (the same result as std([1 2])
%   nanstd([1 2 NaN; 3 4 5], 1, 1) returns [1 1 0]
%
% See also: nanmean,nansum
%

% Author(s): Anton Schwaighofer, Feb 2005

if nargin<3,
  % Operate along the first non-singleton dimension
  dim = min(find(size(x)~=1));
  if isempty(dim),
    dim = 1;
  end
end
if nargin<2,
  flag = 0;
end
if isempty(x),
  y = 0/0;
  return;
end
tile = ones(1, max(ndims(x), dim));
tile(dim) = size(x,dim);
% Effective number of non-NaNs
effSize = size(x,dim)-sum(isnan(x),dim);
% Remove mean, also ignoring NaNs
xc = x - repmat(nanmean(x, dim), tile);
if flag,
  y = sqrt(nansum(conj(xc).*xc, dim)./effSize);
else
  y = sqrt(nansum(conj(xc).*xc, dim)./(effSize-1));
  % Simulate the behaviour of std: if only one sample, output 0
  y(effSize==1) = 0;
end


function a = mass_matrix_t3 ( node_num, element_num, element_node, x, y )

%*****************************************************************************80
%
%% MASS_MATRIX_T3 computes the mass matrix, using 3-node triangles.
%
%  Discussion:
%
%    The mass matrix to be estimated has the form:
%
%      A(I,J) = integral ( PHI(I)(X,Y) * PHI(J)(X,Y) ) d Region
%
%    where PHI(I) and PHI(J) are the shape functions associated with
%    the I-th and J-th variables.
%
%  Referene Element T6:
%
%    |
%    1  3
%    |  |\
%    |  | \
%    S  |  \
%    |  |   \
%    |  |    \
%    0  1-----2
%    |
%    +--0--R--1-->
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 January 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NODE_NUM, the number of nodes.
%
%    Input, integer ELEMENT_NUM, the number of elements.
%
%    Input, integer ELEMENT_NODE(3,ELEMENT_NUM), the nodes that make
%    up each element.
%
%    Input, real X(NODE_NUM), Y(NODE_NUM), the coordinates
%    of the nodes.
%
%    Output, real A(NODE_NUM,NODE_NUM), the mass matrix.
%
  element_order = 3;
%
%  Zero out the matrix.
%
  a(1:node_num,1:node_num) = 0.0;
%
%  Get the weights and abscissas for a unit triangle.
%
  rule = 4;
  quad_num = triangle_unit_size ( rule );
  [ rtab, stab, weight ] = triangle_unit_set ( rule );
%
%  For each element.
%
  for element = 1 : element_num

    p1 = element_node(1,element);
    p2 = element_node(2,element);
    p3 = element_node(3,element);

    area = 0.5 * abs ( ...
        x(p1) * ( y(p2) - y(p3) ) ...
      + x(p2) * ( y(p3) - y(p1) ) ...
      + x(p3) * ( y(p1) - y(p2) ) );

    if ( area == 0.0 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'MASS_MATRIX_T3 - Fatal error!\n' );
      fprintf ( 1, '  Zero area for element %d\n', element );
      error ( 'MASS_MATRIX_T3 - Fatal error!' );
    end
%
%  For each quadrature point in the element...
%
    for quad = 1 : quad_num

      r = rtab(quad);
      s = stab(quad);

      [ w, dwdr, dwds ] = shape_t3 ( r, s );
%
%  For each basis function PHI(I) associated with a node in the element,
%
      for iq = 1 : element_order

        ip = element_node(iq,element);
%
%  For each "neighbor" basis function PHI(J) associated with a node in
%  the element.
%
        for jq = 1 : element_order

          jp = element_node(jq,element);

          a(ip,jp) = a(ip,jp) + area * weight(quad) * w(iq) * w(jq);

        end
      end
    end
  end

  return
end


function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
%GRADIENTDESCENTMULTI Performs gradient descent to learn theta
%   theta = GRADIENTDESCENTMULTI(x, y, theta, alpha, num_iters) updates theta by
%   taking num_iters gradient steps with learning rate alpha

% Initialize some useful values
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters

    % ====================== YOUR CODE HERE ======================
    % Instructions: Perform a single gradient step on the parameter vector
    %               theta.
    %
    % Hint: While debugging, it can be useful to print out the values
    %       of the cost function (computeCost) and gradient here.
    %

    h = X * theta;
    errors = h - y;
    delta = X' * errors;
    theta = theta - (alpha / m) * delta;

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

    % Save the cost J in every iteration
    J_history(iter) = computeCost(X, y, theta);

end

end


function p = predict(theta, X)
%PREDICT Predict whether the label is 0 or 1 using learned logistic
%regression parameters theta
%   p = PREDICT(theta, X) computes the predictions for X using a
%   threshold at 0.5 (i.e., if sigmoid(theta'*x) >= 0.5, predict 1)

m = size(X, 1); % Number of training examples

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

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned logistic regression parameters.
%               You should set p to a vector of 0's and 1's
%

p = sigmoid(X * theta)>=0.5 ;

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

end


function exactness_test08 ( )

%*****************************************************************************80
%
%% EXACTNESS_TEST08 tests Gauss-Chebyshev1 rules for the Chebyshev1 integral.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 May 2014
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'EXACTNESS_TEST08\n' );
  fprintf ( 1, '  Test Gauss-Chebyshev1 rules for the Chebyshev1 integral.\n' );
  fprintf ( 1, '  Density function rho(x) = 1/sqrt(1-x^2).\n' );
  fprintf ( 1, '  Region: -1 <= x <= +1.\n' );
  fprintf ( 1, '  Exactness: 2*N-1.\n' );

  for n = 1 : 5

    [ x, w ] = chebyshev1_set ( n );
    p_max = 2 * n;
    chebyshev1_exactness ( n, x, w, p_max );

  end

  return
end


function l = l1dd_inverse ( n, h )

%*****************************************************************************80
%
%% L1DD_INVERSE stores the inverse of the 1D DD Laplacian.
%
%  Discussion:
%
%    The N grid points are assumed to be evenly spaced by H.
%
%    For N = 5, the discrete Laplacian with Dirichlet boundary conditions
%    at both ends of [0,6] has the matrix form L:
%
%       2 -1  0  0  0
%      -1  2 -1  0  0
%       0 -1  2 -1  0
%       0  0 -1  2 -1
%       0  0  0 -1  2
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 October 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of points.
%    N must be at least 3.
%
%    Input, real H, the spacing between points.
%
%    Output, real L(N,N), the inverse of the Laplacian matrix.
%
  if ( n < 3 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'L1DD_INVERSE - Fatal error!\n' );
    fprintf ( 1, '  N < 3.\n' );
    error ( 'L1DD_INVERSE - Fatal error!' );
  end

  l = zeros ( n, n );

  for j = 1 : n
    for i = 1 : n
      l(i,j) = min ( i, j ) * ( n + 1 - max ( i, j ) ) * h * h / ( n + 1 );
    end
  end

  return
end


%% Machine Learning Online Class - Exercise 2: Logistic Regression
%
%  Instructions
%  ------------
%
%  This file contains code that helps you get started on the logistic
%  regression exercise. You will need to complete the following functions
%  in this exericse:
%
%     sigmoid.m
%     costFunction.m
%     predict.m
%     costFunctionReg.m
%
%  For this exercise, you will not need to change any code in this file,
%  or any other files other than those mentioned above.
%

%% Initialization
clear ; close all; clc

%% Load Data
%  The first two columns contains the exam scores and the third column
%  contains the label.

data = load('ex2data1.txt');
X = data(:, [1, 2]); y = data(:, 3);

%% ==================== Part 1: Plotting ====================
%  We start the exercise by first plotting the data to understand the
%  the problem we are working with.

fprintf(['Plotting data with + indicating (y = 1) examples and o ' ...
         'indicating (y = 0) examples.\n']);

plotData(X, y);

% Put some labels
hold on;
% Labels and Legend
xlabel('Exam 1 score')
ylabel('Exam 2 score')

% Specified in plot order
legend('Admitted', 'Not admitted')
hold off;

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============ Part 2: Compute Cost and Gradient ============
%  In this part of the exercise, you will implement the cost and gradient
%  for logistic regression. You neeed to complete the code in
%  costFunction.m

%  Setup the data matrix appropriately, and add ones for the intercept term
[m, n] = size(X);

% Add intercept term to x and X_test
X = [ones(m, 1) X];

% Initialize fitting parameters
initial_theta = zeros(n + 1, 1);

% Compute and display initial cost and gradient
[cost, grad] = costFunction(initial_theta, X, y);

fprintf('Cost at initial theta (zeros): %f\n', cost);
fprintf('Gradient at initial theta (zeros): \n');
fprintf(' %f \n', grad);

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============= Part 3: Optimizing using fminunc  =============
%  In this exercise, you will use a built-in function (fminunc) to find the
%  optimal parameters theta.

%  Set options for fminunc
options = optimset('GradObj', 'on', 'MaxIter', 400);

%  Run fminunc to obtain the optimal theta
%  This function will return theta and the cost
[theta, cost] = ...
	fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);

% Print theta to screen
fprintf('Cost at theta found by fminunc: %f\n', cost);
fprintf('theta: \n');
fprintf(' %f \n', theta);

% Plot Boundary
plotDecisionBoundary(theta, X, y);

% Put some labels
hold on;
% Labels and Legend
xlabel('Exam 1 score')
ylabel('Exam 2 score')

% Specified in plot order
legend('Admitted', 'Not admitted')
hold off;

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

%% ============== Part 4: Predict and Accuracies ==============
%  After learning the parameters, you'll like to use it to predict the outcomes
%  on unseen data. In this part, you will use the logistic regression model
%  to predict the probability that a student with score 45 on exam 1 and
%  score 85 on exam 2 will be admitted.
%
%  Furthermore, you will compute the training and test set accuracies of
%  our model.
%
%  Your task is to complete the code in predict.m

%  Predict probability for a student with score 45 on exam 1
%  and score 85 on exam 2

prob = sigmoid([1 45 85] * theta);
fprintf(['For a student with scores 45 and 85, we predict an admission ' ...
         'probability of %f\n\n'], prob);

% Compute accuracy on our training set
p = predict(theta, X);

fprintf('Train Accuracy: %f\n', mean(double(p == y)) * 100);

fprintf('\nProgram paused. Press enter to continue.\n');
pause;

github-repos/MATLAB/Borye-machine-learning-coursera-1/machine-learning-coursera-1-033fdc2e6da393eeb1179a09aafe92362021effb/Week 3 Assignments/Logistic Regression and Regularization/mlclass-ex2/ex2.m


function a = cauchy ( n, x, y )

%*****************************************************************************80
%
%% CAUCHY returns the CAUCHY matrix.
%
%  Formula:
%
%    A(I,J) = 1.0 / ( X(I) + Y(J) )
%
%  Example:
%
%    N = 5, X = ( 1, 3, 5, 8, 7 ), Y = ( 2, 4, 6, 10, 9 )
%
%    1/3  1/5  1/7  1/11 1/10
%    1/5  1/7  1/9  1/13 1/12
%    1/7  1/9  1/11 1/15 1/14
%    1/10 1/12 1/14 1/18 1/17
%    1/9  1/11 1/13 1/17 1/16
%
%    or, in decimal form,
%
%    0.333333      0.200000      0.142857      0.0909091     0.100000
%    0.200000      0.142857      0.111111      0.0769231     0.0833333
%    0.142857      0.111111      0.0909091     0.0666667     0.0714286
%    0.100000      0.0833333     0.0714286     0.0555556     0.0588235
%    0.111111      0.0909091     0.0769231     0.0588235     0.0625000
%
%  Properties:
%
%    A is generally not symmetric: A' /= A.
%
%    A is totally positive if 0 < X(1) < ... < X(N) and 0 < Y1 < ... < Y(N).
%
%    A will be singular if any X(I) equals X(J), or
%    any Y(I) equals Y(J), or if any X(I)+Y(J) equals zero.
%
%    A is generally not normal: A' * A /= A * A'.
%
%    The Hilbert matrix is a special case of the Cauchy matrix.
%
%    The Parter matrix is a special case of the Cauchy matrix.
%
%    The Ris or "ding-dong" matrix is a special case of the Cauchy matrix.
%
%    det ( A ) = product ( 1 <= I < J <= N ) ( X(J) - X(I) )* ( Y(J) - Y(I) )
%           / product ( 1 <= I <= N, 1 <= J <= N ) ( X(I) + Y(J) )
%
%    The inverse of A is
%
%      INVERSE(A)(I,J) = product ( 1 <= K <= N ) [ (X(J)+Y(K)) * (X(K)+Y(I)) ] /
%            [ (X(J)+Y(I)) * product ( 1 <= K <= N, K /= J ) (X(J)-X(K))
%                          * product ( 1 <= K <= N, K /= I ) (Y(I)-Y(K)) ]
%
%    The family of matrices is nested as a function of N.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 January 2015
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Robert Gregory, David Karney,
%    Example 3.26,
%    A Collection of Matrices for Testing Computational Algorithms,
%    Wiley, New York, 1969, page 54,
%    LC: QA263.G68.
%
%    Nicholas Higham,
%    Accuracy and Stability of Numerical Algorithms,
%    SIAM, 1996.
%
%    Donald Knuth,
%    The Art of Computer Programming,
%    Volume 1, Fundamental Algorithms, Second Edition
%    Addison-Wesley, Reading, Massachusetts, 1973, page 36.
%
%    Olga Taussky, Marvin Marcus,
%    Eigenvalues of finite matrices,
%    in Survey of Numerical Analysis,
%    Edited by John Todd,
%    McGraw-Hill, New York, pages 279-313, 1962.
%
%    Evgeny Tyrtyshnikov,
%    Cauchy-Toeplitz matrices and some applications,
%    Linear Algebra and Applications,
%    Volume 149, 1991, pages 1-18.
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Input, real X(N), Y(N), vectors that determine A.
%
%    Output, real A(N,N), the matrix.
%
  for i = 1 : n

    for j = 1 : n

      if ( x(i) + y(j) == 0.0 )
        fprintf ( 1, '\n' );
        fprintf ( 1, 'CAUCHY - Fatal error!\n' );
        fprintf ( 1, '  The denominator X(I)+Y(J) was zero\n' );
        fprintf ( 1, '  for I = %d\n', i );
        fprintf ( 1, '  X(I)  = %g\n', x(i) );
        fprintf ( 1, '  and J = %d\n', j );
        fprintf ( 1, '  Y(J)  = %g\n', y(j) );
        error ( 'CAUCHY - Fatal error!' );
      end

      a(i,j) = 1.0 / ( x(i) + y(j) );

    end
  end

  return
end


function p=unrankTComposition(theRank,t,n,firstElMostSig)
%%UNRANKTCOMPOSITION Return the composition of the given theRank, starting
%                   from zero, of n unlabeled items in t parts. That is, a
%                   method of putting n unlabeled balls into t labeled
%                   slots. Compositions are tuples of t integers >=1 that
%                   sum to n. Compositions are given in lexicographic order
%                   where the first element is the least significant unless
%                   otherwise specified.
%
%INPUTS: theRank The theRank (position in an ordered sequence) of the
%                desired composition starting from zero. There is a total
%                of binomial(n-1,t-1) compositions.
%              t The number of slots that can hold items, >=1.
%              n The number of items that are composed into slots, >=1;
%                n>=t
% firstElMostSig An optional parameter specifying whether the first
%                element is the most or least significant. The default if
%                omitted or an empty matrix is passed is false (the first
%                element is the least significant).
%
%OUTPUTS: p A tX1 vector holding the current composition, whose elements
%           sum to n. Each element is the number of "balls" in that slot.
%           If theRank is larger than the maximum number of compositions,
%           an empty matrix is returned. The values of q can range from 0
%           to n.
%
%This is an implementation of the relation described in Chapter 7.2.1.3 of
%[1] for mapping combinations to compositions. theRank is used to obtain a
%combination in lexicographic order (p(1) is the least significant
%element) and the elements of the combination are mapped to the equivalent
%composition. However, a special case is if the input is one-dimensional,
%in which case the only composition is for theRank=0 and the value is n.
%
%REFERENCES:
%[1] D. E. Knuth, The Art of Computer Programming. Vol. 4, Fascicle 3:
%    Generating all Combinations and Partitions, Upper Saddle River, NJ:
%    Addison-Wesley, 2009.
%
%October 2013 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(nargin<4||isempty(firstElMostSig))
    firstElMostSig=false;
end

n=n-1;
nCombo=n;
tCombo=t-1;

if(tCombo>0)
    c=unrankCombination(theRank,nCombo,tCombo);

    if(isempty(c))
        p=[];
        return;
    end

    %Transform the combination into a valid composition.
    p=zeros(t,1);
    p(1)=c(1)+1;
    for curIdx=2:tCombo
        p(curIdx)=c(curIdx)-c(curIdx-1);
    end
    p(t)=n-c(tCombo);
else%The t=1 case has to be handled separately.
    if(theRank==0)
        p=n+1;
    else
        p=[];
    end
end

if(firstElMostSig)
   p=flipud(p(:));
end

end

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


function [H] = lpfilter(type,M,N,D0,n)
%LPFILTER Computes freq. domain lowpass filters
%		THIS IS NOT A STANDARD MATLAB FUNCTION
%		H = lpfilter (type,M,N,D0,n) creates the
%		transfer function of a lowpass filter, H, of
%		the specified type and size MxN. Acceptable
%		values for type, D0, and n are:
%
%				'ideal'				Ideal lowpass filter with
%									cutoff frequency D0. If
%									supplied, n is ignored.
%				'btw'				Butterworth lowpass filter
%									of order n, and cutoff D0.
%				'gauss'			    Gaussian lowpass filter with
%									cutoff (standard deviation)D0.
%									If supplied, n is ignored.
%		M and N should be even numbers for DFT
%		filtering.
%
%		Class support: double, uint8, uint16
%		The output is of class double

%		Verify the number of inputs

error(nargchk(4,5,nargin));

%		Issue warning if M or N not even

L1 = M/2;
L2 = N/2;
if((L1-round(L1)) | (L2-round(L2)))
		disp('Warning: M & N must be even for DFT filtering')
end

%		Set up meshgrid to compute filter functions
%		running from 0 to M-1 and 0 to N-1. But,
%		recall that U and V run from 1 to M and 1 to N,
%		repectively.  See Section 2.10.4 for an
%		explanation of meshgrid. Recall also that
%		meshgrid reverses the order of rows and
%		columns, so the final result must be transposed
%		in order to preserve the original order of
%		of the coordinates.

[U,V] = meshgrid(0:M-1,0:N-1);

%   Compute the filter center

U0=L1;
V0=L2;

%		Compute distances D(U,V)

D=((U-U0).^2 + (V-V0).^2).^0.5;

%		Begin filter computations

switch type
	case 'ideal'
		H = D<=D0;
        H = H';
	case 'btw'
		H = 1./(1 + (D./D0).^(2*n));
        H = H';
	case 'gauss'
		H = exp(-(D.^2)./(2*(D0^2)));
        H = H';
	otherwise
		error('Unknown filter type')
end

%		End of function


function [h,tf]=Jakes_Flat(fd,Ts,Ns,t0,E0,phi_N)
% Inputs:
%   fd      : Doppler frequency
%   Ts      : sampling period
%   Ns      : number of samples
%   t0      : initial time
%   E0      : channel power
%   phi_N  : inital phase of the maximum doppler frequency sinusoid
% Outputs:
%   h       : complex fading vector
%   t_state: current time
if nargin<6
    phi_N=0;
end
if nargin<5
    E0=1;
end
if nargin<4
    t0=0;
end
if nargin<3
    error('More arguments are needed for Jakes_Flat()');
end
N0=8;                 % As suggested by Jakes
N=4*N0+2;             % an accurate approximation
wd=2*pi*fd;           % Maximum doppler frequency[rad]
%t_state = t0;
%for i=1:Ns
%   ich=sqrt(2)*cos(phi_N)*cos(wd*t_state);
%   qch=sqrt(2)*sin(phi_N)*cos(wd*t_state);
%   for k=1:N0
%      phi_n=pi*k/(N0+1);
%      wn=wd*cos(2*pi*k/N);
%      ich=ich+2*cos(phi_n)*cos(wn*t_state);
%      qch=qch+2*sin(phi_n)*cos(wn*t_state);
%   end
%   h1(i) = E0/sqrt(2*N0+1)*complex(ich,qch);
%   t_state=t_state+Ts;             % save last time
%end
t = t0+[0:Ns-1]*Ts;
tf = t(end)+Ts;
coswt = [sqrt(2)*cos(wd*t); 2*cos(wd*cos(2*pi/N*[1:N0]')*t)]; % (2.32)
h = E0/sqrt(2*N0+1)*exp(j*[phi_N pi/(N0+1)*[1:N0]])*coswt;
% discrepancy = norm(h-h1)


function [average, weight] = CrossWeightAverage(DATA,WEIGHT)
% =========================================================================
% Compute the weighted average of DATA, computing the weights form the
% matrix WEIGHT. Note that if there are NaNs in DATA the weights are
% rescaled. WEIGHTS CANNOT contain NaN
% =========================================================================
% [average, weight] = CrossWeightAverage(DATA,WEIGHT)
% -------------------------------------------------------------------------
% INPUT
%	- DATA: panel of time series DATA(T,N) of T observation x N series
%       (NaN are accepted and weights rescaled)
%   - WEIGHT: time series of FLOWS or WEIGHTS (TxN). You can also
%       provide a (1xN) matrix in this case the code would automatically
%       compute fixed weights
% -------------------------------------------------------------------------
% OUTPUT
%	- average : weighted average vector (T x 1)
%	- weight  : matrix of weights (T x N)
% =========================================================================
% Example 1: foreign variables as in GVAR (example with fixed weights)
% x = [1 NaN  3 ;
%      2   3  4 ;
%      3   4  5 ;
%      4   5  6];
% w = [0  .4 .6];
% [average, weight] = CrossWeightAverage(x,w)
% -------------------------------------------------------------------------
% Example 2: weighted average (with time-varying weights)
% x = [ 1 NaN   3 ;
%       2   3   4 ;
%       3   4   5 ;
%       4   5   6];
% w = [.4  .2  .4 ;
%      .3  .4  .3 ;
%      .4  .3  .3 ;
%      .5  .3  .2];
% [average, weight] = CrossWeightAverage(x,w)
% =========================================================================
% Ambrogio Cesa Bianchi, March 2015

%% Preliminaries
% Check inputs
[r1, c1] = size(DATA);
[r2, c2] = size(WEIGHT);
if r2==1 && c2==c1
    % Create a matrix of fixed weights
    aux = [];
    for ii=1:r1
        aux = [aux; WEIGHT];
    end
    WEIGHT = aux;
end

% Re-Check inputs
[r1, c1] = size(DATA);
[r2, c2] = size(WEIGHT);
if r1~=r2 || c1~=c2
    disp(' ')
    disp('The matrices of data and weights are not conformable.')
    return
end

%% Cross section weihgted average
[nobs, nvars] = size(DATA);
nans = isnan(DATA);
WEIGHT(nans) = NaN;

average(1:nobs,1) = NaN;
weight(1:nobs,1:nvars) = NaN;

for ii=1:nobs
    aux_weight = WEIGHT(ii,:)./nansum(WEIGHT(ii,:));
    weight(ii,:) = aux_weight;
    aux_weight(nans(ii,:)) = 0;
    DATA(ii,nans(ii,:)) = 0;
    average(ii,1) = DATA(ii,:) * aux_weight';
end


function intVal=monomialIntPrism(alpha)
%%MONOMIALINTPRISM Evaluate the integral of prod_{i=1}^3 x(i)^alpha(i)
%  over a standard prism in 3D. This is a triangle that has been extruded
%  upward. The vertices are (1,-1,-1), (-1,-1,-1), (-1,1,-1), (1,-1,1),
%  (-1,-1,1), and (-1,1,1).
%
%INPUTS: alpha A 3X1 or 1X3 vector of the integer exponents of the
%              monomial term. All elements must be >=0.
%
%OUTPUTS: intVal The value of the specified integral.
%
%The solution was obtained via analytic integration. These types of
%explicit moment formulae are useful for testing cubature integration
%points.
%
%EXAMPLE:
%An analytic solution for alpha=[10;18;6] is -4/3861. Here, we
%show that this function produces the same result within resonable finite
%precision limits.
% alpha=[19;12;8];
% intSol=monomialIntPrism(alpha);
% trueSol=-4/3861;
% RelErr=(intSol-trueSol)/trueSol
%
%October 2022 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

if(mod(alpha(3),2)==0)
    a=alpha(1);
    b=alpha(2);
    c=alpha(3);

    intVal=(2*(-1)^a*(1+a)+2*(-1)^b*(1+b+(-1)^a*(2+a+b)))/((1+a)*(1+b)*(2+a+b)*(1+c));
else
    intVal=0;
end
end

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


%% Example of dop2Dbox Applied to Illumination Correction
%
% (C) 2013 Matthew harker and Paul O'Leary
% Institute for Automation
% University of Leoben
% A-8700 Leoben
% Austria
%
% email: office@harkeroleary.org
%
% This program demonstrates the application of discrete orthogonal
% polynomials to illumination correction in an image.
%
% This tool requires the discrete orthogonal toolbox: dopBox:
%
%   http://www.mathworks.com/matlabcentral/fileexchange/41250
%
%%
close all;
clear;
%
%% Load the Test Data
% \cellName{loadData}
%
% This is an image of a metallurgical sample taken with a microscope
%
load metallurgy;
%
fig1 = figure;
imagesc( D );
colormap(gray);
axis image;
%
%\caption{Example metallurgical image, note the inhomogeneous illumination}
%
%% Generate the Basis Functions for the X and Y Directions
% \cellName{genBases}
%
% Determine the size of the image
%
[ny, nx] = size( D );
%
% Define the degree of the basis functions for the x and y directions
%
degreeX = 2;
degreeY = 2;
%
% The function call dop uses the number of basis functions not degree
%
noBfsX = degreeX + 1;
noBfsY = degreeY + 1;
%
% Generate the discrete orthogonal basis functions
%
Bx = dop( nx, noBfsX );
By = dop( ny, noBfsY );
%
%% Compute the 2D Polynomial Spectrum
% \cellName{computeSpec}
%
% Only a few basis functions have been used. Consequently the 2D polynomial
% is of low degree. The fit will model the global intensity of the image.
%
Sp = By' * D * Bx;
%
% generate scale vectors for the x and y directions
%
xScale = 0:degreeX;
yScale = 0:degreeY;
%
fig2 = figure;
imagesc( xScale, yScale, Sp );
xlabel('Degree in $$x$$');
ylabel('Degree in $$y$$');
colorbar;
%
% \caption{2D polynomial spectrum}
%
%% Compute the Illumination Approximation
% \cellName{approx}
%
% Reconstructing the 2D data set corresponds to the global illumination
% approximation.
%
Z = By * Sp * Bx';
%
fig3 = figure;
imagesc( Z );
colorbar;
colormap(gray);
%
% \caption{2D Polynomial approximation to the image. The low degree of
% approximation ensures that the details in the image are not modelled.
% In this manner the approximation corresponds to the global illumination}
%
%% Correct the Image Intensity
% \cellName{correct}
%
C = D - Z;
%
fig4 = figure;
imagesc( C );
colorbar;
colormap(gray);
%
% \caption{Metallurgical image corrected for the non-uniform illumination.}


function [ x, seed ] = c_normal_01_sample ( seed )

%*****************************************************************************80
%
%% C_NORMAL_01_SAMPLE samples the complex Normal 01 PDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer SEED, a seed for the random number generator.
%
%    Output, complex X, a sample of the PDF.
%
  [ v1, seed ] = r8_uniform_01 ( seed );
  [ v2, seed ] = r8_uniform_01 ( seed );

  x_r = sqrt ( - 2.0 * log ( v1 ) ) * cos ( 2.0 * pi * v2 );
  x_c = sqrt ( - 2.0 * log ( v1 ) ) * sin ( 2.0 * pi * v2 );

  x = x_r + i * x_c;

  return
end


function trans = createTranslation(varargin)
%CREATETRANSLATION Create the 3*3 matrix of a translation.
%
%   TRANS = createTranslation(DX, DY);
%   Returns the translation corresponding to DX and DY.
%   The returned matrix has the form :
%   [1 0 TX]
%   [0 1 TY]
%   [0 0  1]
%
%   TRANS = createTranslation(VECTOR);
%   Returns the matrix corresponding to a translation by the vector [x y].
%
%
%   See also:
%   transforms2d, transformPoint, createRotation, createScaling
%
%   ---------
%   author : David Legland
%   INRA - TPV URPOI - BIA IMASTE
%   created the 06/04/2004.
%

%   HISTORY
%   22/04/2009: rename as createTranslation

% process input arguments
if isempty(varargin)
    tx = 0;
    ty = 0;
elseif length(varargin)==1
    var = varargin{1};
    tx = var(1);
    ty = var(2);
else
    tx = varargin{1};
    ty = varargin{2};
end

% create the matrix representing the translation
trans = [1 0 tx ; 0 1 ty ; 0 0 1];


function [ x, w ] = ccoh_rule ( n )

%*****************************************************************************80
%
%% CCOH_RULE computes a Clenshaw Curtis Open Half rule.
%
%  Discussion:
%
%    Our convention is that the abscissas are numbered from left to right.
%
%    The rule is defined on [-1,1].
%
%    The integral to approximate:
%
%      Integral ( -1 <= X <= 1 ) F(X) dX
%
%    The quadrature rule:
%
%      Sum ( 1 <= I <= N ) W(I) * F ( X(I) )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 February 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the rule.
%
%    Output, real X(N), the abscissas.
%
%    Output, real W(N), the weights.
%
  x = zeros ( n, 1 );
  x =  ( 1 : 2 : 2 * n - 1 )' / ( 2 * n );
%
%  Chebyshev transformation from [0,1] to [-1,1].
%
  x = cos ( x * pi );
%
%  Compute the weights.
%
  x_min = -1.0;
  x_max = +1.0;

  w = nc_compute ( n, x_min, x_max, x );

  return
end


function f = p03_f ( m, c, w, n, x )

%*****************************************************************************80
%
%% P03_F evaluates the function for problem p03.
%
%  Discussion:
%
%    f(x) = 1 / ( 1 + sum ( c(1:m) * x(1:m) ) ) ^ ( m + 1 )
%
%    Default values are:
%
%    c(1:m) = 1/m
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 August 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Alan Genz,
%    A Package for Testing Multiple Integration Subroutines,
%    in Numerical Integration: Recent Developments, Software
%    and Applications,
%    edited by Patrick Keast and Graeme Fairweather,
%    Reidel, 1987, pages 337-340,
%    ISBN: 9027725144,
%    LC: QA299.3.N38.
%
%  Parameters:
%
%    Input, integer M, the spatial dimension.
%
%    Input, real C(M,1), W(M,1), the problem parameters.
%
%    Input, integer N, the number of points.
%
%    Input, real X(M,N), the evaluation points.
%
%    Output, real F(N,1), the function values.
%
  f = ones ( n, 1 );

  for i = 1 : m
    f = f + c(i) .* x(i,:)';
  end
  f = 1.0 ./ f .^ ( m + 1 );

  return
end


function result = fit_rayleigh_pdf( x,y,W,hAx )
% fit_rayleigh_pdf - Non Linear Least Squares fit of the Rayleigh distribution.
%                    given the samples of the histogram of the samples, finds the
%                    distribution parameter that fits the histogram samples.
%
%    fits data to the probability of the form:
%        p(r)=r*exp(-r^2/(2*s))/s
%    with parameter: s
%
% format:   result = fit_rayleigh_pdf( x,y,W,hAx )
%
% input:    y   - vector, samples of the histogram to be fitted
%           x   - vector, position of the samples of the histogram (i.e. y = f(x,a))
%           W   - matrix or scalar, a square weighting matrix of the size NxN where
%                 N = length(y), or 0 to indicate no weighting is needed.
%           hAx - handle of an axis, on which the fitted distribution is plotted
%                 if h is given empty, a figure is created.
%
% output:   result  - structure with the fields
%                      s   - fitted parameter
%                      VAR - variance of the estimation
%                      type- weighted LS or not weighted LS
%                      iter- number of iteration for the solution
%

%
% Algorithm
% ===========
%
% We use the WLS algorithm to estimate the PDF from the samples.%
% The rayleigh distribution is given by:
%
%    p(x,s) = x*exp(-x^2/(2*s))/s
%
%    note that X is known and therefore, considered a constant vector
%
% The non liner WLS estimator is given by:
%
%    s(n+1) = s(n) + inv(H'*W*H)*(H') * (y-h) = s(n) + G * err
%
%    where:   h = p(x,s)
%             H = diff( p(x,a) ) with respect to "s"
%             W = weighting matrix of size NxN  (N = length(y))
%             s = a single parameter to be estimated
%
% The error estimation is given by:
%
%    VAR( s ) = G * VAR( err ) * (G')
%
%       or when W=I and the noise is a gaussian noise
%
%    VAR( s ) = inv( H' * H )
%

if (nargin<3)
    error( 'fit_rayleigh_pdf - insufficient input arguments' );
end

s       = x(find(y==max(y))).^2;        % initial guess
y       = y(:);                         % both should be column vectors !
x       = x(:);
x2      = x.^2;                         % save computation time
thresh  = 0.995;                        % convergence threshold for the loop
last_cnt= inf;
iter    = 0;

% check weight matrix input
if (size(W,1)==length(y)) & (size(W,2)==length(y))
    weights_flag    = 1;
    type            = 'WLS';
else
    weights_flag    = 0;
    type            = 'LS';
end

% Estimation
% =============
if (weights_flag)
    % loop for convergence (with weighting matrix)
    % =============================================
    while (1)
        iter    = iter + 1;
        h       = x.*exp( -x2/(2*s) )/s;
        H       = h.*(x2/(2*s^2) - 1/s);
        HTW     = H'*W;
        e       = inv( HTW * H ) * HTW * (y-h);
        s       = s + e;
        control = e*e;
        if ( control > (last_cnt * thresh) )
            break;
        else
            last_cnt = control;
        end
    end

    % summarize results
    h       = x.*exp( -x2/(2*s) )/s;
    H       = h.*(x2/(2*s^2) - 1/s);
    HTW     = H'*W;
    G       = inv( HTW * H ) * HTW;
    err     = (y-h);
    VAR     = G * var(err) * (G');
else

    % loop for convergence (without a weighting matrix)
    % ==================================================
    while (1)
        iter    = iter + 1;
        h       = x.*exp( -x2/(2*s) )/s;
        H       = h.*(x2/(2*s^2) - 1/s);
        HT      = H';
        control = inv( HT * H );
        s       = s + control * HT * (y-h);
        if ( control>(last_cnt * thresh) )
            break;
        else
            last_cnt = control;
        end
    end

	% summarize results
    h       = x.*exp( -x2/(2*s) )/s;
    H       = h.*(x2/(2*s^2) - 1/s);
    err     = (y-h);
    VAR     = inv( (H') * H );
end

% finish summarizing results
% ============================
result.s    = s;
result.VAR  = VAR;
result.RMS  = sqrt( (err')*err/ (x(2)-x(1))^2 / (length(err)-1) );
result.iter = iter;
result.type = type;

% plot distribution if asked for
% ===============================
if (nargin>3)
    if ishandle( hAx )
        plot_rayleigh( x,result,hAx,4 );
    else
        figure;
        plot_rayleigh( x,result1,gca,4 );
    end
end


% RM_histogram Computes the frequency histogram of the row vector x.
%   [RESULT,DESCRIPTOR] = HISTOGRAM(X) or
%   [RESULT,DESCRIPTOR] = HISTOGRAM(X,DESCRIPTOR) or
% where
%   DESCRIPTOR = [LOWER,UPPER,NCELL]
%
%   RESULT    : A row vector containing the histogram
%   DESCRIPTOR: The used descriptor
%
%   X         : The row vector be analyzed
%   DESCRIPTOR: The descriptor of the histogram
%     LOWER   : The lowerbound of the histogram
%     UPPER   : The upperbound of the histogram
%     NCELL   : The number of cells of the histogram
%
%   See also: http://www.cs.rug.nl/~rudy/matlab/
%
%   R. Moddemeijer
%   Copyright (c) by R. Moddemeijer
%   $Revision: 1.2 $  $Date: 2001/02/05 09:54:29 $

function [result,descriptor] = RM_histogram(x,descriptor)

if nargin < 1
   disp('Usage: RESULT = HISTOGRAM(X)')
   disp('       RESULT = HISTOGRAM(X,DESCRIPTOR)')
   disp('Where: DESCRIPTOR = [LOWER,UPPER,NCELL]')
   return
end

% Some initial tests on the input arguments

[NRowX, NColX] = size(x);

if NRowX ~= 1
  error('Invalid dimension of X');
end;

if nargin > 2
  error('Too many arguments');
end;

if nargin==1
  minx=min(x);
  maxx=max(x);
  delta=(maxx-minx)/(length(x)-1);
  ncell=ceil(sqrt(length(x)));
  descriptor=[minx-delta/2,maxx+delta/2,ncell];
end;

lower=descriptor(1);
upper=descriptor(2);
ncell=descriptor(3);

if ncell<1
  error('Invalid number of cells')
end;

if upper<=lower
  error('Invalid bounds')
end;

result(1:ncell)=0;

y=round( (x-lower)/(upper-lower)*ncell + 1/2 );
for n=1:NColX
  index=y(n);
  if index >= 1 & index<=ncell
    result(index)=result(index)+1;
  end;
end;