function r=v_rotpl2ro(u,v,t)
%V_ROTPL2RO find matrix to rotate in the plane containing u and v r=[u,v,t]
% Inputs:
%
%     U(n,1) and V(n,1) define a plane in n-dimensional space
%     T is the rotation angle in radians from U towards V. If T
%       is omitted it will default to the angle between U and V
%
% Outputs:
%
%     R(n,n)   Rotation matrix

%
%      Copyright (C) Mike Brookes 2007-2018
%      Version: $Id: v_rotpl2ro.m 10865 2018-09-21 17:22:45Z dmb $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

u=u(:);
    n=length(u);
v=v(:);
l=sqrt(u'*u);
if l==0, error('input u is a zero vector'); end
u=u/l;      % normalize
q=v-v'*u*u;        % q is orthogonal to x
l=sqrt(q'*q);
if l==0          % u and v are colinear or v=zero
    [m,i]=max(abs(u));
    q=zeros(n,1);
    q(1+mod(i(1),n))=1;  % choose next available dimension
    q=q-q'*u*u;  % q is orthogonal to x
    l=sqrt(q'*q);
end
q=q/l;          % normalize
if nargin<3
    [s,c]=v_atan2sc(v'*q,v'*u);
    r=eye(n)+(c-1)*(u*u'+q*q')+s*(q*u'-u*q');
else
    r=eye(n)+(cos(t)-1)*(u*u'+q*q')+sin(t)*(q*u'-u*q');
end
if ~nargout && n==3
    v_rotqr2ro(v_rotro2qr(r)); % plot a rotated cube
end


function hyperball_monte_carlo_test02 ( )

%*****************************************************************************80
%
%% HYPERBALL_MONTE_CARLO_TEST02 uses HYPERBALL01_SAMPLE in 6D.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    05 January 2014
%
%  Author:
%
%    John Burkardt
%
  m = 6;

  e_test = [ ...
    0, 0, 0, 0, 0, 0; ...
    1, 0, 0, 0, 0, 0; ...
    0, 2, 0, 0, 0, 0; ...
    0, 2, 2, 0, 0, 0; ...
    0, 0, 0, 4, 0, 0; ...
    2, 0, 0, 0, 2, 2; ...
    0, 0, 0, 0, 0, 6 ]';

  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST02\n' );
  fprintf ( 1, '  Use the Monte Carlo method to estimate integrals \n' );
  fprintf ( 1, '  over the interior of the unit hyperball in M dimensions.\n' );
  fprintf ( 1, 'n' );
  fprintf ( 1, '  Spatial dimension M = %d\n', m );

  seed = 123456789;

  fprintf ( 1, '\n' );
  fprintf ( 1, '         N' );
  fprintf ( 1, '        1      ' );
  fprintf ( 1, '        U      ' );
  fprintf ( 1, '         V^2   ' );
  fprintf ( 1, '         V^2W^2' );
  fprintf ( 1, '         X^4   ' );
  fprintf ( 1, '         Y^2Z^2' );
  fprintf ( 1, '         Z^6\n' );
  fprintf ( 1, '\n' );

  n = 1;

  while ( n <= 65536 )

    [ x, seed ] = hyperball01_sample ( m, n, seed );

    fprintf ( 1, '  %8d', n );
    for j = 1 : 7
      e(1:m) = e_test(1:m,j);
      value = monomial_value ( m, n, e, x );
      result(j) = hyperball01_volume ( m ) * sum ( value(1:n) ) / n;
      fprintf ( 1, '  %14.6g', result(j) );
    end
    fprintf ( 1, '\n' );

    n = 2 * n;

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '     Exact' );
  for j = 1 : 7
    e(1:m) = e_test(1:m,j);
    result(j) = hyperball01_monomial_integral ( m, e );
    fprintf ( 1, '  %14.6g', result(j) );
  end
  fprintf ( 1, '\n' );

  return
end


function normals = points2normals(points)
    % estimating a normal vector based on nearby 100 points
    % points is 3 * n matrix for n points

    if size(points,2)==3 && size(points,1)~=3
        points = points';
    end

    normals = lsqnormest(points, 100);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% functions from http://www.mathworks.com/matlabcentral/fileexchange/27804-iterative-closest-point

% Least squares normal estimation from point clouds using PCA
%
% H. Hoppe, T. DeRose, T. Duchamp, J. McDonald, and W. Stuetzle.
% Surface reconstruction from unorganized points.
% In Proceedings of ACM Siggraph, pages 71:78, 1992.
%
% p should be a matrix containing the horizontally concatenated column
% vectors with points. k is a scalar indicating how many neighbors the
% normal estimation is based upon.
%
% Note that for large point sets, the function performs significantly
% faster if Statistics Toolbox >= v. 7.3 is installed.
%
% Jakob Wilm 2010

function n = lsqnormest(p, k)
m = size(p,2);
n = zeros(3,m);

v = ver('stats');
if str2double(v.Version) >= 7.5
    neighbors = transpose(knnsearch(transpose(p), transpose(p), 'k', k+1));
else
    neighbors = k_nearest_neighbors(p, p, k+1);
end

for i = 1:m
    x = p(:,neighbors(2:end, i));
    p_bar = 1/k * sum(x,2);

    P = (x - repmat(p_bar,1,k)) * transpose(x - repmat(p_bar,1,k)); %spd matrix P
    %P = 2*cov(x);

    [V,D] = eig(P);

    [~, idx] = min(diag(D)); % choses the smallest eigenvalue

    n(:,i) = V(:,idx);   % returns the corresponding eigenvector
end

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

% Program to find the k - nearest neighbors (kNN) within a set of points.
% Distance metric used: Euclidean distance
%
% Note that this function makes repetitive use of min(), which seems to be
% more efficient than sort() for k < 30.

function [neighborIds,neighborDistances] = k_nearest_neighbors(dataMatrix, queryMatrix, k)

numDataPoints = size(dataMatrix,2);
numQueryPoints = size(queryMatrix,2);

neighborIds = zeros(k,numQueryPoints);
neighborDistances = zeros(k,numQueryPoints);

D = size(dataMatrix, 1); %dimensionality of points

for i=1:numQueryPoints
    d=zeros(1,numDataPoints);
    for t=1:D % this is to avoid slow repmat()
        d=d+(dataMatrix(t,:)-queryMatrix(t,i)).^2;
    end
    for j=1:k
        [s,t] = min(d);
        neighborIds(j,i)=t;
        neighborDistances(j,i)=sqrt(s);
        d(t) = NaN; % remove found number from d
    end
end


function vs = sphere_triangle_vertices_to_centroid ( r, v1, v2, v3 )

%*****************************************************************************80
%
%% SPHERE_TRIANGLE_VERTICES_TO_CENTROID gets a spherical triangle centroid in 3D.
%
%  Discussion:
%
%    A sphere centered at 0 in 3D satisfies the equation:
%
%      X*X + Y*Y + Z*Z = R*R
%
%    A spherical triangle is specified by three points on the sphere.
%
%    The (true) centroid of a spherical triangle is the point
%
%      VT = (XT,YT,ZT) = Integral ( X, Y, Z ) dArea / Integral 1 dArea
%
%    Note that the true centroid does NOT, in general, lie on the sphere.
%
%    The "flat" centroid VF is the centroid of the planar triangle defined by
%    the vertices of the spherical triangle.
%
%    The "spherical" centroid VS of a spherical triangle is computed by
%    the intersection of the geodesic bisectors of the triangle angles.
%    The spherical centroid lies on the sphere.
%
%    VF, VT and VS lie on a line through the center of the sphere.  We can
%    easily calculate VF by averaging the vertices, and from this determine
%    VS by normalizing.
%
%    Of course, we still will not have actually computed VT, which lies
%    somewhere between VF and VS!
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real R, the radius of the sphere.
%
%    Input, real V1(3), V2(3), V3(3), the vertices of the triangle.
%
%    Output, real VS(3), the coordinates of the "spherical
%    centroid" of the spherical triangle.
%
  dim_num = 3;

  vs(1:dim_num) = ( v1(1:dim_num) + v2(1:dim_num) + v3(1:dim_num) ) / 3.0;

  norm = sqrt ( sum ( vs(1:dim_num).^2 ) );

  vs(1:dim_num) = r * vs(1:dim_num) / norm;

  return
end


function [HotellingT2] = HotellingT2(X,alpha)
%Hotelling T-Squared testing procedures for multivariate samples.
%
%   Syntax: function [HotellingT2] = HotellingT2(X,alpha)
%
%     Inputs:
%          X - multivariate data matrix.
%      alpha - significance level (default = 0.05).
%
%     Outputs:
%          It depends of the Hotelling's T-Squared multivariate test of interest,
%          being able to be:
%
%            |-One-sample
%            |                          |-Homoskedasticity (to test)
%            |            |-Independent |
%            |            |             |-Heteroskedasticity (to test)
%            |-Two-sample |
%                         |
%                         |-Dependent
%
%          Each case calls to a corresponding function that contains a complete
%          explanation.
%
%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%             And the special collaboration of the post-graduate students of the 2002:2
%             Multivariate Statistics Course: Karel Castro-Morales, Alejandro Espinoza-Tenorio,
%             Andrea Guia-Ramirez.
%
%  Copyright (C) December 2002.
%

if nargin < 2,
    alpha = 0.05; %(default)
end;

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

sam = input('Do you have one multivariate sample (1) or two multivariate samples (2)?: ');
if sam == 1;
   T2Hot1(X,alpha)
else
   id = input('They are independent (1) or dependent (2)?: ');
   if id == 1;
      disp('The covariance matrix homogeneity will be testing.:');
      MBoxtest(X,alpha);
      disp(' ')
      dc = input('Are they significant? (y/n): ','s');
      if dc == 'y'
         T2Hot2ihe(X,alpha);
      else
         T2Hot2iho(X,alpha);
      end;
   else
      T2Hot2d(X,alpha);
   end;
end;

return;


function [gv gh]=sobel_fn(x)

%%% sobel_fn: Computes the vertical & horizontal edges of x using sobel operator.
%%%
%%% [gv gh]=sobel_fn(x)
%%%
%%% Author : B. K. SHREYAMSHA KUMAR
%%% Created on 28-10-2011.
%%% Updated on 28-10-2011.

vtemp=[-1 0 1;-2 0 2;-1 0 1]/8;
htemp=[-1 -2 -1;-0 0 0;1 2 1]/8;

[a b]=size(htemp);
x_ext=per_extn_im_fn(x,a);
[p,q]=size(x_ext);
for ii=2:p-1
   for jj=2:q-1
      gv(ii-1,jj-1)=sum(sum(x_ext(ii-1:ii+1,jj-1:jj+1).*vtemp));
      gh(ii-1,jj-1)=sum(sum(x_ext(ii-1:ii+1,jj-1:jj+1).*htemp));
   end
end


%% file example_mtl_classify.m
%   This example shows how to perform classification using least squares
%   loss and logistic loss.
%
%% LICENSE
%   This program is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%   Copyright (C) 2011 - 2012 Jiayu Zhou and Jieping Ye
%
%   You are suggested to first read the Manual.
%   For any problem, please contact with Jiayu Zhou via jiayu.zhou@asu.edu
%
%   Last modified on June 3, 2012.
%

clear, clc;
addpath('../MALSAR/utils/')
addpath('../MALSAR/functions/Lasso/')

n = 50;
d = 300;
t = 10;

X = cell(t, 1);
Y = cell(t, 1);
W = randn(d, t);
W_mask = abs(randn(d, t))<1;
W(W_mask) = 0;
for i = 1: t
    X{i} = randn(n, d);
    Y{i} = sign(X{i} * W(:, i) + rand(n, 1) * 0.01);
end

% training and prediction using least squares loss
W_pred = Least_Lasso(X, Y, 0.01);
% compute training error
least_acc = zeros(t, 1);
for i = 1: t
    least_acc(i) = nnz(sign(X{i} * W_pred(:, i)) == Y{i})/n;
end
fprintf('Least Squares Loss Training Accuracy: %.4f +/- %.4f\n', mean(least_acc), std(least_acc));

% training and prediction using logistic loss
[W_pred C_pred]= Logistic_Lasso(X, Y, 0.01);
% compute training error
logistic_acc = zeros(t, 1);
for i = 1: t
    logistic_acc(i) = nnz(sign(X{i} * W_pred(:, i) + C_pred(i)) == Y{i})/n;
end
fprintf('Logistic Loss Training Accuracy: %.4f +/- %.4f\n', mean(logistic_acc), std(logistic_acc));


function cdf = semicircular_cdf ( x, a, b )

%*****************************************************************************80
%
%% SEMICIRCULAR_CDF evaluates the Semicircular CDF.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%
%    Input, real A, B, the parameter of the PDF.
%    0.0 < B.
%
%    Output, real CDF, the value of the CDF.
%
  if ( x <= a - b )

    cdf = 0.0;

  elseif ( x <= a + b )

    y = ( x - a ) / b;

    cdf = 0.5 + ( y * sqrt ( 1.0 - y * y ) + asin ( y ) ) / pi;

  elseif ( a + b < x )

    cdf = 1.0;

  end

  return
end


function ha = r8mat_house_hxa ( n, a, v )

%*****************************************************************************80
%
%% R8MAT_HOUSE_HXA computes H*A where H is a compact Householder matrix.
%
%  Discussion:
%
%    The Householder matrix H(V) is defined by
%
%      H(V) = I - 2 * v * v' / ( v' * v )
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    27 April 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Input, real A(N,N), the matrix to be premultiplied.
%
%    Input, real V(N), a vector defining a Householder matrix.
%
%    Output, real HA(N,N), the product H*A.
%
  ha = a - 2.0 * v * v' * a / ( v' * v );

  return
end


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

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

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

for i = 1:size(Z, 1)
    v = Z(i, :);

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

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

end


%EUL2TR Convert Euler angles to homogeneous transform
%
% T = EUL2TR(PHI, THETA, PSI, OPTIONS) is a SE(3) homogeneous
% transformation matrix (4x4) equivalent to the specified Euler angles.
% These correspond to rotations about the Z, Y, Z axes respectively. If
% PHI, THETA, PSI are column vectors (Nx1) then they are assumed to
% represent a trajectory and R is a three-dimensional matrix (4x4xN), where
% the last index corresponds to rows of PHI, THETA, PSI.
%
% T = EUL2TR(EUL, OPTIONS) as above but the Euler angles are taken from
% consecutive columns of the passed matrix EUL = [PHI THETA PSI].  If EUL
% is a matrix (Nx3) then they are assumed to represent a trajectory and T
% is a three-dimensional matrix (4x4xN), where the last index corresponds
% to rows of EUL which are assumed to be [PHI, THETA, PSI].
%
% Options::
%  'deg'      Compute angles in degrees (radians default)
%
% Note::
% - The vectors PHI, THETA, PSI must be of the same length.
% - The translational part is zero.
%
% See also EUL2R, RPY2TR, TR2EUL.

% Copyright (C) 1993-2015, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

function T = eul2tr(phi, varargin)

    R = eul2r(phi, varargin{:});
    T = r2t(R);


function BW = im2bw_ent(IM)
% This fucntion convert an intensity image to a binary image
% by using Entropy-based method
%
% Usage: BW = im2bw_ent(IM)
% Input: IM -> Input Image
% Output: BW -> Segmented Image
%
% Example:
% IM = imread('house.jpg');
% BW = im2bw_ent(IM);
% imagesc(BW)
%
% Reference: E.R.Davies Machine Vision 3rd Edition

% size of input image
dim = size(IM);
% Change input image to gray scale
leng = length(dim);
if leng == 3
    IM = rgb2gray(IM);
end

% histgram of input image
ihis = imhist(IM);

leng = length(ihis);
para = zeros(1,leng);
for k = 2:leng-1
    % intensity of class A
    classa = ihis(1:k);
    ind = (classa==0);
    classa = classa+ind;
    clear ind
    % intensity of class B
    classb = ihis(k+1:end);
    ind = (classb==0);
    classb = classb+ind;
    clear ind
    % probability distribution of class A
    Pa = classa/(dim(1,1)*dim(1,2));
    % probability distribution of class B
    Pb = classb/(dim(1,1)*dim(1,2));
    % parameters to decide threshold
    para1 = log2(sum(Pa));
    para2 = log2(sum(Pb));
    logpa = log2(Pa);
    logpb = log2(Pb);
    para3 = -sum(Pa.*logpa)/sum(Pa);
    para4 = -sum(Pb.*logpb)/sum(Pb);
    % parameter which has to be maximized
    para(1,k) = abs(para1+para2+para3+para4);
    clear classa classb logpa logpb
end

% find threshold
[maxv,row] = max(para);
thresh = row-1;
% segment input image
BW = (IM>=thresh);


function a = plu ( n, pivot )

%*****************************************************************************80
%
%% PLU returns the PLU matrix.
%
%  Discussion:
%
%    The PLU matrix has known P, L and U Gauss factors.
%
%  Example:
%
%    Input:
%
%      N = 5
%      PIVOT = ( 1, 3, 3, 5, 5 )
%
%    Output:
%
%      A:
%
%         11            12           13            14           15
%          1.375         9.75        43.25         44.75        46.25
%          2.75         25           26.25         27.5         28.75
%          0.34375       2.4375       7.71875      17.625       73.125
%          0.6875        4.875       15.4375       60           61.5625
%
%      P:
%
%          1             0            0             0            0
%          0             0            1             0            0
%          0             1            0             0            0
%          0             0            0             0            1
%          0             0            0             1            0
%
%      L:
%
%         1              0            0             0            0
%         0.25           1            0             0            0
%         0.125          0.375        1             0            0
%         0.0625         0.1875       0.3125        1            0
%         0.03125        0.09375      0.15625       0.21875      1
%
%      U:
%
%        11             12           13            14           15
%         0             22           23            24           25
%         0              0           33            34           35
%         0              0            0            44           45
%         0              0            0             0           55
%
%  Note:
%
%    The LINPACK routine DGEFA will factor the above A as:
%
%       11             12             13             14             15
%      -0.125          22             23             24             25
%      -0.25           -0.375         33             34             35
%      -0.03125        -0.09375       -0.15625       44             45
%      -0.0625         -0.1875        -0.3125        -0.21875       55
%
%    and the pivot information in the vector IPVT as:
%
%      ( 1, 3, 3, 5, 5 ).
%
%    The LAPACK routine DGETRF will factor the above A as:
%
%      11              12             13             14             15
%      0.25            22             23             24             25
%      0.125            0.375         33             34             35
%      0.0625           0.1875         0.3125        44             45
%      0.03125          0.09375        0.15625        0.21875       55
%
%   and the pivot information in the vector IPIV as:
%
%     ( 1, 3, 3, 5, 5 ).
%
%  Method:
%
%    The L factor will have unit diagonal, and subdiagonal entries
%    L(I,J) = ( 2 * J - 1 ) / 2^I, which should result in a unique
%    value for every entry.
%
%    The U factor of A will have entries
%    U(I,J) = 10 * I + J, which should result in "nice" entries as long
%    as N < 10.
%
%    The P factor can be deduced by applying the pivoting operations
%    specified by PIVOT in reverse order to the rows of the identity.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    25 March 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of the matrix.
%
%    Input, integer PIVOT(N), the list of pivot rows.  PIVOT(I)
%    must be a value between I and N, reflecting the choice of
%    pivot row on the I-th step.  For no pivoting, set PIVOT(I) = I.
%
%    Output, real A(N,N), the matrix.
%
  [ p, l, u ] = plu_plu ( n, pivot );

  a = p * l * u;

  return
end


function dstimgs = slpixlinnorm(imgs, mu, sigma)
%SLPIXLINNORM Performs linear normalization on pixel values
%
% $ Syntax $
%   - dstimgs = slpixlinnorm(imgs);
%   - dstimgs = slpixlinnorm(imgs, mu, sigma)
%
% $ Arguments $
%   - imgs:     the array of images
%   - mu:       the mean pixel value to be normalized to (default = 0)
%   - sigma:    the standard deviation relative to mean pixel (default = 1)
%
% $ Description $
%   - dstimgs = slpixlinnorm(imgs, mu, sigma) performs linear normalization
%     on the image pixels so that the average pixel value is set to mu
%     while the standard deviation is set to sigma. The normalization is
%     conducted on each page(channel) respectively.
%
%   - dstimgs = slpixlinnorm(imgs) performs linear pixel value
%     normalization using default values.
%
% $ History $
%   - Created by Dahua Lin, on Aug 8th, 2006
%

%% parse and verify input arguments

if ~isa(imgs, 'double')
    imgs = im2double(imgs);
end
[h, w, n] = size(imgs);

if nargin < 2 || isempty(mu)
    mu = 0;
end

if nargin < 3 || isempty(sigma)
    sigma = 1;
end

d = h * w;

%% perform normalization

if n == 1
    dstimgs = normalize_page(imgs, d, mu, sigma);
else
    dstimgs = zeros(size(imgs));
    for i = 1 : n
        dstimgs(:,:,i) = normalize_page(imgs(:,:,i), d, mu, sigma);
    end
end

function dstimg = normalize_page(img, d, mu, sigma)

curimg = img(:);

% compute current mean value
cur_mv = sum(curimg) / d;

% shift to zero mean
curimg = curimg - cur_mv;

% compute current standard deviation
cur_std = norm(curimg) / sqrt(d);

% normalize to specified std dev
k = sigma / cur_std;
curimg = curimg * k;

% shift to specified mean
if mu ~= 0
    curimg = curimg + mu;
end

% reshape back to origin shape
dstimg = reshape(curimg, size(img));


%% Rotation Demonstration: Discontinous Data
%
% A demonstration of how the timestep affects the error of the splitting
% method for a rotation. Similar results can be expected in general,
% although nonlinear sharpening may give smaller errors.
%
% The equation we solve is
%
% $$u_t - y u_x + x u_y = 0, \qquad u(x,y,0)=u_0(x,y)$$
%
% where the initial function u0 is discontinuous. To solve the equation, we
% will use Godunov splitting and front tracking to approximate the 1-D
% solution operators.

%% Initial setup
T     = 4*pi;
xmin  = -1.5; xmax=1.5;
N     = 128;
h     = (xmax-xmin)/N;
x     = xmin+h*(0:N);
y     = 0.5*(x(1:end-1)+x(2:end));
[X,Y] = meshgrid(y,y);
u0    = adiscontnuous_function(X,Y);
surfl(X,Y,u0); shading interp, view(-15,60), colormap(gray), axis tight

%% Error versus CFL number
% First we study the pointwise and the L1 error for CFL numbers 2.^(0:5)
colormap(jet)
for i=1:6
	nu=2^(i-1);
	err= abs( rotrack(u0,y,y,nu,T) - u0);
   subplot(2,3,i), pcolor(y,y,err), axis equal image, shading interp;
   set(colorbar('West'),'XColor',[1 1 1],'YColor',[1 1 1]);
   caxis([0 2]), title(['CFL = ', num2str(nu)]);
   set(gca,'XTick',[],'YTick',[])
   xlabel(['L1 error: ', num2str(h*h*sum(abs(err(:))))]);
	drawnow;
end;
%%
% The error is determined by two error mechanisms that work in opposite
% directions. The splitting error increases with increasing splitting
% steps, whereas the smoothing error caused by the projection operator
% increases with decreasing splitting steps. The total splitting error is
% therefore a convex function of the time step, and in the figure above,
% the minimum error is observed for CFL number 16.

%% Testing convergence
% We choose the best CFL number vu=16, and check for convergence rate.
% To this end, we use only one lap (it takes too long otherwise).
T    = 2*pi;
Lerr = zeros(1,7);
wbar = waitbar(0,'Convergence study');
for i=1:7,
	N    = 2^(i+3);
	h    = (xmax-xmin)/N; x=xmin+h*(1:N);
	[X,Y]=meshgrid(x,x);
	u0   = adiscontnuous_function(X,Y);
	err  = abs(rotrack(u0,x,x,nu,T) - u0);
	Lerr(i)=sum(err(:)) / sum(abs(u0(:)));
	waitbar(i/7,wbar);
end;
close(wbar);
clf, semilogy(1:7,Lerr,'o--');
set(gca,'XTick',1:7,'XTickLabel',2.^((1:7)+3))
xlabel('Grid size'); ylabel('Log(error)'); axis tight
title('Errors for \nu = 16');


% Chapter 3 - Complex Iterative Maps.
% Program 3b - The Mandelbrot Set.
% Thanks to Steve Lord from The MathWorks for his help.
% Copyright Birkhauser 2013. Stephen Lynch.

% Vectorized program.
% Plot the Mandelbrot set in black and white (Figure 3.2).
Nmax = 50; scale = 0.005;
xmin = -2.4; xmax  = 1.2;
ymin = -1.5; ymax  = 1.5;

% Generate x and y coordinates and z complex values
[x,y]=meshgrid(xmin:scale:xmax,ymin:scale:ymax);
z = x+1i*y;

% Generate w accumulation matrix and k counting matrix
w = zeros(size(z));
k = zeros(size(z));

N = 0;
while N<Nmax && ~all(k(:))
    w = w.^2+z;
    N = N+1;
    k(~k & abs(w)>4) = N;
end
k(k==0) = Nmax;
figure
s = pcolor(x, y, mod(k, 2));
colormap([0 0 0;1 1 1])
set(s,'edgecolor','none')

axis([xmin xmax -ymax ymax])
fsize=15;
set(gca,'XTick',xmin:0.4:xmax,'FontSize',fsize)
set(gca,'YTick',-ymax:0.5:ymax,'FontSize',fsize)
xlabel('Re z','FontSize',fsize)
ylabel('Im z','FontSize',fsize)
% End of Program 3b


function value = r8_cin ( x )

%*****************************************************************************80
%
%% R8_CIN evaluates the alternate cosine integral Cin of an R8 argument.
%
%  Discussion:
%
%    CIN(X) = gamma + log(X)
%      + integral ( 0 <= T <= X ) ( cos ( T ) - 1 ) / T  dT
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 September 2011
%
%  Author:
%
%    Original FORTRAN77 version by Wayne Fullerton.
%    MATLAB version by John Burkardt.
%
%  Reference:
%
%    Wayne Fullerton,
%    Portable Special Function Routines,
%    in Portability of Numerical Software,
%    edited by Wayne Cowell,
%    Lecture Notes in Computer Science, Volume 57,
%    Springer 1977,
%    ISBN: 978-3-540-08446-4,
%    LC: QA297.W65.
%
%  Parameters:
%
%    Input, real X, the argument.
%
%    Output, real VALUE, the cosine integral Cin evaluated at X.
%
  persistent cincs
  persistent eul
  persistent ncin
  persistent xmin

  eul = 0.57721566490153286060651209008240;

  if ( isempty ( ncin ) )

    cincs = [ ...
      0.37074501750909688741654801228564992, ...
     -0.05893574896364446831956864397363697, ...
      0.00538189642113569124048745326203340, ...
     -0.00029860052841962135319594906563410, ...
      0.00001095572575321620077031054467306, ...
     -0.00000028405454877346630491727187731, ...
      0.00000000546973994875384912457861806, ...
     -0.00000000008124187461318157083277452, ...
      0.00000000000095868593117706609013181, ...
     -0.00000000000000920266004392351031377, ...
      0.00000000000000007325887999017895024, ...
     -0.00000000000000000049143726675842909, ...
      0.00000000000000000000281577746753902, ...
     -0.00000000000000000000001393986788501, ...
      0.00000000000000000000000006022485646, ...
     -0.00000000000000000000000000022904717, ...
      0.00000000000000000000000000000077273, ...
     -0.00000000000000000000000000000000233 ]';

    ncin = r8_inits ( cincs, 18, 0.1 * r8_mach ( 3 ) );
    xmin = sqrt ( r8_mach ( 1 ) );

  end

  absx = abs ( x );

  if ( absx <= xmin )
    value = 0.0;
  elseif ( absx <= 4.0 )
    value = r8_csevl ( ( x * x - 8.0 ) * 0.125, cincs, ncin ) * x * x;
  else
    [ f, g ] = r8_sifg ( absx );
    sinx = sin ( absx );
    value = - f * sinx + g * cos ( absx ) + log ( absx ) + eul;
  end

  return
end


function [ xstar, seed ] = rk2_tv_step ( x, t, h, q, fv, gv, seed )

%*****************************************************************************80
%
%% RK2_TV_STEP takes one step of a stochastic Runge Kutta scheme.
%
%  Discussion:
%
%    The Runge-Kutta scheme is second-order, and suitable for time-varying
%    systems.
%
%    d/dx X(t,xsi) = F ( X(t,xsi), t ) + G ( X(t,xsi), t ) * w(t,xsi)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 June 2010
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Jeremy Kasdin,
%    Runge-Kutta algorithm for the numerical integration of
%    stochastic differential equations,
%    Journal of Guidance, Control, and Dynamics,
%    Volume 18, Number 1, January-February 1995, pages 114-120.
%
%    Jeremy Kasdin,
%    Discrete Simulation of Colored Noise and Stochastic Processes
%    and 1/f^a Power Law Noise Generation,
%    Proceedings of the IEEE,
%    Volume 83, Number 5, 1995, pages 802-827.
%
%  Parameters:
%
%    Input, real X, the value at the current time.
%
%    Input, real T, the current time.
%
%    Input, real H, the time step.
%
%    Input, real Q, the spectral density of the input white noise.
%
%    Input, external real FV, the name of the deterministic
%    right hand side function.
%
%    Input, external real GV, the name of the stochastic
%    right hand side function.
%
%    Input/output, integer SEED, a seed for the random
%    number generator.
%
%    Output, real XSTAR, the value at time T+H.
%
  a21 = 1.0;
  a31 = 0.5;
  a32 = 0.5;

  q1 = 2.0;
  q2 = 2.0;

  t1 = t;
  x1 = x;
  [ n1, seed ] = r8_normal_01 ( seed );
  w1 = n1 * sqrt ( q1 * q / h );
  k1 = h * fv ( t1, x1 ) + h * gv ( t1, x1 ) * w1;

  t2 = t1 + a21 * h;
  x2 = x1 + a21 * k1;
  [ n2, seed ] = r8_normal_01 ( seed );
  w2 = n2 * sqrt ( q2 * q / h );
  k2 = h * fv ( t2, x2 ) + h * gv ( t2, x2 ) * w2;

  xstar = x1 + a31 * k1 + a32 * k2;

  return
end


function fluxlimiter(N, method)
% N = number of grid points

% grid spacing on interval (-1,1)
dx = 2./N;

% location of cell centers
x = linspace(-1+0.5*dx, 1-0.5*dx, N);

% advection speed
u = 1;

% cfl condition + safety margin
dt = 0.25*dx;

% final time
FinalTime = 2;
Nsteps = ceil(FinalTime/dt);
dt = FinalTime/Nsteps;
lam = u*dt/dx;

% initial condition
q = fluxlimiterexact(x);

% time step
for n=1:Nsteps

  qp1  = [q(2:N),q(1)];    % q_{m+1}
  qm1 = [q(N),q(1:N-1)]; % q_{m-1}
  qm2 = [qm1(N), qm1(1:N-1)]; % q_{m-2}

  % compute limited cell average jumps based on method choice
  % theta_{i-1/2} = (q_{i-1}-q_{i-2})/(q_{i}-q_{i-1})
  tol = 1e-10;
  dq1 = q-qm1;
  dq2 = qm1-qm2;
  % have to test in case dq1 is small because of finite precision effects

  % are both dq1, and dq2 small (smooth)
  ids = find(abs(dq1)+abs(dq2)<tol); % both jumps small
  thetaL(ids) = 1;

  % is dq1 small and dq2 relatively large
  ids = find(abs(dq1)<tol & abs(dq2)>tol );
  thetaL(ids) = 100; % choose theta large

  % hopefully the remainder
  ids = find(abs(dq1)>= tol);
  thetaL(ids) = dq2(ids)./dq1(ids);

  if(strcmp(method,'minmod'))
      phiL = minmod(1, thetaL);
  elseif(strcmp(method,'MC'))
      phiL = max(0, min(min(0.5*(1+thetaL),2), 2*thetaL));
  elseif(strcmp(method,'vanleer'))
      phiL = (thetaL+abs(thetaL))./(1+abs(thetaL));
  elseif(strcmp(method,'superbee'))
      phiL = max(0, max(min(1,2*thetaL), min(2,thetaL)));
  elseif(strcmp(method,'Fromm'))
      phiL = 0.5*(1+thetaL);
  elseif(strcmp(method,'BeamWarming'))
      phiL = thetaL; % upwind
  elseif(strcmp(method,'LaxWendroff'))
      phiL = ones(size(q)); % downwind
  elseif(strcmp(method, 'upwind'))
      phiL = zeros(size(q));
  elseif(strcmp(method, 'custom'))

      phiL = customphi(thetaL);
  else
      disp('WARNING: wrong choice of flux limiter');
  end
  phiR = [phiL(2:N), phiL(1)];

  % update cell averages
  q = q - lam*(q-qm1) - 0.5*lam*(1-lam)*(phiR.*(qp1-q) -phiL.*(q-qm1));

  if(mod(n,40)==0)
    plot(x,q, '.');
    hold on; plot(x-0.5*dx, phiL, 'g-'); hold off;pause(0.02);
  end
end

plot(x, q, 'b.');
% have gone one exact period
hold on; plot(x, fluxlimiterexact(x), 'r-'); hold off;
hold on; plot(x-0.5*dx, phiL, 'g-'); hold off;
xlabel('x');
legend(sprintf('%s N=%d T=%f', method, N, FinalTime), ...
           'Exact solution', sprintf('flux limiter function: phi_{%s}', method));
axis([-1 1 -1 3])


% hohmann.m          July 9, 2013

% Hohmann two impulse orbit transfer between
% planar and non-coplanar circular orbits

% includes three-dimensional orbit graphics
% and graphical primer vector analysis

% Orbital Mechanics with MATLAB

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

global rtd dtr pvi pvdi

global mu req hn1 hn2 hn3 dinc

% astrodynamic and utility constants

om_constants;

% Brent root-finding tolerance

rtol = 1.0e-8;

% request inputs

clc; home;

fprintf('\nHohmann Orbit Transfer Analysis\n');

while (1)

    fprintf('\n\nplease input the initial altitude (kilometers)\n');

    alt1 = input('? ');

    if (alt1 > 0.0)
        break;
    end

end

while (1)

    fprintf('\n\nplease input the final altitude (kilometers)\n');

    alt2 = input('? ');

    if (alt2 > 0.0)
        break;
    end

end

while (1)

    fprintf('\n\nplease input the initial orbital inclination (degrees)');
    fprintf('\n(0 <= inclination <= 180)\n');

    inc1 = input('? ');

    if (inc1 >= 0.0 && inc1 <= 180.0)
        break;
    end

end

while (1)

    fprintf('\n\nplease input the final orbital inclination (degrees)');
    fprintf('\n(0 <= inclination <= 180)\n');

    inc2 = input('? ');

    if (inc2 >= 0.0 && inc2 <= 180.0)
        break;
    end

end

% convert orbit inclinations to radians

inc1 = inc1 * dtr;

inc2 = inc2 * dtr;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% solve the orbit transfer problem %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% calculate total inclination change (radians)

dinc = abs(inc2 - inc1);

% compute geocentric radii of initial and final orbits (kilometers)

r1 = req + alt1;

r2 = req + alt2;

% compute "normalized" radii

hn1 = sqrt(2.0 * r2 / (r2 + r1));

hn2 = sqrt(r1 / r2);

hn3 = sqrt(2.0 * r1 / (r2 + r1));

% compute "local circular velocity" of initial and final orbits (km/sec)

v1 = sqrt(mu / r1);

v2 = sqrt(mu / r2);

% compute transfer orbit semimajor axis (kilometers)

smat = 0.5 * (r1 + r2);

% compute transfer orbit eccentricity (non-dimensional)

ecct = (max(r1, r2) - min(r1, r2)) / (r1 + r2);

% compute transfer orbit perigee and apogee radii and velocities

rp = smat * (1.0 - ecct);

ra = smat * (1.0 + ecct);

vt1 = sqrt(2.0 * mu * ra / (rp * (rp + ra)));

vt2 = sqrt(2.0 * mu * rp / (ra * (rp + ra)));

% compute transfer orbit period (seconds)

taut = 2.0 * pi * sqrt(smat^3 / mu);

tof = 0.5 * taut;

if (abs(dinc) == 0)

    % coplanar orbit transfer

    if (r2 > r1)

        % higher-to-lower transfer

        dv1 = vt1 - v1;

        dv2 = v2 - vt2;

    else

        % lower-to-higher transfer

        dv1 = v1 - vt2;

        dv2 = vt1 - v2;

    end

    dinc1 = 0;

    dinc2 = 0;

    inct = inc1;

else

    % non-coplanar orbit transfer

    [xroot, froot] = brent('hohmfunc', 0, dinc, rtol);

    % calculate delta-v's

    dinc1 = xroot;

    dinc2 = dinc - dinc1;

    dv1 = v1 * sqrt(1.0 + hn1 * hn1 - 2.0 * hn1 * cos(dinc1));

    dv2 = v1 * sqrt(hn2 * hn2 * hn3 * hn3 + hn2 * hn2 ...
        - 2.0 * hn2 * hn2 * hn3 * cos(dinc2));

    if (inc2 > inc1)

        inct = inc1 + dinc1;

    else

        inct = inc1 - dinc1;

    end

end

% print results

clc; home;

fprintf('\nHohmann Orbit Transfer Analysis');
fprintf('\n-------------------------------\n\n');

fprintf('initial orbit altitude            %10.4f kilometers \n\n', alt1);

fprintf('initial orbit radius              %10.4f kilometers \n\n', alt1 + req);

fprintf('initial orbit inclination         %10.4f degrees \n\n', inc1 * rtd);

fprintf('initial orbit velocity            %10.4f meters/second \n\n\n', 1000.0 * v1);

fprintf('final orbit altitude              %10.4f kilometers \n\n', alt2);

fprintf('final orbit radius                %10.4f kilometers \n\n', alt2 + req);

fprintf('final orbit inclination           %10.4f degrees \n\n', inc2 * rtd);

fprintf('final orbit velocity              %10.4f meters/second \n', 1000.0 * v2);

fprintf('\n\nfirst inclination change          %10.4f degrees\n\n', dinc1 * rtd);

fprintf('second inclination change         %10.4f degrees\n\n', dinc2 * rtd);

fprintf('total inclination change          %10.4f degrees\n\n\n', rtd * (dinc1 + dinc2));

fprintf('first delta-v                     %10.4f meters/second \n\n', 1000.0 * dv1);

fprintf('second delta-v                    %10.4f meters/second \n\n', 1000.0 * dv2);

fprintf('total delta-v                     %10.4f meters/second \n\n\n', 1000.0 * (dv1 + dv2));

fprintf('transfer orbit semimajor axis     %10.4f kilometers \n\n', smat);

fprintf('transfer orbit eccentricity       %10.8f \n\n', ecct);

fprintf('transfer orbit inclination        %10.4f degrees \n\n', rtd * inct);

fprintf('transfer orbit perigee velocity   %10.4f meters/second \n\n', 1000.0 * vt1);

fprintf('transfer orbit apogee velocity    %10.4f meters/second \n\n', 1000.0 * vt2);

fprintf('transfer orbit coast time         %10.4f seconds \n', tof);

fprintf('                                  %10.4f minutes \n', tof / 60.0);

fprintf('                                  %10.4f hours \n\n', tof / 3600.0);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% create trajectory graphics %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% load orbital elements arrays, create state vectors and plot orbits

oevi(1) = r1;
oevi(2) = 0.0;
oevi(3) = inc1;
oevi(4) = 0.0;
oevi(5) = 0.0;

% determine correct true anomaly (radians)

if (alt2 > alt1)

    oevi(6) = 0.0;

else

    oevi(6) = 180.0 * dtr;

end

[ri, vi] = orb2eci(mu, oevi);

oevti(1) = smat;
oevti(2) = ecct;
oevti(3) = inct;
oevti(4) = 0.0;
oevti(5) = 0.0;

% determine correct true anomaly (radians)

if (alt2 > alt1)

    oevti(6) = 0.0;

else

    oevti(6) = 180.0 * dtr;

end

[rti, vti] = orb2eci(mu, oevti);

oevtf(1) = smat;
oevtf(2) = ecct;
oevtf(3) = inct;
oevtf(4) = 0.0;
oevtf(5) = 0.0;

% determine correct true anomaly (radians)

if (alt2 > alt1)

    oevtf(6) = 180.0 * dtr;

else

    oevtf(6) = 0.0;

end

[rtf, vtf] = orb2eci(mu, oevtf);

oevf(1) = r2;
oevf(2) = 0.0;
oevf(3) = inc2;
oevf(4) = 0.0;
oevf(5) = 0.0;

% determine correct true anomaly (radians)

if (alt2 > alt1)

    oevf(6) = 180.0 * dtr;

else

    oevf(6) = 0.0;

end

[rf, vf] = orb2eci(mu, oevf);

% compute orbital periods

period1 = 2.0 * pi * oevi(1) * sqrt(oevi(1) / mu);

period2 = 2.0 * pi * oevti(1) * sqrt(oevti(1) / mu);

period3 = 2.0 * pi * oevf(1) * sqrt(oevf(1) / mu);

deltat1 = period1 / 300;

simtime1 = -deltat1;

deltat2 = 0.5 * period2 / 300;

simtime2 = -deltat2;

deltat3 = period3 / 300;

simtime3 = -deltat3;

for i = 1:1:301

    simtime1 = simtime1 + deltat1;

    simtime2 = simtime2 + deltat2;

    simtime3 = simtime3 + deltat3;

    % compute initial orbit "normalized" position vector

    [rwrk, vwrk] = twobody2 (mu, simtime1, ri, vi);

    rp1_x(i) = rwrk(1) / req;

    rp1_y(i) = rwrk(2) / req;

    rp1_z(i) = rwrk(3) / req;

    % compute transfer orbit position vector

    [rwrk, vwrk] = twobody2 (mu, simtime2, rti, vti);

    rp2_x(i) = rwrk(1) / req;

    rp2_y(i) = rwrk(2) / req;

    rp2_z(i) = rwrk(3) / req;

    % compute final orbit position vector

    [rwrk, vwrk] = twobody2 (mu, simtime3, rf, vf);

    rp3_x(i) = rwrk(1) / req;

    rp3_y(i) = rwrk(2) / req;

    rp3_z(i) = rwrk(3) / req;

end

figure(1);

% create axes vectors

xaxisx = [1 1.5];
xaxisy = [0 0];
xaxisz = [0 0];

yaxisx = [0 0];
yaxisy = [1 1.5];
yaxisz = [0 0];

zaxisx = [0 0];
zaxisy = [0 0];
zaxisz = [1 1.5];

figure (1);

hold on;

grid on;

% plot earth

[x y z] = sphere(24);

h = surf(x, y, z);

colormap([127/255 1 222/255]);

set (h, 'edgecolor', [1 1 1]);

% plot coordinate system axes

plot3(xaxisx, xaxisy, xaxisz, '-g', 'LineWidth', 1);

plot3(yaxisx, yaxisy, yaxisz, '-r', 'LineWidth', 1);

plot3(zaxisx, zaxisy, zaxisz, '-b', 'LineWidth', 1);

% plot initial orbit

plot3(rp1_x, rp1_y, rp1_z, '-r', 'LineWidth', 1.5);

plot3(rp1_x(1), rp1_y(1), rp1_z(1), 'ob');

% plot transfer orbit

plot3(rp2_x, rp2_y, rp2_z, '-b', 'LineWidth', 1.5);

plot3(rp2_x(end), rp2_y(end), rp2_z(end), 'ob');

% plot final orbit

plot3(rp3_x, rp3_y, rp3_z, '-g', 'LineWidth', 1.5);

xlabel('X coordinate (ER)', 'FontSize', 12);

ylabel('Y coordinate (ER)', 'FontSize', 12);

zlabel('Z coordinate (ER)', 'FontSize', 12);

title('Hohmann Transfer: Initial, Transfer and Final Orbits', 'FontSize', 16);

axis equal;

view(50, 20);

rotate3d on;

print -depsc -tiff -r300 hohmann1.eps

%%%%%%%%%%%%%%%%%%%%%%%%
% create primer graphics
%%%%%%%%%%%%%%%%%%%%%%%%

dvi = (vti - vi)';

dvf = (vf - vtf)';

% perform primer vector initialization

pviniz(tof, rti, vti, dvi, dvf);

% number of graphic data points

npts = 300;

% plot behavior of primer vector magnitude

dt = tof / npts;

for i = 1:1:npts + 1

    t = (i - 1) * dt;

    if (t == 0)

        % initial value of primer magnitude and derivative

        pvm = norm(pvi);

        pvdm = dot(pvi, pvdi) / pvm;

    else

        % primer vector and derivative magnitudes at time t

        [pvm, pvdm] = pvector(rti, vti, t);

    end

    % load data array

    x1(i) = t / 60.0;

    y1(i) = pvm;

    y2(i) = pvdm;

end

figure(2);

hold on;

plot(x1, y1, '-r', 'LineWidth', 1.5);

plot(x1(1), y1(1), 'or');

plot(x1(end), y1(end), 'or');

title('Primer Vector Analysis of the Hohmann Transfer', 'FontSize', 16);

xlabel('simulation time (minutes)', 'FontSize', 12);

ylabel('primer vector magnitude', 'FontSize', 12);

grid;

% create eps graphics file with tiff preview

print -depsc -tiff -r300 primer.eps;

% plot behavior of magnitude of primer derivative

figure(3);

hold on;

plot(x1, y2, '-r', 'LineWidth', 1.5);

plot(x1(1), y2(1), 'or');

plot(x1(end), y2(end), 'or');

title('Primer Vector Analysis of the Hohmann Transfer', 'FontSize', 16);

xlabel('simulation time (minutes)', 'FontSize', 12);

ylabel('primer derivative magnitude', 'FontSize', 12);

grid;

% create eps graphics file with tiff preview

print -depsc -tiff -r300 primer_der.eps;


function [theta] = normalEqn(X, y)
    %% NORMALEQN Computes the closed-form solution to linear regression
    %   NORMALEQN(X,y) computes the closed-form solution to linear
    %   regression using the normal equations.
    theta = pinv(X' * X) * X' * y;
end


%MAIN_singlePendulum.m
%
% This script runs a simple simulation of a single pendulum

% Use: EoM_Single_Pendulum to write the equations of motion

m = 1.0;  % (kg) pendulum mass
g = 9.81; % (m/s^2) gravity
l = 1.0; % (m) pendulum length

tSpan = [0,10]; %Simulation time interval

th0 = (pi/180)*(-178);  %Initial angle
w0 = 0;  %Initial angular rate
z0 = [th0;w0];

userFunc = @(t,z)singlePendulumRhs(t,z,g,l);

options = odeset(...
    'AbsTol',1e-8,...
    'RelTol',1e-8,...
    'Vectorized','on');

% Run the simulation!
sol = ode45(userFunc,tSpan,z0,options);

% Break apart solution for plotting
nPlot = 1000;
time = linspace(tSpan(1),tSpan(2),nPlot);
z = deval(sol,time); %Evaluate solution from ode45 at points in time
th = z(1,:);
w = z(2,:);
[energy, kinetic, potential] = singlePendulumEnergy(th,w,m,g,l);

% Plotting!

figure(1111);clf;

subplot(3,1,1);
plot(time,th,'k-','LineWidth',2);
xlabel('time (s)')
ylabel('angle (rad)');

subplot(3,1,2);
plot(time,w,'k-','LineWidth',2);
xlabel('time (s)')
ylabel('angle rate (rad/s)');

subplot(3,1,3);  hold on;
plot(time,energy,'k-','LineWidth',3);
plot(time,kinetic,'r-','LineWidth',2);
plot(time,potential,'b-','LineWidth',2);
xlabel('time (s)')
ylabel('energy (J)');
legend('total','kinetic','potential');


function [err, C] = gen_pos_err(std, n, type, absolute)
%GEN_POS_ERR Generates position errors. We first generate i.i.d. position errors
%for each sensor. We use the first sensor as the reference sensor and substract
%the the position error of the first sensor from the remaining sensors.
%Therefore, the resulting covariance matrix is not diagonal.
%Inputs:
%   std - Standard deviation of the position errors.
%   n - Number of sensors.
%   type - 'Gaussian' or 'Uniform'.
%   absolute - If set to true, will not use the first sensor as the reference
%              sensor and the position errors will be i.i.d.
%Outputs:
%   err - 2xn vector of position errors.
%   C - Covariance matrix. (2n-2) x (2n-2) if absolute is false, (2n) x (2n) if
%       absolute is true.
if nargin < 4
    absolute = false;
end
switch lower(type)
    case 'gaussian'
        err = randn(2, n)*std;
        if nargout > 1
            if absolute
                C = std^2*eye(n + n);
            else
                C = std^2*(eye(n - 1) + ones(n - 1));
                C = blkdiag(C, C);
            end
        end
    case 'uniform'
        b = sqrt(3)*std;
        err = unifrnd(-b, b, 2, n);
        if nargout > 1
            if absolute
                C = std^2*eye(n + n);
            else
                C = std^2*(eye(n - 1) + ones(n - 1));
                C = blkdiag(C, C);
            end
        end
    otherwise
        error('Unknow type "%s".', type);
end
if ~absolute
    err(1,2:end) = err(1,2:end) - err(1,1);
    err(2,2:end) = err(2,2:end) - err(2,1);
    err(1,1) = 0;
    err(2,1) = 0;
end
end


function Zf = filt2(Z,res,lambda,filtertype)
% filt2 performs a highpass, lowpass, bandpass, or bandstop 2D gaussian filter on gridded data such as
% topographic, atmospheric, oceanographic, or any kind of geospatial data. This function is designed to
% make it easy to remove features longer or shorter than a given characteristic wavelength. The
% input grid can contain NaNs!
%
%% Syntax
%
%  Zf = filt2(Z,res,lambda,filtertype)
%
%% Description
%
% Zf = filt2(Z,res,lambda,filtertype) filters 2D dataset Z that has resolution res,
% to an approximate wavelength lambda.  If the filtertype is 'lp' or 'hp' for lowpass
% or highpass, lambda must be a scalar value.  If the filtertype is 'bp' or 'bs' for
% bandpass or bandstop, lambda must be a two-element array of the two cutoff wavelengths.
%
%% Explanation of this type of filter
% For an explanation of this filter with pictures, type
%
%   showdemo filt2_documentation
%
% into your command window.
%
%% Example
% Consider a 100 km by 100 km elevation dataset that has a resolution of 200 m.  It has
% some long 25 km wavelength features aligned with north/south direction, some short
% ~5 km features oriented diagonally, and a considerable amount of random noise.  There's
% also a block of missing data. Here's what your datset looks like:
%
% res = 0.2; % 200 m resolution
% x = 0:res:100; % eastings from 0 to 100 km
% y = 0:res:100; % northings from 0 to 100 km
% [X,Y] = meshgrid(x,y);
%
% % Z contains 25 km features, ~5 km diagonal features, and noise:
% Z = cos(2*pi*X/25)+cos(2*pi*(X+Y)/7)+randn(size(X));
%
% % Z also has some missing data:
% Z(100:120,100:120) = nan;
%
% subplot(1,3,1)
% imagesc(x,y,Z);
% axis xy image
% caxis([-1 1])
% title ' original Z matrix '
% xlabel ' eastings (km) '
% ylabel ' northings (km) '
%
% % Get the lowpass-filtered version of Z:
% Zlow = filt2(Z,res,15,'lp');
%
% subplot(1,3,2)
% imagesc(x,y,Zlow);
% axis xy image
% caxis([-1 1])
% title ' 15 km lowpass filtered Z matrix '
% xlabel ' eastings (km) '
% ylabel ' northings (km) '
%
% % Get the highpass-filtered version of Z:
% Zhi = filt2(Z,res,15,'hp');
%
% subplot(1,3,3)
% imagesc(x,y,Zhi);
% axis xy image
% caxis([-1 1])
% title ' 15 km highpass filtered Z matrix '
% xlabel ' eastings (km) '
% ylabel ' northings (km) '
%
%% Author Info
% This function was written by Chad A. Greene of the University of Texas Institute for
% Geophysics in November 2016; however, all I did was repackage Carlos Adrian Vargas Aguilera's
% superb ndnanfilter function, which can be found here: http://www.mathworks.com/matlabcentral/fileexchange/20417.
% Many thanks to Carlos for his well-thought-out code and clear documentation.
%
% See also conv2, imgaussfilt, and imfilter.

%% Input checks

narginchk(4,4)
% assert(license('test','image_toolbox')==1,'Error: I''m sorry, the filt2 function requires the Image Processing Toolbox.')
assert(ismatrix(Z)==1,'Input error: Z must be a 2d matrix.')
%assert(isscalar(res)==1,'Input error: res must be a scalar value.')
assert(ismember(lower(filtertype),{'lp','hp','bp','bs'}),'Input error: filtertype must be ''hp'', ''lp'', ''bp'', or ''bs''.')
if lambda<=(2*max(res))
   warning('Nyquist says the wavelength should exceed two times the resolution of the dataset, which is an unmet condition based on these inputs. I''ll give you some numbers, but I would''t trust ''em if I were you.')
end

if ismember(lower(filtertype),{'bp','bs'})
   assert(numel(lambda)==2,'Input error: Wavelength lambda must be a two-element array for a bandpass filter.')
else
   assert(isscalar(lambda)==1,'Input error: Wavelength lambda must be a scalar for lowpass or bandpass filters.')
end

%% Design filter:

% 2*pi*sigma is the wavelength at which the amplitude is multiplied by a factor of about 0.6 (more exactly, exp(-0.5))
sigma = (lambda(1)./res) /(2*pi);
%f = fspecial('gaussian',2*ceil(2.6*sigma)+1,sigma);
% WJP implementation without image processing toolbox, subfunc at bottom of
% this function
f = gaussian2D([2*ceil(2.6*sigma(1))+1 2*ceil(2.6*sigma(end))+1], sigma);

%% Now filter the data

switch lower(filtertype)
   %WJP incorrect usage originally but happened to work if imfilter is available
   case 'lp'
      Zf = ndnanfilter(Z,f,size(f),[],[],{'replicate'}); % ndnanfilter is Carlos Adrian Vargas Aguilera's excellent function, which is included as a subfunction below.

   case 'hp'
      Zf = Z - ndnanfilter(Z,f,size(f),[],[],{'replicate'});

   case 'bp'
      Zf =  filt2(filt2(Z,res,max(lambda),'hp'),res,min(lambda),'lp');

   case 'bs'
      Zf = filt2(Z,res,max(lambda),'lp') - filt2(Z,res,min(lambda),'hp');

   otherwise
      error('No such filter type.')
end

end

function [Y,W] = ndnanfilter(X,HWIN,F,DIM,WINOPT,PADOPT,WNAN)
% NDNANFILTER   N-dimensional zero-phase digital filter, ignoring NaNs.
%
%   Syntax:
%         Y = ndnanfilter(X,HWIN,F);
%         Y = ndnanfilter(X,HWIN,F,DIM);
%         Y = ndnanfilter(X,HWIN,F,DIM,WINOPT);
%         Y = ndnanfilter(X,HWIN,F,DIM,WINOPT,PADOPT);
%         Y = ndnanfilter(X,HWIN,F,DIM,WINOPT,PADOPT,WNAN);
%     [Y,W] = ndnanfilter(...);
%
%   Input:
%     X      - Data to be filtered with/without NaNs.
%     HWIN   - Window function handle (or name) or numeric multidimensional
%              window to be used (without NaNs). See WINDOW for details.
%              Default:   @rectwin  or 'rectwin' (moving average).
%     F      - A vector specifying the semi-width of the window for each
%              dimension. The final window's width will be 2*F+1.
%              Default: 3 (i.e. a 1-dimensional window of width 6).
%     DIM    - If F is a single scalar, the window will be applied through
%              this dimension; otherwise, this will be ignored.
%              Default: columns (or the first non-singleton dimension).
%     WINOPT - Cell array specifying optional arguments for the window
%              function HWIN (in addition to the width).
%              Default: {} (window's defaults).
%     PADOPT - Cell array specifying the optional arguments for the
%              PADARRAY MATLAB's function (in addition to the array X and
%              the padsize: 2*F+1). If the function is not found, data is
%              padded with zeros or the specified value: try {mean(X(:))}
%              for example.
%              Default: {'replicate'} (repeats border elements of X).
%              Default: {0} (pads with zeros if PADARRAY not found).
%     WNAN   - Integer indicating NaNs treatment and program behaviour!:
%              0: Filters data and interpolates NaNs         (default).
%              1: Filters data but do not interpolates NaNs
%              2: "Do not filters data" but interpolates NaNs!
%              See the NOTEs below
%
%   Output:
%     Y      - Filtered X data (same size as X!).
%     W      - N-dimensional window with central symmetry generated by a
%              special subfunction called NDWIND. See the description below
%              for details.
%
%   Description:
%     This function applies a N-dimensional convolution of X with W, using
%     the MATLAB's IMFILTER or CONVN function. One important aspect of the
%     function is the generation of the N-dimensional window (W) from the
%     specified function and width, which cannot be done with MATLAB's
%     functions. Besides, unlike MATLAB's FILTER, FILTER2 and IMFILTER,
%     NaNs elements are taken into account (ignored).
%
%     The N-dimensional window is generated from rotating the 1-dimensional
%     output of the HWIN function, through each of the N-dimensions, and
%     then shrinking it through each of its axes in order to fit the
%     specified semi-widths (F). This is done in the included subfunction
%     named NDWIND. In this way, the window has central symmetry and do not
%     produce a phase shift on X data.
%
%     By default, the edges are padded with the values of X at the borders
%     with the PADARRAY MATLAB's function. In this way, the edges are
%     treated smoothly. When PADARRAY is not found, the program performs
%     zero-padding.
%
%   Notes:
%     * The use of semi-widths F's is to force the generated window to be
%       even and, therefore, the change of phase is null.
%     * The window function HWIN should output an even function, otherwise,
%       it won't generate an error but the user should be aware that this
%       program will consider only the last half of it.
%     * The function window should return a monotonically decreasing
%       result, this restriction is because I try to avoid the use of FZERO
%       function, for example, to find the expanding/shrinking factors.
%     * If the user has an already generated window, it can be used in HWIN
%       instead of a function handle or name.
%     * Accepts empty value for any input. When X is empty, the program can
%       be used as a N-dimensional window generator.
%     * NaNs elements surrounded by no-NaNs elements (which will depend on
%       window width) are the ones that will be interpolated. The others
%       are leaved untouched.
%     * When WNAN=2, the programs acts like an NAN-interpolat/GAP-filling,
%       leaving untouched the no-NaNs elements but the filtering is
%       perfomed anyway. I recomend the default behaviour (WNAN=0) in order
%       to keep the filtered data in the workspace, and then use the code
%       at the end of this function to get/remove the interpolated NaNs
%       (see the example).
%     * The program looks for the IMFILTER and PADARRAY functions from the
%       Image Processing Toolbox. If not found, then CONVN is used instead
%       (slower) and pads with zeros or the given value. In this latter
%       case, if border elements are NaNs, the window won't work properly.
%
%   Example:
%     FWIN = 'hamming';
%     F = [13 8];
%     N = 100;
%     Pnoise = 0.30;
%     PNaNs  = 0.20;
%     X = peaks(N);                                     % original
%     Y = X + ((rand(size(X))-0.5)*2)*max(X(:))*Pnoise; % add noise
%     Y(round(1 + (N^2-1).*rand(N^2*PNaNs,1))) = NaN;   % add NaNs
%     [Z0,W] = ndnanfilter(Y,FWIN,F);                   % filters
%     Z1 = Z0; Z2 = Y; inan = isnan(Y);
%     Z1(inan) = NaN;
%     Z2(inan) = Z0(inan);
%     subplot(231), imagesc(X), clim = caxis; axis equal tight
%                   title('Original data')
%     subplot(232), imagesc(Y),  caxis(clim), axis equal tight
%                   title('Data + NOISE + NaNs')
%     subplot(234), imagesc(Z0), caxis(clim), axis equal tight
%                   title('FILTERS + NaNs interpolation')
%     subplot(235), imagesc(Z1), caxis(clim), axis equal tight
%                   title('FILTERS ignoring NaNs')
%     subplot(236), imagesc(Z2), caxis(clim), axis equal tight
%                   title('GAP-filling with interpolated NaNs')
%     subplot(233), imagesc(-F(1):F(1),-F(2):F(2),W), axis equal tight,
%                    title([upper(FWIN) ' 2D window']), view(2)
%
%   See also: FILTER, FILTER2 and CONVN; WINDOW from the Signal Processing
%   Toolbox; and FWIND1, FWIND2, FSPECIAL, IMFILTER and PADARRAY from the
%   Image Processing Toolbox.

%   Copyright 2008 Carlos Adrian Vargas Aguilera
%   $Revision: 1.2 $  $Date: 2008/06/30 18:00:00 $

%   Written by
%   M.S. Carlos Adrian Vargas Aguilera
%   Physical Oceanography PhD candidate
%   CICESE
%   Mexico, 2008
%   nubeobscura@hotmail.com
%
%   Download from:
%   http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objec
%   tType=author&objectId=1093874

%   1.0    Release (2008/06/23 10:30:00)
%   1.1    Fixed Bug adding an extra dimension of unitary width.
%   1.2    Fixed Bug with ynan.

% Use the IMFILTER function? (faster than CONVN):
yimfilter = (exist('imfilter','file')==2);

% Use the PADARRAY function (or zero padding):
ypadarray = (exist('padarray','file')==2);

% Check inputs and sets defaults of principal arguments:
if nargin<3 || nargin>7
 error('Filtern:IncorrectNumberOfInputs',...
  'At least three inputs are needed and less than 7.')
end
if isempty(HWIN)
 HWIN = 'rectwin';
end
if isempty(F)
 F = 3;
end
N = length(F);
S = size(X);
% Secondary arguments:
if N && (nargin<4 || isempty(DIM))
 DIM = find(S~=1,1);   %  DIM = min(find(S~=1));
 if isempty(DIM), DIM = 1; end
end
if nargin<5 || isempty(WINOPT)
 WINOPT = {};
end
if nargin<6 || isempty(PADOPT)
 if ypadarray
  PADOPT = {'replicate'};
 else
  PADOPT = {0};
 end
elseif ~ypadarray && ~isnumeric(PADOPT{1})
 PADOPT = {0};
end
if nargin<7 || isempty(WNAN)
 WNAN = 0;
end

% Selects the 1-dimensional filter or set a row vector:
if N==1
 a = zeros(1,DIM);
 a(DIM) = F;
 F = a;
 clear a
end

% Checks if the window input is a function or an array:
if ~isa(HWIN,'function_handle') && ~ischar(HWIN)
 W = HWIN;
else
 W = [];
end

% If no input data but two outputs then generates the window only:
if isempty(X)
 Y = [];
 if nargout==2 && ~isempty(W)
  W = ndwind(HWIN,F,WINOPT{:});
 end
 return
end

% Generates the window:
if isempty(W)
 W = ndwind(HWIN,F,WINOPT{:});
end

% Check for NaN's:
inan = isnan(X);
ynan = any(inan(:));                       % Bug fixed 30/jun/2008
if ynan
 X(inan) = 0;
else
 factor = sum(W(:));
end

% Filtering:
if yimfilter                                % Use IMFILTER (faster)
 if ~isa(X,'double')
  X = double(X);
 end
 if ~isa(W,'double')
  W = double(W);
 end
 if ynan
  Y = imfilter(X,W       ,PADOPT{:},'conv');
 else
  Y = imfilter(X,W/double(factor),PADOPT{:},'conv');
 end
else                                        % Use CONVN
 % Sets F and S of equal sizes.
 F = reshape(F,1,N);
 Nx = numel(S);
 if N<Nx
  F(N+1:Nx) = 0;
 elseif N>Nx
  S(Nx+1:N) = 1;
 end
 F2 = 2*F;
 % Pads the borders:
 if ypadarray
  ind    = padarray(false(S),F2,true     );    % Index of the padding.
  Y      = padarray(X       ,F2,PADOPT{:},'both');
 elseif length(PADOPT{1})==1
  ind2 = cell(N,1);
  for n = 1:N
   ind2{n} = F2(n) + (1:S(n)).';
  end
  ind          = true(2*F2+S);
  Y            = repmat(PADOPT{1},2*F2+S);
  ind(ind2{:}) = false;
  Y(ind2{:})   = X;
 else % No padding at all
  Y    = X;
  ind  = false(S);
  warning('Ndnanfilter:PaddingOption','Do not perfom any padding.')
 end
 % Convolutes both arrays:
 if ynan
  Y = convn(Y,W       ,'same');
 else
  Y = convn(Y,W/factor,'same');
 end
 %  Eliminates the padding:
 Y(ind) = [];
 Y      = reshape(Y,S);
end

% Estimates the averages when NaNs are present:
if ynan
 if yimfilter
  factor       = imfilter(double(~inan),W,PADOPT{:},'conv');
 else
  if ypadarray
   factor      = padarray(~inan,F2,PADOPT{:});
  elseif length(PADOPT{1})==1 % (won't work properly with NaNs at borders)
   factor          = ind;
   factor(ind2{:}) = ~inan;
  else
   factor = ~inan;
  end
  factor      = convn(factor,W,'same');
  factor(ind) = [];
  factor      = reshape(factor,S);
 end
 Y = Y./factor;
end

% What about NaNs?:
if     WNAN == 1       % Leave NaNs elements untouched!
 Y(inan) = NaN;
elseif WNAN == 2       % Leave no-NaNs elements untouched!!!
 X(inan) = Y(inan);
 Y = X;
end
end

function W = ndwind(HWIN,F,varargin)
% NDWIND Generate a N-Dimensional zero-phase window.
%
%   Syntax:
%     W = ndwind(HWIN,F);
%     W = ndwind(HWIN,F,OPT);
%
%   Input:
%     HWIN - Window function handle. See WINDOW for details. By default
%            uses: @rectwin (a rectangular window).
%     F    - A vector specifying the semiwidth of the window for each
%            dimension. The window's width will be 2*F+1. By default uses:
%            3 (i.e. a window of width 6).
%     OPT  - Cell array specifying optional arguments for the window
%            function. By default uses: {[]} (window's defaults).
%
%   Output:
%     W    - N-Dimensional window with central symmetry.
%
%   Description:
%     In the axes of each dimension, W has a 1-D window defined as
%              feval(HWIN,2*F(n)+1), n = 1,...,N.
%     That is, they are defined by the same window function but have
%     different widths. So, this program creates another widther window (at
%     least 201 points), with the same definition, and finds how much the
%     former windows should be expanded in order to fit the latter one.
%
%     Afterwards, the coordinates of every point are expanded accordingly
%     and the value of the window in those points are found by linear
%     interpolation with the bigger window.
%
%     In resume, it is like rotating this big window through every
%     dimension and then shrinking it through each of its axes to fix the
%     specified widths.
%
%   Notes:
%     * Because of the use of the semi-widths F's, all the generated
%       windows are even. Therefore the change of phase is null.
%     * The window function HWIN should output an even function, otherwise,
%       it won't generate an error but this program will consider only the
%       last half of it.
%     * The window should be monotonically decreasing.
%     * Instead of the handle window, it can be given as a string:
%       'hamming' instead of @hamming, for example.
%     * Uses the MATLAB's function FUNC2STR.
%
%   Example:
%     W = ndwind(@hamming,[3 2])
%     % Results:
%     W =
%
%              0         0    0.0800         0         0
%              0    0.1417    0.3100    0.1417         0
%              0    0.3966    0.7700    0.3966         0
%         0.0800    0.5400    1.0000    0.5400    0.0800
%              0    0.3966    0.7700    0.3966         0
%              0    0.1417    0.3100    0.1417         0
%              0         0    0.0800         0         0
%
%
%   See also: WINDOW from the Signal Processing Toolbox; and FWIND1,
%   FWIND2, and FSPECIAL from the Image Processing Toolbox.

%   Copyright 2008 Carlos Adrian Vargas Aguilera
%   $Revision: 1.1 $  $Date: 2008/06/26 19:30:00 $

%   Written by
%   M.S. Carlos Adrian Vargas Aguilera
%   Physical Oceanography PhD candidate
%   CICESE
%   Mexico, 2008
%   nubeobscura@hotmail.com
%
%   Download from:
%   http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objec
%   tType=author&objectId=1093874

%   1.0    Release (2008/06/23 10:30:00)
%   1.1    Fixed Bug adding an extra dimension of unitary width.

% Check inputs:
if nargin<1 || isempty(HWIN)
 HWIN = 'rectwin';
end
if nargin<2 || isempty(F)
 F = 3;
end

% Rectangular wind?:
if isa(HWIN,'function_handle')
 HWIN = func2str(HWIN);
end
if strcmpi(HWIN,'rectwin')
 W = ones([2*F(:).'+1 1]);
 return
end

% Generate the BIG window (only the last half):
FBIG         = max([100; F(:)]);
BIGw         = feval(HWIN,2*FBIG+1,varargin{:});
BIGw(1:FBIG) = [];       % Deletes the first half.
rBIGw        = 0:FBIG;   % Window argument (distance).

% Axial windows widths:
N  = numel(F);
F  = reshape(F,1,N);
F  = [F 0];             % BUG fixed by adding an extra dimension.
N  = N+1;
F2 = 2*F+1;

% Pre-allocates the final window and the expanded axis:
W  = zeros(F2);
An = cell(N,1);
Ae = An;

% Generates the index and expanded axes:
for n = 1:N

 % Generate temporally the window in the n-axis:
 wn = feval(HWIN,F2(n),varargin{:});

 % Finds the expansion factors (Note: the window should tends to zero):
 if F(n)
  piv = wn(end);
  ind = (BIGw == piv);
  if ~any(ind)
   ind1 = (BIGw >= piv); ind1 = length(ind1(ind1));
   ind2 = (BIGw <= piv); ind2 = length(ind2(~ind2))+1;
   if ind2>FBIG+1
    r = rBIGw(ind1);
   else
    r = interp1(BIGw([ind1 ind2]), rBIGw([ind1 ind2]),piv);
   end
  else
   r = rBIGw(ind);
  end
  Ef = r/F(n);
 else
  Ef = 1;
 end

 % Reversed index and expanded n-axis (for the following grid):
 An{n} = (F(n):-1:0);
 Ae{n} = An{n}*Ef;

end

% Estimates the expanded distances outside the axes (only at the 1st
% quarter):
% Note: In a 2-Dimensional matrix, by the 1st quarter of a matrix I mean
% the first 1/4 piece of the matrix after you divided it throuh the middle
% row and column. In N-dimensions it would be the 1st 1/2^N part.
gride4      = cell(N,1);
[gride4{:}] = ndgrid(Ae{:});
R4          = sqrt(sum(reshape([gride4{:}],prod(F+1),N).^2,2));

% Generates the window and linear index in the 1st quarter:
grid4     = cell(N,1);
[grid4{:}]= ndgrid(An{:});
in        = (R4<=rBIGw(end));           % Looks for elements inside window.
W4        = zeros(F+1);                 % 1st quarter of the window.
W4(in)    = interp1(rBIGw,BIGw,R4(in)); % Interpolates the window values.
for n=1:N                               % Linear index on the 1st quarter.
 grid4{n} = flip(grid4{n}+1,n);
end
ind4      = sub2ind(F2,grid4{:});

% Index of permutations to fill the N-D window:
np = 2^N-1;
ip = zeros(1,np);
for n = 1:N
 ini  = 2^(n-1);
 step = ini*2;
 ip(ini:step:np) = n;
end

% Fills the N-D window by flipping W4 and the index:
ones4       = false(F2);    % Avoids using new FALSE function
ones4(ind4) = true;
W(ones4)    = W4;
for kp = ip
 W4         = flip(W4,kp);
 ones4      = flip(ones4,kp);
 W(ones4)   = W4;
end
end

function h = gaussian2D(siz, std)

    % create the grid of (x,y) values
    siz = (siz-1)./2;
    [x,y] = meshgrid(-siz(2):siz(2),-siz(1):siz(1));

    std = max(std);
    sr = siz(2)/siz(1);
    if sr > 1
        sy = sr^2; sx = 1;
    else
        sx = sr^2; sy = 1;
    end

    % analytic function
    h = exp(-(sx*x.*x + sy*y.*y)/(2*std*std));

    % truncate very small values to zero
    h(h<eps*max(h(:))) = 0;

    % normalize filter to unit L1 energy
    sumh = sum(h(:));
    if sumh ~= 0
        h = h/sumh;
    end
end


function [x0,y0,iout,jout] = intersections(x1,y1,x2,y2,robust)
%INTERSECTIONS Intersections of curves.
%   Computes the (x,y) locations where two curves intersect.  The curves
%   can be broken with NaNs or have vertical segments.
%
% Example:
%   [X0,Y0] = intersections(X1,Y1,X2,Y2,ROBUST);
%
% where X1 and Y1 are equal-length vectors of at least two points and
% represent curve 1.  Similarly, X2 and Y2 represent curve 2.
% X0 and Y0 are column vectors containing the points at which the two
% curves intersect.
%
% ROBUST (optional) set to 1 or true means to use a slight variation of the
% algorithm that might return duplicates of some intersection points, and
% then remove those duplicates.  The default is true, but since the
% algorithm is slightly slower you can set it to false if you know that
% your curves don't intersect at any segment boundaries.  Also, the robust
% version properly handles parallel and overlapping segments.
%
% The algorithm can return two additional vectors that indicate which
% segment pairs contain intersections and where they are:
%
%   [X0,Y0,I,J] = intersections(X1,Y1,X2,Y2,ROBUST);
%
% For each element of the vector I, I(k) = (segment number of (X1,Y1)) +
% (how far along this segment the intersection is).  For example, if I(k) =
% 45.25 then the intersection lies a quarter of the way between the line
% segment connecting (X1(45),Y1(45)) and (X1(46),Y1(46)).  Similarly for
% the vector J and the segments in (X2,Y2).
%
% You can also get intersections of a curve with itself.  Simply pass in
% only one curve, i.e.,
%
%   [X0,Y0] = intersections(X1,Y1,ROBUST);
%
% where, as before, ROBUST is optional.

% Version: 1.12, 27 January 2010
% Author:  Douglas M. Schwarz
% Email:   dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu
% Real_email = regexprep(Email,{'=','*'},{'@','.'})

% Theory of operation:
%
% Given two line segments, L1 and L2,
%
%   L1 endpoints:  (x1(1),y1(1)) and (x1(2),y1(2))
%   L2 endpoints:  (x2(1),y2(1)) and (x2(2),y2(2))
%
% we can write four equations with four unknowns and then solve them.  The
% four unknowns are t1, t2, x0 and y0, where (x0,y0) is the intersection of
% L1 and L2, t1 is the distance from the starting point of L1 to the
% intersection relative to the length of L1 and t2 is the distance from the
% starting point of L2 to the intersection relative to the length of L2.
%
% So, the four equations are
%
%    (x1(2) - x1(1))*t1 = x0 - x1(1)
%    (x2(2) - x2(1))*t2 = x0 - x2(1)
%    (y1(2) - y1(1))*t1 = y0 - y1(1)
%    (y2(2) - y2(1))*t2 = y0 - y2(1)
%
% Rearranging and writing in matrix form,
%
%  [x1(2)-x1(1)       0       -1   0;      [t1;      [-x1(1);
%        0       x2(2)-x2(1)  -1   0;   *   t2;   =   -x2(1);
%   y1(2)-y1(1)       0        0  -1;       x0;       -y1(1);
%        0       y2(2)-y2(1)   0  -1]       y0]       -y2(1)]
%
% Let's call that A*T = B.  We can solve for T with T = A\B.
%
% Once we have our solution we just have to look at t1 and t2 to determine
% whether L1 and L2 intersect.  If 0 <= t1 < 1 and 0 <= t2 < 1 then the two
% line segments cross and we can include (x0,y0) in the output.
%
% In principle, we have to perform this computation on every pair of line
% segments in the input data.  This can be quite a large number of pairs so
% we will reduce it by doing a simple preliminary check to eliminate line
% segment pairs that could not possibly cross.  The check is to look at the
% smallest enclosing rectangles (with sides parallel to the axes) for each
% line segment pair and see if they overlap.  If they do then we have to
% compute t1 and t2 (via the A\B computation) to see if the line segments
% cross, but if they don't then the line segments cannot cross.  In a
% typical application, this technique will eliminate most of the potential
% line segment pairs.

% Input checks.
error(nargchk(2,5,nargin))

% Adjustments when fewer than five arguments are supplied.
switch nargin
	case 2
		robust = true;
		x2 = x1;
		y2 = y1;
		self_intersect = true;
	case 3
		robust = x2;
		x2 = x1;
		y2 = y1;
		self_intersect = true;
	case 4
		robust = true;
		self_intersect = false;
	case 5
		self_intersect = false;
end

% x1 and y1 must be vectors with same number of points (at least 2).
if sum(size(x1) > 1) ~= 1 || sum(size(y1) > 1) ~= 1 || ...
		length(x1) ~= length(y1)
	error('X1 and Y1 must be equal-length vectors of at least 2 points.')
end
% x2 and y2 must be vectors with same number of points (at least 2).
if sum(size(x2) > 1) ~= 1 || sum(size(y2) > 1) ~= 1 || ...
		length(x2) ~= length(y2)
	error('X2 and Y2 must be equal-length vectors of at least 2 points.')
end

% Force all inputs to be column vectors.
x1 = x1(:);
y1 = y1(:);
x2 = x2(:);
y2 = y2(:);

% Compute number of line segments in each curve and some differences we'll
% need later.
n1 = length(x1) - 1;
n2 = length(x2) - 1;
xy1 = [x1 y1];
xy2 = [x2 y2];
dxy1 = diff(xy1);
dxy2 = diff(xy2);

% Determine the combinations of i and j where the rectangle enclosing the
% i'th line segment of curve 1 overlaps with the rectangle enclosing the
% j'th line segment of curve 2.
[i,j] = find(repmat(min(x1(1:end-1),x1(2:end)),1,n2) <= ...
	repmat(max(x2(1:end-1),x2(2:end)).',n1,1) & ...
	repmat(max(x1(1:end-1),x1(2:end)),1,n2) >= ...
	repmat(min(x2(1:end-1),x2(2:end)).',n1,1) & ...
	repmat(min(y1(1:end-1),y1(2:end)),1,n2) <= ...
	repmat(max(y2(1:end-1),y2(2:end)).',n1,1) & ...
	repmat(max(y1(1:end-1),y1(2:end)),1,n2) >= ...
	repmat(min(y2(1:end-1),y2(2:end)).',n1,1));

% Force i and j to be column vectors, even when their length is zero, i.e.,
% we want them to be 0-by-1 instead of 0-by-0.
i = reshape(i,[],1);
j = reshape(j,[],1);

% Find segments pairs which have at least one vertex = NaN and remove them.
% This line is a fast way of finding such segment pairs.  We take
% advantage of the fact that NaNs propagate through calculations, in
% particular subtraction (in the calculation of dxy1 and dxy2, which we
% need anyway) and addition.
% At the same time we can remove redundant combinations of i and j in the
% case of finding intersections of a line with itself.
if self_intersect
	remove = isnan(sum(dxy1(i,:) + dxy2(j,:),2)) | j <= i + 1;
else
	remove = isnan(sum(dxy1(i,:) + dxy2(j,:),2));
end
i(remove) = [];
j(remove) = [];

% Initialize matrices.  We'll put the T's and B's in matrices and use them
% one column at a time.  AA is a 3-D extension of A where we'll use one
% plane at a time.
n = length(i);
T = zeros(4,n);
AA = zeros(4,4,n);
AA([1 2],3,:) = -1;
AA([3 4],4,:) = -1;
AA([1 3],1,:) = dxy1(i,:).';
AA([2 4],2,:) = dxy2(j,:).';
B = -[x1(i) x2(j) y1(i) y2(j)].';

% Loop through possibilities.  Trap singularity warning and then use
% lastwarn to see if that plane of AA is near singular.  Process any such
% segment pairs to determine if they are colinear (overlap) or merely
% parallel.  That test consists of checking to see if one of the endpoints
% of the curve 2 segment lies on the curve 1 segment.  This is done by
% checking the cross product
%
%   (x1(2),y1(2)) - (x1(1),y1(1)) x (x2(2),y2(2)) - (x1(1),y1(1)).
%
% If this is close to zero then the segments overlap.

% If the robust option is false then we assume no two segment pairs are
% parallel and just go ahead and do the computation.  If A is ever singular
% a warning will appear.  This is faster and obviously you should use it
% only when you know you will never have overlapping or parallel segment
% pairs.

if robust
	overlap = false(n,1);
	warning_state = warning('off','MATLAB:singularMatrix');
	% Use try-catch to guarantee original warning state is restored.
	try
		lastwarn('')
		for k = 1:n
			T(:,k) = AA(:,:,k)\B(:,k);
			[unused,last_warn] = lastwarn;
			lastwarn('')
			if strcmp(last_warn,'MATLAB:singularMatrix')
				% Force in_range(k) to be false.
				T(1,k) = NaN;
				% Determine if these segments overlap or are just parallel.
				overlap(k) = rcond([dxy1(i(k),:);xy2(j(k),:) - xy1(i(k),:)]) < eps;
			end
		end
		warning(warning_state)
	catch err
		warning(warning_state)
		rethrow(err)
	end
	% Find where t1 and t2 are between 0 and 1 and return the corresponding
	% x0 and y0 values.
	in_range = (T(1,:) >= 0 & T(2,:) >= 0 & T(1,:) <= 1 & T(2,:) <= 1).';
	% For overlapping segment pairs the algorithm will return an
	% intersection point that is at the center of the overlapping region.
	if any(overlap)
		ia = i(overlap);
		ja = j(overlap);
		% set x0 and y0 to middle of overlapping region.
		T(3,overlap) = (max(min(x1(ia),x1(ia+1)),min(x2(ja),x2(ja+1))) + ...
			min(max(x1(ia),x1(ia+1)),max(x2(ja),x2(ja+1)))).'/2;
		T(4,overlap) = (max(min(y1(ia),y1(ia+1)),min(y2(ja),y2(ja+1))) + ...
			min(max(y1(ia),y1(ia+1)),max(y2(ja),y2(ja+1)))).'/2;
		selected = in_range | overlap;
	else
		selected = in_range;
	end
	xy0 = T(3:4,selected).';

	% Remove duplicate intersection points.
	[xy0,index] = unique(xy0,'rows');
	x0 = xy0(:,1);
	y0 = xy0(:,2);

	% Compute how far along each line segment the intersections are.
	if nargout > 2
		sel_index = find(selected);
		sel = sel_index(index);
		iout = i(sel) + T(1,sel).';
		jout = j(sel) + T(2,sel).';
	end
else % non-robust option
	for k = 1:n
		[L,U] = lu(AA(:,:,k));
		T(:,k) = U\(L\B(:,k));
	end

	% Find where t1 and t2 are between 0 and 1 and return the corresponding
	% x0 and y0 values.
	in_range = (T(1,:) >= 0 & T(2,:) >= 0 & T(1,:) < 1 & T(2,:) < 1).';
	x0 = T(3,in_range).';
	y0 = T(4,in_range).';

	% Compute how far along each line segment the intersections are.
	if nargout > 2
		iout = i(in_range) + T(1,in_range).';
		jout = j(in_range) + T(2,in_range).';
	end
end

% Plot the results (useful for debugging).
% plot(x1,y1,x2,y2,x0,y0,'ok');


function res = hbg(im,thresh)

% inputs
% im is the fourier transform of the image
% thresh is the cutoff circle radius

%outputs
% res is the boosted image

[r,c]=size(im);
d0=thresh;
d=zeros(r,c);
h=zeros(r,c);

for i=1:r
    for j=1:c
     d(i,j)=  sqrt( (i-(r/2))^2 + (j-(c/2))^2);
    end
end

A=1.75; % boost factor or coefficient

for i=1:r
    for j=1:c

         h(i,j)= 1-exp ( -( (d(i,j)^2)/(2*(d0^2)) ) );
         h(i,j)=(A-1)+h(i,j);
    end

end

for i=1:r
    for j=1:c
    res(i,j)=(h(i,j))*im(i,j);
    end
end


function [w,msg,msgobj] = my_gencoswin(varargin)
%GENCOSWIN   Returns one of the generalized cosine windows.
%   GENCOSWIN returns the generalized cosine window specified by the
%   first string argument. Its inputs can be
%     Window name    - a string, any of 'hamming', 'hann', 'blackman'.
%     N              - length of the window desired.
%     Sampling flag  - optional string, one of 'symmetric', 'periodic'.

%   Copyright 1988-2010 The MathWorks, Inc.
%   $Revision: 1.7.4.3 $  $Date: 2011/05/13 18:14:10 $

% Parse the inputs
window = varargin{1};
n = varargin{2};
msg = '';
msgobj = [];

% Check for trivial orders
% [n,w,trivialwin] = check_order(n);
% if trivialwin, return, end;

% Select the sampling option
if nargin == 2, % no sampling flag specified, use default.
    sflag = 'symmetric';
else
    sflag = lower(varargin{3});
end

% Allow partial strings for sampling options
allsflags = {'symmetric','periodic'};
sflagindex = strmatch(sflag, allsflags);
if length(sflagindex)~=1         % catch 0 or 2 matches
    msgobj = message('signal:gencoswin:BadFlag','symmetric','periodic');
    msg = getString(msgobj);
    return;
else
    sflag = allsflags{sflagindex};
end

% Evaluate the window
switch sflag
case 'periodic'
    w = sym_window(n+1,window);
    w(end) = [];
case 'symmetric'
    w = sym_window(n,window);
end

%---------------------------------------------------------------------
function w = sym_window(n,window)
%SYM_WINDOW   Symmetric generalized cosine window.
%   SYM_WINDOW Returns an exactly symmetric N point generalized cosine
%   window by evaluating the first half and then flipping the same samples
%   over the other half.

if ~rem(n,2)
    % Even length window
    half = n/2;
    w = calc_window(half,n,window);
    w = [w; w(end:-1:1)];
else
    % Odd length window
    half = (n+1)/2;
    w = calc_window(half,n,window);
    w = [w; w(end-1:-1:1)];
end

%---------------------------------------------------------------------
function w = calc_window(m,n,window)
%CALC_WINDOW   Calculate the generalized cosine window samples.
%   CALC_WINDOW Calculates and returns the first M points of an N point
%   generalized cosine window determined by the 'window' string.

x = (0:m-1)'/(n-1);

switch window
case 'hann'
    % Hann window
    % w = 0.5 * (1 - cos(2*pi*(0:m-1)'/(n-1)));
    w = 0.5 - 0.5*cos(2*pi*x);
case 'hamming'
    % Hamming window
    % w = (54 - 46*cos(2*pi*(0:m-1)'/(n-1)))/100;
    w = 0.54 - 0.46*cos(2*pi*x);
case 'blackman'
    % Blackman window
    % Force end points to zero to avoid close-to-zero negative values caused
    % by roundoff errors.
    % w = (42 - 50*cos(2*pi*(0:m-1)/(n-1)) + 8*cos(4*pi*(0:m-1)/(n-1)))'/100;
    w = 0.42 - 0.5*cos(2*pi*x) + 0.08*cos(4*pi*x);
    w(1) = 0;
case 'flattopwin'
    % Flattop window
    % Coefficients as defined in the reference [1] (see flattopwin.m)
    a0 = 0.21557895;
    a1 = 0.41663158;
    a2 = 0.277263158;
    a3 = 0.083578947;
    a4 = 0.006947368;
    w = a0 - a1*cos(2*pi*x) + a2*cos(4*pi*x) - a3*cos(6*pi*x) + ...
      a4*cos(8*pi*x);
end

% [EOF] gencoswin.m


 function [proj, J, alpha, kb_m, d] = kaiser_bessel_xray(r, J, alpha, kb_m, d)
%function [proj, J, alpha, kb_m, d] = kaiser_bessel_xray(r, J, alpha, kb_m, d)
%
% X-ray transform of generalized Kaiser-Bessel function,
% See (A7) in lewitt:90:mdi, JOSA-A, Oct. 1990.
%
% in
%	r	[?]	radial locations in projection space (unitless)
%
% options
%	J		diameter of blob (a = J/2), default 4
%	alpha		shape parameter, default 10.83
%	kb_m		order parameter, default 2
%	d		dimension, default 2
%
% out
%	proj	[?]	x-ray transform values
%
% Copyright 2005-7-29, Jeff Fessler, The University of Michigan

if nargin < 1, ir_usage, end
if nargin == 1 && streq(r, 'test'), kaiser_bessel_xray_test, return, end

if ~isvar('J'), J = 4; end
if ~isvar('alpha') || isempty('alpha'), alpha = 10.83; end
if ~isvar('kb_m') || isempty('kb_m'), kb_m = 2; end
if ~isvar('d'), d = 2; end
tol = 1e-4;

%
% trick to yield inline functions
%
if ischar(r)
	kernel = sprintf('kaiser_bessel_xray(r, %d, %g, %g, %g)', ...
		J, alpha, kb_m, d);

	if streq(r, 'string')
		proj = kernel;
	elseif streq(r, 'inline')
		proj = inline(kernel, 'r');
	else
		error 'bad argument'
	end
return
end

%
% Check for validity of FT formula
%
persistent warned
if (kb_m < 0 || (abs(round(kb_m)-kb_m) > eps))
	if isempty(warned)
		printf([mfilename: 'kb_m=%g in kaiser_bessel_xray()'], kb_m)
		printf('validity of formula uncertain')
		warned = 1;
	end
end

a = J/2;
factor = a / besseli(kb_m, alpha) * sqrt(2*pi/alpha);
root = sqrt(1 - (r/a).^2);
nu = kb_m + 1/2;
proj = factor * root.^nu .* besseli(nu, alpha * root);
proj = reale(proj, tol);

%
% test
%
function kaiser_bessel_xray_test
x = linspace(-2.5,2.5,501)';
y = x;
[xx yy] = ndgrid(x, y);
r = sqrt(xx.^2 + yy.^2);
[proj J kb_m alpha] = kaiser_bessel_xray(x);
dx = x(2) - x(1);

f0 = kaiser_bessel(r, J, kb_m, alpha);
psum = sum(f0,2) * dx;

if im
	clf
	im(221, x, y, f0, 'blob'), grid
	subplot(222)
	plot(x, f0(:,y==0)), title 'profile', axis tight
	xtick([-2:1.0:2]), grid
	subplot(212)
	plot(x, proj, '-', x, psum, '--'), axis tight, title 'projection'
	legend('Analytical', 'Numerical')
end
max_percent_diff(proj, psum, mfilename)


function pdf = reciprocal_pdf ( x, a, b )

%*****************************************************************************80
%
%% RECIPROCAL_PDF evaluates the Reciprocal PDF.
%
%  Formula:
%
%    PDF(X)(A,B) = 1.0D+00 / ( X * LOG ( B / A ) )
%    for 0.0D+00 <= X
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 September 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, real X, the argument of the PDF.
%
%    Input, real A, B, the parameters of the PDF.
%    0.0 < A <= B.
%
%    Output, real PDF, the value of the PDF.
%
  if ( x <= 0.0 )
    pdf = 0.0;
  elseif ( 0.0 < x )
    pdf = 1.0 / ( x * log ( b / a ) );
  end

  return
end


function [bmproc] = brownian(npoints, sigma)
% BROWNIAN generate and plot an aproximation to Brownian motion.
%   Generates a random walk with normally distributed jumps
%
% [bmproc] = brownian(npoints [, sigma])
%
% Inputs: npoints - length of the trajectory
%         sigma - optional, the norming constant (standard
%         deviation of B(1)). Default 1.
%
% Outputs: bmproc - trajectory of the process

% Authors: R.Gaigalas, I.Kaj
% v1.2 04-Oct-02

  % set default parameter values
  if (nargin==1)
    sigma = 1;
  end

  % generate a sample from a Gaussian distribution and sum up
  bmproc = [0 cumsum(sigma.*randn(1, npoints-1))];

  % plot the process
  plot([0:npoints-1], bmproc);


function g = p27_g ( n, x )

%*****************************************************************************80
%
%% P27_G evaluates the gradient for problem 27.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 January 2001
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the number of variables.
%
%    Input, real X(N), the values of the variables.
%
%    Output, real G(N), the gradient of the objective function.
%
  g = zeros ( n, 1 );

  r = sqrt ( x(1)^2 + x(2)^2 );

  if ( r == 0.0 )
    g(1) = 0.0;
    g(2) = 0.0;
    return
  end

  rx1 = x(1) / r;
  rx2 = x(2) / r;

  a = ( 1.0 + 0.001 * r^2 )^( -2 );
  ar = - 0.004 * r * ( 1.0 + 0.001 * r^2 )^( -3 );

  b = ( sin ( r ) )^2 - 0.5;
  br = sin ( 2.0 * r );

  g(1) = ( ar * b + a * br ) * rx1;
  g(2) = ( ar * b + a * br ) * rx2;

  return
end


function x = MW2cv(P,N)
%MW1CV   critical Mann-Whitney's U associated to a p-value.
%It obtain a Mann-Whitney's U of two random variables with continuous cumulative
%distribution associated to a p-value. This procedure is highly recommended for sample sizes
%7< nx & ny <=40. For nx & ny <=7 it is recommended to use the MW1cv function;
%otherwise, U-value may be a poor approximation.
%It works with a procedure to get the nearest cumulative distribution relative value to P.
%[Based on the Fortran77 algorithm AS 62 Appl. Statist. (1973)]
%
%   Syntax: function x = MW2cv(P,N)
%
%     Inputs:
%          P - cumulative probability value of interest.
%          N - 2-element vector of sample sizes for the two samples [].
% The input quantities should be scalars.
%     Outputs:
%          x - Mann-Whitney's U statistic.
%
%    Example: For two independent samples we are interested to get the
%             Mann-Whitney's statistic U with an associated cumulative
%             probability P = 0.95. Sample sizes are n1 = 36 and n2 = 14.
%
%                              P = 0.95; N = [36,14];
%
%     Calling on Matlab the function:
%             x = MW2cv(P,N)
%
%       Answer is:
%
%                 328
%

%  Created by A. Trujillo-Ortiz and R. Hernandez-Walls
%             Facultad de Ciencias Marinas
%             Universidad Autonoma de Baja California
%             Apdo. Postal 453
%             Ensenada, Baja California
%             Mexico.
%             atrujo@uabc.mx
%
%  May 23, 2003.
%
%  To cite this file, this would be an appropriate format:
%  Trujillo-Ortiz, A. and R. Hernandez-Walls. (2003). MW2cv: Critical Mann-Whitney's U
%    associated to a p-value: nx or ny >7. A MATLAB file. [WWW document]. URL http://
%    www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=3555&objectType=FILE
%
%  References:
%
%  Mann, H. B. and Whitney, D. R. (1947), On a test of whether one of two
%           random variables is stochastically larger than the other. Annals
%           of Mathematical Statistics, 18: 50-60.
%  Algorithm AS 62 (1973). Journal of Applied Statistics, 22(2):1-3.
%

if nargin <  2,
   error('Requires two input arguments.');
end

nmin = min(N);  %largest sample size.
nmax = max(N);  %smallest sample size.

if (nmin <= 7) & (nmax <= 7);
   fprintf('Warning: For nx and ny <= 7, the p-value may be a poor approximation.\n');
   fprintf('It is recommended to use the MW1cv function you can find on the\n');
   fprintf('Matlab>File Exchange Antonio Trujillo-Ortiz'' Author Page.\n');
   disp(' ');
   cont=input('Do you want to continue anyway (y/n):','s');

   if (cont=='y');
      disp('Here it goes.');

      mn1 = prod(N)+1;
      n1 = nmax+1;
      freq = [ones(n1,1); zeros(mn1-n1,1)];

      lwrk = floor((mn1+1)/2 + nmin);
      work = zeros(lwrk,1);

% Generate successively higher-order distributions
      in = nmax;
      for i = 2:nmin
         in = in+nmax;
         n1 = in+2;
         l = 1 + in/2;
         k = i;

% Generate complete distribution from outside inwards
         for j = 1:l
            k = k+1;
            n1 = n1-1;
            summ = freq(j) + work(j);
            freq(j) = summ;
            work(k) = summ - freq(n1);
            freq(n1) = summ;
         end;
      end;

      freq = freq/sum(freq);  % Make distribution relative

% Cumulative frequency distribution
      cumfreq = cumsum(freq);

%Location of the interested Mann-Whitney's U on all the possible U's for this 2-sample sizes.
%Here we are using a procedure to get the nearest fc value to P.
      cumfreq=cumfreq-P;
      u = find(abs(cumfreq)==min(abs(cumfreq(:))));

      UU = [0:length(freq)-1];  %vector of all the possible Mann-Whitney's U values.

%Association of the interested Mann-Whitney's U with its cumulative distribution.
      x = UU(u);
   else
   end
else

   mn1 = prod(N)+1;
   n1 = nmax+1;
   freq = [ones(n1,1); zeros(mn1-n1,1)];

   lwrk = floor((mn1+1)/2 + nmin);
   work = zeros(lwrk,1);

%Generate successively higher-order distributions
   in = nmax;
   for i = 2:nmin
      in = in+nmax;
      n1 = in+2;
      l = 1 + in/2;
      k = i;

%Generate complete distribution from outside inwards
      for j = 1:l
         k = k+1;
         n1 = n1-1;
         summ = freq(j) + work(j);
         freq(j) = summ;
         work(k) = summ - freq(n1);
         freq(n1) = summ;
      end;
   end;

   freq = freq/sum(freq);  % Make distribution relative

% Cumulative frequency distribution
   cumfreq = cumsum(freq);

%Location of the interested Mann-Whitney's U on all the possible U's for this 2-sample sizes.
%Here we are using a procedure to get the nearest fc value to P.
   cumfreq=cumfreq-P;
   u = find(abs(cumfreq)==min(abs(cumfreq(:))));

   UU = [0:length(freq)-1];  %vector of all the possible Mann-Whitney's U values.

%Association of the interested Mann-Whitney's U with its cumulative distribution.
   x = UU(u);
end


function varargout = holdertable(X)
% Holder table function
%
%   HOLDERTABLE([x1, x2]) returns the value of the Holder table
%   function at the specified points. [x1] and [x2] may be vectors.
%   The search domain is
%
%               -10 < x_i < 10
%
%   The four global minima are near the edges of the interval, and have a
%   function value of
%
%       f(x*) = -1.92085026.

% Author: Rody P.S. Oldenhuis
% Delft University of Technology
% E-mail: oldenhuis@dds.nl
% Last edited 20/Jul/2009

    % if no input is given, return dimensions, bounds and minimum
    if (nargin == 0)
        varargout{1} = 2;  % # dims
        varargout{2} = [-10, -10]; % LB
        varargout{3} = [+10, +10]; % UB
        varargout{4} = [+8.055023472141116e+000   +9.664590028909654e+000
                        -8.055023472141116e+000   +9.664590028909654e+000
                        +8.055023472141116e+000   -9.664590028909654e+000
                        -8.055023472141116e+000   -9.664590028909654e+000]; % solution
        varargout{5} = -1.920850256788675e+001; % function value at solution

    % otherwise, output function value
    else

        % keep values within the search interval
        X(X < -10) = inf;      X(X > 10) = inf;

        % split input vector X into x1, x2
        if size(X, 1) == 2
            x1 = X(1, :);        x2 = X(2, :);
        else
            x1 = X(:, 1);        x2 = X(:, 2);
        end

        % output function value
        varargout{1} = -abs(sin(x1).*cos(x2).*exp(abs(1 - sqrt(x1.^2 + x2.^2)/pi)));

    end

end


function r = hammersley_sequence ( n )

%*****************************************************************************80
%
%% HAMMERSLEY_SEQUENCE computes N elements of a leaped Hammersley subsequence.
%
%  Discussion:
%
%    The DIM_NUM-dimensional Hammersley sequence is really DIM_NUM separate
%    sequences, each generated by a particular base.  If the base is
%    greater than 1, a standard 1-dimensional
%    van der Corput sequence is generated.  But if the base is
%    negative, this is a signal that the much simpler sequence J/(-BASE)
%    is to be generated.  For the standard Hammersley sequence, the
%    first spatial coordinate uses a base of (-N), and subsequent
%    coordinates use bases of successive primes (2, 3, 5, 7, 11, ...).
%    This program allows the user to specify any combination of bases,
%    included nonprimes and repeated values.
%
%    This routine selects elements of a "leaped" subsequence of the
%    Hammersley sequence.  The subsequence elements are indexed by a
%    quantity called STEP, which starts at 0.  The STEP-th subsequence
%    element is simply element
%
%      SEED(1:DIM_NUM) + STEP * LEAP(1:DIM_NUM)
%
%    of the original Hammersley sequence.
%
%
%    This routine "hides" a number of input arguments.  To specify these
%    arguments explicitly, use I4_TO_HAMMERSLEY instead.
%
%    All the arguments have default values.  However, if you want to
%    examine or change them, you may call the appropriate routine first.
%
%    * DIM_NUM, the spatial dimension,
%      Default: DIM_NUM = 1;
%      Required: 1 <= DIM_NUM is required.
%
%    * STEP, the subsequence index.
%      Default: STEP = 0.
%      Required: 0 <= STEP.
%
%    * SEED(1:DIM_NUM), the Hammersley sequence element corresponding to STEP = 0.
%      Default SEED = (0, 0, ... 0).
%      Required: 0 <= SEED(1:DIM_NUM).
%
%    * LEAP(1:DIM_NUM), the succesive jumps in the Hammersley sequence.
%      Default: LEAP = (1, 1, ..., 1).
%      Required: 1 <= LEAP(1:DIM_NUM).
%
%    * BASE(1:DIM_NUM), the Hammersley bases.
%      Default: BASE = (2, 3, 5, 7, 11, ... ) or (-N,2,3,5,7,11,...) if N is known.
%      Required: 1 < BASE(I) for any van der Corput dimension, or BASE(I) < 0
%      to generate the fractional sequence J/|BASE(I)|.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 July 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    J M Hammersley,
%    Monte Carlo methods for solving multivariable problems,
%    Proceedings of the New York Academy of Science,
%    Volume 86, 1960, pages 844-874.
%
%    Ladislav Kocis and William Whiten,
%    Computational Investigations of Low-Discrepancy Sequences,
%    ACM Transactions on Mathematical Software,
%    Volume 23, Number 2, 1997, pages 266-294.
%
%  Parameters:
%
%    Input, integer N, the number of elements to compute.
%
%    Output, real R(DIM_NUM,N), the SEED-th through SEED+N-1th elements of
%    the Hammersley sequence.
%
  dim_num = hammersley_dim_num_get ( );
  step = hammersley_step_get ( );
  seed = hammersley_seed_get ( );
  leap = hammersley_leap_get ( );
  base = hammersley_base_get ( );

  r = i4_to_hammersley_sequence ( dim_num, n, step, seed, leap, base );

  step = step + n;

  hammersley_step_set ( step );

  return
end


function [E, E1, E2, Et, Et1, Et2] = testClassSeperability(N,MEAN1,STD1,MEAN2,STD2, PLOT)

%
% This function generates two random Gaussian sequences and computes
% both the theoretical error and the histogram-based method, using
% respectively the functions computeHistError() and theoreticalError().
%
%
% ARGUMENTS:
% N: number of samples per class
% MEAN1: average value of the samples (1st class)
% STD1: standard deviation of the samples (1st class)
% MEAN2: average value of the samples (2nd class)
% STD2: standard deviation of the samples (2nd class)
% PLOT: this is 1 if results are to be plotted
%
% --------------------------------------------
% Theodoros Giannakopoulos
% Dep. of Informatics and Telecommunications
% University of Athens, Greece
% http://www.di.uoa.gr/~tyiannak
% --------------------------------------------
%

if (N<100)
    fprintf('N has to be at lest 1000!\n');
    return;
end

% GENERATE DATASETS (normal distribution)
x1 = randn(N,1) * sqrt(STD1) + MEAN1;
x2 = randn(N,1) * sqrt(STD2) + MEAN2;

if (N<1000)
    nBins = 10;
else
    if (N<10000)
        nBins = 50;
    else
        nBins = 100;
    end
end

% CALCULATE HISTOGRAMS FOR BOTH CLASSES:
step = (max(MEAN1,MEAN2) - min(MEAN1,MEAN2)) / nBins;
X = min(MEAN1-3*STD1,MEAN2-3*STD2): step : max(MEAN1+3*STD1,MEAN2+3*STD2);
[H1, X1] = hist(x1, X);
[H2, X2] = hist(x2, X);

% COMPUTE THE ERROR PROBABILITIES FOR BOTH CLASSES using the historam method:
%
% N O T E : this function computes the error classification probability for
% the training data using the histograms as a pdf estimation method.
% Therefore, it can be used for any distribution of input data.
%

[E1, E2] = computeHistError(x1, x2);
E1 = 100* E1;
E2 = 100* E2;

% OVERALL ERROR PROBABILITY:
E = (E1 + E2) / 2;

if (PLOT==1)
    figure;
    subplot(2,1,1);
    str = sprintf('Estimated Errors: E1 = %.2f%%, E2 = %.2f%%, E = %.2f%%.', E1, E2, E);
    plot(X1, H1);
    hold on;
    plot(X2, H2,'r');
    legend('Class A','Class B');
    title(str);
    axis([min(MEAN1-3*STD1,MEAN2-3*STD2) max(MEAN1+3*STD1,MEAN2+3*STD2) 0 max([H1 H2])]);
    subplot(2,1,2);
    [Et, Et1, Et2, x] = theoreticalError(MEAN1, STD1, MEAN2, STD2);
    str = sprintf('Theoretical Errors: E1 = %.2f%%, E2 = %.2f%%, E = %.2f%%.', Et1, Et2, Et);
    title(str);
end


% %Question No: 5 (a)
% Determine the weights of a network with 4 input and 2 output units using
% Perceptron Learning Law for the following input-output pairs:

% Input: [1100]' [1001]' [0011]' [0110]'
% output: [11]' [10]' [01]' [00]'
% Discuss your results for different choices of the learning rate
% parameters.
% Use suitable values for the initial weights.

in=[1 1 0 0 -1;1 0 0 1 -1; 0 0 1 1 -1; 0 1 1 0 -1];
out=[1 1; 1 0; 0 1; 0 0];
eta=input('Enter the learning rate value = ');
it=input('Enter the number of iterations required = ');
wgt=input('Enter the weights,2 by 5 matrix(including weight for bias):\n');
for x=1:it
    for i=1:4
        s1=0;
        s2=0;
        for j=1:5
          s1=s1+in(i,j)*wgt(1,j);
          s2=s2+in(i,j)*wgt(2,j);
        end
        wi=eta*(out(i,1)-sign(s1))*in(i,:);
        wgt(1,:)=wgt(1,:)+wi;
        wi=eta*(out(i,2)-sign(s2))*in(i,:);
        wgt(2,:)=wgt(2,:)+wi;
    end
end
wgt