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

%*****************************************************************************80
%
%% JED_TO_YMDF_SYRIAN converts a JED to a Syrian YMDF date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 July 2012
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Edward Richards,
%    Algorithm F,
%    Mapping Time, The Calendar and Its History,
%    Oxford, 1999, pages 324-325.
%
%  Parameters:
%
%    Input, real JED, the Julian Ephemeris Date.
%
%    Output, integer Y, M, D, real F,
%    the YMDF date.
%

%
%  Determine the computational date (Y'/M'/D').
%
  j = floor ( jed + 0.5 );
  f = ( jed + 0.5 ) - j;

  j_prime = j + 1401;

  y_prime = floor ( ( 4 * j_prime + 3 ) / 1461 );
  t_prime = floor ( mod ( 4 * j_prime + 3, 1461 ) / 4 );
  m_prime = floor ( ( 5 * t_prime + 2 ) / 153 );
  d_prime = floor ( mod ( 5 * t_prime + 2, 153 ) / 5 );
%
%  Convert the computational date to a calendar date.
%
  d = d_prime + 1;
  m = mod ( m_prime + 5, 12 ) + 1;
  y = y_prime - 4405 + floor ( ( 17 - m ) / 12 );

  return
end


options = optimset('GradObj','on','Hessian','on');
[x,y]=fminunc('fun4',rand(1,2),options)


function [kappa,pval,k, pk]=kappa_stats(D,ncat)
% calculate Kappa statisc for agreement
% D: matrix NxM of N scores by M raters
% cat: categories
% Written By Issam El Naqa Date: 03/21/07
% ref.: SAS docs. (Fleiss '81)
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

[N,M]=size(D);
lk=length(ncat); % number of categories
for i=1:lk
    x(:,i) = sum(D==ncat(i),2);
end
p=sum(x)/(N*M);
k=1-sum(x.*(M-x))./((N*M*(M-1).*p.*(1-p))+eps);
sek=sqrt(2/(N*M*(M-1)));
pk=drxlr_get_p_gaussian(k./sek)/2; % one-sided
% kappa=sum(p.*(1-p).*k)/sum(p.*(1-p));
kappa=1-(N*M^2-sum(sum(x.^2)))/((N*M*(M-1)*sum(p.*(1-p)))+eps);
sekappa=sqrt(2)/(sum(p.*(1-p)*sqrt(N*M*(M-1)))+eps)*sqrt(sum(p.*(1-p))^2-sum(p.*(1-p).*(1-2*p)));
z=kappa/sekappa;
pval=drxlr_get_p_gaussian(z)/2; % one-sided
return

function p=drxlr_get_p_gaussian(x)
% two tailed p-value from a normal distribution
%DREX subfunction
%Written by Issam El Naqa 2003-2005
%Extracted for generalized use 2005, AJH

    p = erfc(abs(x)./sqrt(2));

return


%% Example: Dense SDP relaxation for quartic optimization over the sphere

clc; clear; close all; restoredefaultpath; % start clean

mosekpath = '../../mosek';
pgdpath   = '../STRIDE';
sdpnalpath  = '../../SDPNAL+v1.0';
manoptpath  = '../manopt';
utilspath   = '../utils';
addpath(genpath(utilspath))
addpath(genpath(manoptpath))
addpath(genpath('./solvers'))
addpath(genpath('../spotless')) % Use spotless for defining polynomials
addpath('../SDPRelaxations') % implementations for SDP relaxation

%% Generate random binary quadratic program
d       = 30; % d variables
x       = msspoly('x',d); % symbolic decision variables using SPOTLESS
v       = monomials(x,0:4);
c       = randn(length(v),1);
f       = c'*v; % objective function
h       = sum(x.^2) - 1; % equality constraints

%% Relax BQP into an SDP
problem.vars            = x;
problem.objective       = f;
problem.equality        = h;
kappa                   = 2; % relaxation order
[SDP,info]              = dense_sdp_relax(problem,kappa);
SDP.M       = 3; % upper bound on the trace of the moment matrix
% need the following for fast computation in the local search method
info.v      = msspoly2degcoeff(info.v);
info.f      = msspoly2degcoeff(info.f);
info.J      = msspoly2degcoeff(info.J);

%{
%% Solve using MOSEK, should be slow
prob       = convert_sedumi2mosek(SDP.sedumi.At,...
                                  SDP.sedumi.b,...
                                  SDP.sedumi.c,...
                                  SDP.sedumi.K);
addpath(genpath(mosekpath))
[~,res]    = mosekopt('minimize info',prob);
[Xopt,yopt,Sopt,obj] = recover_mosek_sol_blk(res,SDP.blk);
rmpath(genpath(mosekpath))

figure; bar(eig(Xopt{1})); % if rank = 1, then relaxation is exact/tight
%}

%% solve using stride
addpath(genpath(pgdpath))

pgdopts.pgdStepSize     = 10;
pgdopts.SDPNALpath      = sdpnalpath;
pgdopts.tolADMM         = 10e-5;
pgdopts.phase1          = 1;
pgdopts.rrOpt           = 1:3;
pgdopts.rrFunName       = 'local_search_q4s';
pgdopts.rrPar           = info;
pgdopts.maxiterLBFGS    = 1000;
pgdopts.maxiterSGS      = 300;
pgdopts.tolLBFGS        = 1e-12;
pgdopts.tolPGD          = 1e-8;

[outPGD,Xopt,yopt,Sopt]     = PGDSDP(SDP.blk, SDP.At, SDP.b, SDP.C, [], pgdopts);
time_pgd                    = outPGD.totaltime;
% round solutions and check optimality certificate
res = get_performance_q4s(Xopt,yopt,Sopt,SDP,info,pgdpath);

%% helper functions
function s = msspoly2degcoeff(f)
[~,degmat,coeff,~] = decomp(f);
s.degmat = degmat';
s.coefficient = coeff;
end


% Given time domain samples, extracts out each of the OFDM symbols minus their cyclic prefixes for both time and
% frequency domains.  First sample must be the exact start of the burst!
%
% @param samples Time domain samples as a row/column vector
function [time_domain, freq_domain] = extract_ofdm_symbol_samples(samples, sample_rate)
    assert(isrow(samples) || iscolumn(samples), "Samples must be a row or column vector");

    fft_size = get_fft_size(sample_rate);
    [long_cp_len, short_cp_len] = get_cyclic_prefix_lengths(sample_rate);

    % List of cyclic prefix lengths for each OFDM symbol
    cp_lengths = [
        long_cp_len,...
        short_cp_len,...
        short_cp_len,...
        short_cp_len,...
        short_cp_len,...
        short_cp_len,...
        short_cp_len,...
        short_cp_len,...
        long_cp_len...
    ];

    freq_domain = zeros(length(cp_lengths), fft_size);
    time_domain = zeros(length(cp_lengths), fft_size);

    sample_offset = 1;
    for idx=1:length(cp_lengths)
        % Skip the cyclic prefix
        symbol = samples(sample_offset:sample_offset + fft_size + cp_lengths(idx) - 1);
        symbol = symbol(cp_lengths(idx) + 1:end);

        % Extract the time domain samples for this OFDM symbol
        time_domain(idx,:) = symbol;

        % Convert the time domain samples into frequency domain
        freq_domain(idx,:) = fftshift(fft(time_domain(idx,:)));

        sample_offset = sample_offset + fft_size + cp_lengths(idx);
    end
end


function cc_levels_constrained_display ( )

%*****************************************************************************80
%
%% CC_LEVELS_CONSTRAINED_DISPLAY displays grids generated by CC_LEVELS_CONSTRAINED.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 November 2006
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  timestamp ( );

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CC_LEVELS_CONSTRAINED_DISPLAY:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Display the 2D Clenshaw-Curtis grids\n' );
  fprintf ( 1, '  generated by CC_LEVELS_CONSTRAINED.\n' );

  dim_num = 2;

  while ( 1 )
%
%  Get user input.
%
    q_max = input ( 'Enter Q_MAX or RETURN to exit;' );

    if ( isempty ( q_max ) )
      break
    end

    if ( q_max < dim_num )
      fprintf ( 1, '\n' );
      fprintf ( 1, '  We require DIM_NUM <= Q_MAX!\n' );
      continue
    end

    alpha = input ( 'Enter [ ALPHA1, ALPHA2 ] or RETURN to exit;' );

    if ( isempty ( alpha ) )
      break
    end

    level_min = input ( 'Enter [ LEVEL_MIN1, LEVEL_MIN2 ] or RETURN to exit;' );

    if ( isempty ( level_min ) )
      break
    end

    level_max = input ( 'Enter [ LEVEL_MAX1, LEVEL_MAX2 ] or RETURN to exit;' );

    if ( isempty ( level_max ) )
      break
    end
%
%  Compute data.
%
    [ grid_num, point_num ] = cc_levels_constrained_size ( dim_num, ...
      q_max, alpha, level_min, level_max );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Number of grids is %d\n', grid_num );
    fprintf ( 1, '  Number of points is %d\n', point_num );

    [ grid_level, grid_point ] = cc_levels_constrained ( dim_num, ...
      q_max, alpha, level_min, level_max, grid_num, point_num );

    clf
%
%  We have to name the axes in order to control the grid.
%
    axes_handle = axes;
%
%  Plot the points.
%
    handle = scatter ( grid_point(1,:), grid_point(2,:), 'filled' );
%
%  Force the plotting region to be square, not rectangular.
%
    axis square
%
%  Request grid lines.
%
    grid on
%
%  Specify the location of the grid lines, and suppress labeling.
%
    set ( axes_handle, 'xtick', [ -1, -.75, -.5, -.25, 0, .25, .50, .75, 1] );
    set ( axes_handle, 'xticklabel', [] );
    set ( axes_handle, 'ytick', [ -1, -.75, -.5, -.25, 0, .25, .50, .75, 1] );
    set ( axes_handle, 'yticklabel', [] );
%
%  Make the plotting region slightly bigger than the data.
%
    axis ( [ -1.1, 1.1, -1.1, 1.1 ] )
%
%  Title
%
    s = sprintf ( 'ALPHA = [ %f, %f]', alpha(1), alpha(2) );
    title ( s );

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CC_LEVELS_CONSTRAINED_DISPLAY:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );

  fprintf ( 1, '\n' );
  timestamp ( );

  return
ed


% Comparing Gaussian Blur and Guided Image Filtering
% See http://dsp.stackexchange.com/questions/29041

%% General Parameters and Initialization

clear();
close('all');

% set(0, 'DefaultFigureWindowStyle', 'docked');
defaultLooseInset = get(0, 'DefaultAxesLooseInset');
% set(0, 'DefaultAxesLooseInset', [0.05, 0.05, 0.05, 0.05]);

titleFontSize   = 14;
axisFotnSize    = 12;
stringFontSize  = 12;

thinLineWidth   = 2;
normalLineWidth = 3;
thickLineWidth  = 4;

smallSizeData   = 36;
mediumSizeData  = 48;
bigSizeData     = 60;

randomNumberStream  = RandStream('mlfg6331_64', 'NormalTransform', 'Ziggurat');
subStreamNumber     = round(sum(clock()));
% subStreamNumber    = 57162;
% subStreamNumber    = 2143;
set(randomNumberStream, 'Substream', subStreamNumber);
RandStream.setGlobalStream(randomNumberStream);

%% Setting Constants

FALSE   = 0;
TRUE    = 1;

OFF = 0;
ON  = 1;

RADIUS_TO_STD_FACTOR    = 5;

%% Setting Parameters

numRows = 400;
numCols = 400;

grayLevel1 = 245 / 255;
grayLevel2 = 10 / 255;

noiseStd = 10 / 255;

refLine1Row     = 201;
vRefLine1ColIdx = [1:numCols];

gaussianFilterRadius    = 7;
vGuidedFilterRadius     = [7, 7];
guidedFilterSmoothing   = 0.01;

%% Creating Data

borderColIdx = round(numCols / 2);

% Refrence Image
mRefImage = zeros([numRows, numCols]);
mRefImage(:, 1:borderColIdx)            = grayLevel1;
mRefImage(:, (borderColIdx + 1):end)    = grayLevel2;

% Noisy Image
mNoisyImage = mRefImage + (noiseStd * randn([numRows, numCols]));

% Gaussian Filtered Image
mGaussFilteredImage = ApplyGaussianBlur(mNoisyImage, gaussianFilterRadius, RADIUS_TO_STD_FACTOR);

% Guided Filtered Image
mGuidedFilteredImage = imguidedfilter(mNoisyImage, 'NeighborhoodSize', vGuidedFilterRadius, 'DegreeOfSmoothing', guidedFilterSmoothing);

%% Displaying Results

% Displaying Reference Image
mImgDisplay                                     = repmat(mRefImage, [1, 1, 3]);
mImgDisplay(refLine1Row, vRefLine1ColIdx, 1)    = 1;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 2)    = 0;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 3)    = 0;
for iRow = 1:numRows
    mImgDisplay(iRow, iRow, 1) = 0;
    mImgDisplay(iRow, iRow, 2) = 1;
    mImgDisplay(iRow, iRow, 3) = 0;
end

hFigure         = figure();
set(hFigure, 'Units', 'pixels', 'Position', [100, 100, 500, 500]);
hAxes           = axes('Units', 'pixels', 'Position', [50, 50, numCols, numRows]);
hImageObject    = image(mImgDisplay);
set(get(hAxes, 'Title'), 'String', 'Reference Image', 'FontSize', titleFontSize);

% Extract Line 01
vLine1 = mRefImage(refLine1Row, vRefLine1ColIdx);
% Extract Line 02
vLine2 = zeros([numRows, 1]);
for iRow = 1:numRows
    vLine2(iRow) = mRefImage(iRow, iRow);
end

hFigure = figure();
hAxes   = axes();
hLineSeries = plot([1:numCols], vLine1, [1:numRows], vLine2);
set(hLineSeries(1), 'LineWidth', normalLineWidth, 'Color', 'r');
set(hLineSeries(2), 'LineWidth', normalLineWidth, 'Color', 'g');
set(get(hAxes, 'Title'), 'String', 'Values Across Lines - Reference Image', 'FontSize', titleFontSize);
hLegend = legend({['Line #01'], ['Line #02']});
set(hLegend, 'FontSize', axisFotnSize);

% Displaying Noisy Image
mImgDisplay                                     = repmat(mNoisyImage, [1, 1, 3]);
mImgDisplay(refLine1Row, vRefLine1ColIdx, 1)    = 1;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 2)    = 0;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 3)    = 0;
for iRow = 1:numRows
    mImgDisplay(iRow, iRow, 1) = 0;
    mImgDisplay(iRow, iRow, 2) = 1;
    mImgDisplay(iRow, iRow, 3) = 0;
end

hFigure         = figure();
set(hFigure, 'Units', 'pixels', 'Position', [100, 100, 500, 500]);
hAxes           = axes('Units', 'pixels', 'Position', [50, 50, numCols, numRows]);
hImageObject    = image(mImgDisplay);
set(get(hAxes, 'Title'), 'String', 'Noisy Image', 'FontSize', titleFontSize);

% Extract Line 01
vLine1 = mNoisyImage(refLine1Row, vRefLine1ColIdx);
% Extract Line 02
vLine2 = zeros([numRows, 1]);
for iRow = 1:numRows
    vLine2(iRow) = mNoisyImage(iRow, iRow);
end

hFigure = figure();
hAxes   = axes();
hLineSeries = plot([1:numCols], vLine1, [1:numRows], vLine2);
set(hLineSeries(1), 'LineWidth', normalLineWidth, 'Color', 'r');
set(hLineSeries(2), 'LineWidth', normalLineWidth, 'Color', 'g');
set(get(hAxes, 'Title'), 'String', 'Values Across Lines - Noisy Image', 'FontSize', titleFontSize);
hLegend = legend({['Line #01'], ['Line #02']});
set(hLegend, 'FontSize', axisFotnSize);

% Displaying Gaussian Filtered Image
mImgDisplay                                     = repmat(mGaussFilteredImage, [1, 1, 3]);
mImgDisplay(refLine1Row, vRefLine1ColIdx, 1)    = 1;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 2)    = 0;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 3)    = 0;
for iRow = 1:numRows
    mImgDisplay(iRow, iRow, 1) = 0;
    mImgDisplay(iRow, iRow, 2) = 1;
    mImgDisplay(iRow, iRow, 3) = 0;
end

hFigure         = figure();
set(hFigure, 'Units', 'pixels', 'Position', [100, 100, 500, 500]);
hAxes           = axes('Units', 'pixels', 'Position', [50, 50, numCols, numRows]);
hImageObject    = image(mImgDisplay);
set(get(hAxes, 'Title'), 'String', 'Gaussian Filtered Image', 'FontSize', titleFontSize);

% Extract Line 01
vLine1 = mGaussFilteredImage(refLine1Row, vRefLine1ColIdx);
% Extract Line 02
vLine2 = zeros([numRows, 1]);
for iRow = 1:numRows
    vLine2(iRow) = mGaussFilteredImage(iRow, iRow);
end

hFigure = figure();
hAxes   = axes();
hLineSeries = plot([1:numCols], vLine1, [1:numRows], vLine2);
set(hLineSeries(1), 'LineWidth', normalLineWidth, 'Color', 'r');
set(hLineSeries(2), 'LineWidth', normalLineWidth, 'Color', 'g');
set(get(hAxes, 'Title'), 'String', 'Values Across Lines - Gaussian Filtered Image', 'FontSize', titleFontSize);
hLegend = legend({['Line #01'], ['Line #02']});
set(hLegend, 'FontSize', axisFotnSize);

% Displaying Guided Filtered Image
mImgDisplay                                     = repmat(mGuidedFilteredImage, [1, 1, 3]);
mImgDisplay(refLine1Row, vRefLine1ColIdx, 1)    = 1;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 2)    = 0;
mImgDisplay(refLine1Row, vRefLine1ColIdx, 3)    = 0;
for iRow = 1:numRows
    mImgDisplay(iRow, iRow, 1) = 0;
    mImgDisplay(iRow, iRow, 2) = 1;
    mImgDisplay(iRow, iRow, 3) = 0;
end

hFigure         = figure();
set(hFigure, 'Units', 'pixels', 'Position', [100, 100, 500, 500]);
hAxes           = axes('Units', 'pixels', 'Position', [50, 50, numCols, numRows]);
hImageObject    = image(mImgDisplay);
set(get(hAxes, 'Title'), 'String', 'Guided Filtered Image', 'FontSize', titleFontSize);

% Extract Line 01
vLine1 = mGuidedFilteredImage(refLine1Row, vRefLine1ColIdx);
% Extract Line 02
vLine2 = zeros([numRows, 1]);
for iRow = 1:numRows
    vLine2(iRow) = mGuidedFilteredImage(iRow, iRow);
end

hFigure = figure();
hAxes   = axes();
hLineSeries = plot([1:numCols], vLine1, [1:numRows], vLine2);
set(hLineSeries(1), 'LineWidth', normalLineWidth, 'Color', 'r');
set(hLineSeries(2), 'LineWidth', normalLineWidth, 'Color', 'g');
set(get(hAxes, 'Title'), 'String', 'Values Across Lines - Guided Filtered Image', 'FontSize', titleFontSize);
hLegend = legend({['Line #01'], ['Line #02']});
set(hLegend, 'FontSize', axisFotnSize);

%% Restore Defaults
set(0, 'DefaultFigureWindowStyle', 'normal');
set(0, 'DefaultAxesLooseInset', defaultLooseInset);


path(path, '../toolbox_graph_data/off/');

name = 'mushroom';
name = 'nefertiti';
clear options;
options.name = name;
[vertex,face] = read_off([name '.off']);

rep = ['results/mesh-duality/' name '/'];
if not(exist(rep))
    mkdir(rep);
end

clf;
plot_mesh(vertex,face,options);
shading faceted;
camlight; axis tight; axis equal;
saveas(gcf, [rep name '-mesh.png'], 'png');

clf;
A = triangulation2adjacency(face);
plot_graph(A,vertex);
view(2); axis tight; axis equal;
saveas(gcf, [rep name '-graph.png'], 'png');

[A1,vertex1] = compute_dual_graph(face,vertex);
clf;
plot_graph(A1,vertex1);
view(2); axis tight; axis equal;
saveas(gcf, [rep name '-dual.png'], 'png');

% 1:4 subdivision
options.sub_type = '1:4';
[vertex2,face2] = perform_mesh_subdivision(vertex',face',1, options);
[vertex3,face3] = perform_mesh_subdivision(vertex2,face2,1, options);

clf;
plot_mesh(vertex2,face2,options);
shading faceted;
camlight; axis tight; axis equal;
saveas(gcf, [rep name '-subdivide-4-once.png'], 'png');
clf;
plot_mesh(vertex3,face3,options);
shading faceted;
camlight; axis tight; axis equal;
saveas(gcf, [rep name '-subdivide-4-twice.png'], 'png');

% 1:3 subdivision
options.sub_type = '1:3';
[vertex2,face2] = perform_mesh_subdivision(vertex,face,1, options);
[vertex3,face3] = perform_mesh_subdivision(vertex2,face2,1, options);

clf;
plot_mesh(vertex2,face2,options);
shading faceted;
camlight; axis tight; axis equal;
saveas(gcf, [rep name '-subdivide-3-once.png'], 'png');
clf;
plot_mesh(vertex3,face3,options);
shading faceted;
camlight; axis tight; axis equal;
saveas(gcf, [rep name '-subdivide-3-twice.png'], 'png');


function r8mat_det_5d_test ( )

%*****************************************************************************80
%
%% R8MAT_DET_5D_TEST tests R8MAT_DET_5D;
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    19 April 2009
%
%  Author:
%
%    John Burkardt
%
  n = 5;

  x = [ 1.0, 10.0, 4.0, 2.0, 3.0 ];

  fprintf ( 1, '\n' );
  fprintf ( 1, 'R8MAT_DET_5D_TEST\n' );
  fprintf ( 1, '  R8MAT_DET_5D: determinant of 5 by 5 matrix.\n' );

  a = r8mat_vand2 ( n, x );
  det = r8mat_det_5d ( a );

  r8mat_print ( n, n, a, '  Matrix:' );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  R8MAT_DET_5D computes determinant: %f\n', det );
%
%  Special formula for the determinant of a Vandermonde matrix:
%
  det = 1.0;
  for i = 1 : n
    for j = 1 : i-1
      det = det * ( x(i) - x(j) );
    end
  end

  fprintf ( 1, '  Exact determinant is %f\n', det );

  return
end


%% patchConnectivity
% Below is a demonstration of the features of the |patchConnectivity| function

%% Syntax
% |[C]=patchConnectivity(F,V,conType);|

%% Description
% This functions creates connectivity matrices for the input patch data
% defined by the faces F and the vertices V. The output is a structure
% containing the connectivity matrices:
%
% C.vertex.vertex
% C.vertex.face
% C.vertex.edge
%
% C.edge.face
% C.edge.vertex
% C.edge.edge
%
% C.face.vertex
% C.face.face
% C.face.edge
%
% If the 3rd optional input conType is not provided its default value is
% 'all' and all connectivity matrices are output in the structure. If not
% all types are desired the user may request only particular types by
% setting conType. The following conTypes can be specified:
% conType (v stands for vertex, f for face, e for edge):
% 'all','vv','vf','ve','ev','ef','ee','fv','ff','fe'

%% Examples

%%
clear; close all; clc;

%%
% Plot settings
markerSize=50;

%% Example 1: Demonstrating |patchConnectivity| for different patch types

for testCase=1:3

    switch testCase
        case 1
            [F,V]=geoSphere(1,1);
        case 2
            [F,V]=quadSphere(2,1);
        case 3
            r=1; %Sphere radius
            rc=1.5; %Central radius
            nr=12;
            nc=18;
            patchType='honey';
            [F,V]=patchTorus(r,nr,rc,nc,patchType);
    end

    %%
    % Using |patchConnectivity| to compute connectivity arrays

    [C]=patchConnectivity(F,V);

    %%
    E=C.edge.vertex;
    Z=V(:,3);
    [~,indPlotVertex]=max(Z);
    [~,indPlotFace]=max(mean(Z(F),2));
    [~,indPlotEdge]=max(mean(Z(E),2));

    %%
    % Visualize vertex connectivity

    indVertexVertex=C.vertex.vertex(indPlotVertex,:);
    indVertexVertex=indVertexVertex(indVertexVertex>0);
    indVertexFace=C.vertex.face(indPlotVertex,:);
    indVertexEdge=C.vertex.edge(indPlotVertex,:);

    cFigure;
    subplot(1,3,1); hold on;
    title('Vertex-vertex connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=plotV(V(indPlotVertex,:),'g.','MarkerSize',markerSize);
    hl(2)=plotV(V(indVertexVertex,:),'r.','MarkerSize',markerSize);

    legend(hl,{'Example point','Connected points'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    subplot(1,3,2); hold on;
    title('Vertex-face connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=plotV(V(indPlotVertex,:),'g.','MarkerSize',markerSize);
    hl(2)=gpatch(F(indVertexFace,:),V,'r','r',1);

    legend(hl,{'Example point','Connected faces'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    subplot(1,3,3); hold on;
    title('Vertex-edge connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=plotV(V(indPlotVertex,:),'g.','MarkerSize',markerSize);
    hl(2)=gpatch(E(indVertexEdge,:),V,'none','r',1);
    hl(2).LineWidth=3;
    legend(hl,{'Example point','Connected Edges'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    drawnow;

    %%
    % Visualize face connectivity

    indFaceVertex=C.face.vertex(indPlotFace,:);
    indFaceVertex=indFaceVertex(indFaceVertex>0);
    indFaceFace=C.face.face(indPlotFace,:);
    indFaceFace=indFaceFace(indFaceFace>0);
    indFaceEdge=C.face.edge(indPlotFace,:);

    cFigure;
    subplot(1,3,1); hold on;
    title('Face-vertex connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=gpatch(F(indPlotFace,:),V,'g','g',1);
    hl(2)=plotV(V(indFaceVertex,:),'r.','MarkerSize',markerSize);

    legend(hl,{'Example face','Connected points'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    subplot(1,3,2); hold on;
    title('Face-face connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=gpatch(F(indPlotFace,:),V,'g','g',1);
    hl(2)=gpatch(F(indFaceFace,:),V,'r','r',1);

    legend(hl,{'Example face','Connected faces'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    subplot(1,3,3); hold on;
    title('Face-edge connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=gpatch(F(indPlotFace,:),V,'g','g',1);
    hl(2)=gpatch(E(indFaceEdge,:),V,'none','r',1);
    hl(2).LineWidth=3;
    legend(hl,{'Example face','Connected Edges'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    drawnow;

    %%
    % Visualize edge connectivity

    indEdgeVertex=C.edge.vertex(indPlotEdge,:);
    indEdgeVertex=indEdgeVertex(indEdgeVertex>0);
    indEdgeFace=C.edge.face(indPlotEdge,:);
    indEdgeFace=indEdgeFace(indEdgeFace>0);
    indEdgeEdge=C.edge.edge(indPlotEdge,:);
    indEdgeEdge=indEdgeEdge(indEdgeEdge>0);

    cFigure;
    subplot(1,3,1); hold on;
    title('Edge-vertex connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=gpatch(E(indPlotEdge,:),V,'g','g',1); hl(1).LineWidth=3;
    hl(2)=plotV(V(indEdgeVertex,:),'r.','MarkerSize',markerSize);

    legend(hl,{'Example edge','Connected points'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    subplot(1,3,2); hold on;
    title('Edge-face connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=gpatch(E(indPlotEdge,:),V,'g','g',1); hl(1).LineWidth=3;
    hl(2)=gpatch(F(indEdgeFace,:),V,'r','r',1);

    legend(hl,{'Example edge','Connected faces'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    subplot(1,3,3); hold on;
    title('Edge-edge connectivity');
    gpatch(F,V,'kw','k',0.5)

    hl(1)=gpatch(E(indPlotEdge,:),V,'g','g',1); hl(1).LineWidth=3;
    hl(2)=gpatch(E(indEdgeEdge,:),V,'none','r',1); hl(2).LineWidth=3;
    legend(hl,{'Example edge','Connected Edges'},'Location','SouthOutside');

    axisGeom;
    view(2);
    camlight headlight;
    axis off;
    clear hl;

    drawnow;

end

%% Example 2: Using the conTypes input to control output request

%%
% Request only the edge-edge connectivity
C=patchConnectivity(F,V,'ee')

%%
% Request both the edge-edge connectivity and the face-face connectivity
C=patchConnectivity(F,V,{'ee','ff'})

%%
% Loop over all types and compare computation speed

conTypeSet={'all','vv','vf','ve','ev','ef','ee','fv','ff','fe'};
for q=1:1:numel(conTypeSet)
    tic
    C=patchConnectivity(F,V,conTypeSet{q});
    t=toc;
    disp([conTypeSet{q},': ',num2str(t),' seconds'])
end

%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>

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


 function [hash_table, hash_coarse] = at_dense_hashtable(cnnfeat1,cnnfeat1fine)

x_coarse_size = size(cnnfeat1,1);
y_coarse_size = size(cnnfeat1,2);

x_fine_size = size(cnnfeat1fine,1);
y_fine_size = size(cnnfeat1fine,2);

% scale = x_fine_size/x_coarse_size;
% if scale ~= whos
%   error('aspect ratio should be preserved');
% end

% x_coarse_size = 5;
% y_coarse_size = 4;
% scale = 2;
% x_fine_size = x_coarse_size * scale;
% y_fine_size = y_coarse_size * scale;

% [x_coarse,y_coarse] = meshgrid(1:x_coarse_size,1:y_coarse_size);
hash_coarse = reshape(1:(x_coarse_size*y_coarse_size),x_coarse_size,y_coarse_size);

hash_fine = imresize(hash_coarse,[x_fine_size y_fine_size],'nearest');
[x_fine,y_fine] = meshgrid(1:y_fine_size,1:x_fine_size);

Nhash = max(hash_coarse(:));

hash_table = cell(1,Nhash);
hash_fine = hash_fine(:);
x_fine = x_fine(:);
y_fine = y_fine(:);
for ii=1:Nhash
  a = find(hash_fine == ii);
  hash_table{ii} = [x_fine(a)'; y_fine(a)'];
end


function M = getmassmatvec(elem2edge,area,Dlambda,elemType,K)
%% GETMASSMATVEC Get the mass matrix of vector finite element space
%
% M = GETMASSMATVEC(elem2edge,area,Dlambda,elemType,K) get mass matrix of the finite element
% space specified by elemType.
%
% The elemType can be:
%
% - "RT0": The lowest order Raviart-Thomas element
% - "BDM1": The lowest order Brezzi-Douglas-Michel element
% - "BDM1B": The BDM element enriched by the curl of cubic bubble function
% - "ND1': The lowest order Nedelec element
%
% Note that RT0 and ND1 share the same mass matrix.
%
% Created by Ming Wang at July, 2012. Improved by Long Chen.

if ~exist('K','var'), K = []; end
NE = double(max(elem2edge(:)));
NT = size(elem2edge,1);
DiDj = zeros(NT,3,3);
for i = 1:3
    for j = i:3
        DiDj(:,i,j) = dot(Dlambda(:,:,i),Dlambda(:,:,j),2);
        DiDj(:,j,i) = DiDj(:,i,j);
    end
end

localEdge = [2 3; 1 3; 1 2];
%% RT0
if strcmp(elemType,'RT0') || strcmp(elemType,'ND1')
    M = sparse(NE,NE);
    for i = 1:3
        for j = i:3
            % local to global index map and its sign
            ii = double(elem2edge(:,i));
            jj = double(elem2edge(:,j));
            i1 = localEdge(i,1); i2 = localEdge(i,2); % [i1,i2] is the edge opposite to vertex i.
            j1 = localEdge(j,1); j2 = localEdge(j,2);
            % computation of mass matrix --- (phi_i, phi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             - (1+(i1==j2))*DiDj(:,i2,j1) ...
                             - (1+(i2==j1))*DiDj(:,i1,j2) ...
                             + (1+(i2==j2))*DiDj(:,i1,j1));
            if ~isempty(K)
                Mij = Mij./K;
            end
            if (j==i)
                M = M + sparse(ii,jj,Mij,NE,NE);
            else
                M = M + sparse([ii;jj],[jj;ii],[Mij; Mij],NE,NE);
            end
        end
    end
end
%% BDM1
if strcmp(elemType,'BDM1') || strcmp(elemType,'BDM1B')
    M = sparse(2*NE,2*NE);
    for i = 1:3
        for j = i:3
            % local to global index map and its sign
            ii = double(elem2edge(:,i));
            jj = double(elem2edge(:,j));
            i1 = localEdge(i,1); i2 = localEdge(i,2); % [i1,i2] is the edge opposite to vertex i.
            j1 = localEdge(j,1); j2 = localEdge(j,2);
            % computation of mass matrix, note that (rot u, rot v) = (grad u, grad v)
            % (phi_i, phi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             - (1+(i1==j2))*DiDj(:,i2,j1) ...
                             - (1+(i2==j1))*DiDj(:,i1,j2) ...
                             + (1+(i2==j2))*DiDj(:,i1,j1));
            if ~isempty(K)
                Mij = Mij./K;
            end
            if (j==i)
                M = M + sparse(ii,jj,Mij,2*NE,2*NE);
            else
                M = M + sparse([ii;jj],[jj;ii],[Mij; Mij],2*NE,2*NE);
            end
            % (psi_i,psi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             + (1+(i1==j2))*DiDj(:,i2,j1) ...
                             + (1+(i2==j1))*DiDj(:,i1,j2) ...
                             + (1+(i2==j2))*DiDj(:,i1,j1));
            if ~isempty(K)
                Mij = Mij./K;
            end
            if (j==i)
                M = M + sparse(ii+NE,jj+NE,Mij,2*NE,2*NE);
            else
                M = M + sparse([ii;jj]+NE,[jj;ii]+NE,[Mij; Mij],2*NE,2*NE);
            end
        end
    end
    for i = 1:3
        for j = 1:3
            % local to global index map and its sign
            ii = double(elem2edge(:,i));
            jj = double(elem2edge(:,j));
            i1 = localEdge(i,1); i2 = localEdge(i,2);
            j1 = localEdge(j,1); j2 = localEdge(j,2);
            % (psi_i,phi_j)
            Mij = 1/12*area.*( (1+(i1==j1))*DiDj(:,i2,j2) ...
                             - (1+(i1==j2))*DiDj(:,i2,j1) ...
                             + (1+(i2==j1))*DiDj(:,i1,j2) ...
                             - (1+(i2==j2))*DiDj(:,i1,j1));
            if ~isempty(K)
                Mij = Mij./K;
            end
            M = M + sparse([ii+NE;jj],[jj;ii+NE],[Mij; Mij],2*NE,2*NE);
        end
    end
end
%% BDM1B
if strcmp(elemType,'BDM1B')
    newM = sparse(2*NE+NT,2*NE+NT);
    newM(1:2*NE,1:2*NE) = M;
    M = newM;
    % (phi_i, bubble)
    for i = 1:3
        ii = double(elem2edge(:,i));
        jj = double((1:NT)');
        i1 = localEdge(i,1); i2 = localEdge(i,2); i3 = 6-i1-i2;
        Mij = 9/10*area.*(...
             dot(Dlambda(:,:,i2),Dlambda(:,:,i3),2)...
            +dot(Dlambda(:,:,i2),Dlambda(:,:,i2),2)...
            -dot(Dlambda(:,:,i1),Dlambda(:,:,i3),2)...
            -dot(Dlambda(:,:,i1),Dlambda(:,:,i1),2));
        if ~isempty(K)
            Mij = Mij./K;
        end
        M = M + sparse([ii;jj+2*NE],[jj+2*NE;ii],[Mij;Mij],2*NE+NT,2*NE+NT);
    end
    clear ii jj i1 i2 i3 Mij;
    % (psi_i, bubble)
    for i = 1:3
        ii = double(elem2edge(:,i));
        jj = double((1:NT)');
        i1 = localEdge(i,1); i2 = localEdge(i,2); i3 = 6-i1-i2;
        Mij = 9/10*area.*(...
             dot(Dlambda(:,:,i2),Dlambda(:,:,i3),2)...
            +dot(Dlambda(:,:,i1),Dlambda(:,:,i3),2)...
            +dot(Dlambda(:,:,i2),Dlambda(:,:,i2),2)...
            +dot(Dlambda(:,:,i1),Dlambda(:,:,i1),2)...
            +dot(Dlambda(:,:,i1),Dlambda(:,:,i2),2));
        if ~isempty(K)
            Mij = Mij./K;
        end
        M = M + sparse([ii+NE;jj+2*NE],[jj+2*NE;ii+NE],[Mij;Mij],2*NE+NT,2*NE+NT);
    end
    clear ii jj i1 i2 i3 Mij;
    % (bubble, bubble)
    ii = 1+2*NE:NT+2*NE;
    Mij = 81/10*area.*(...
          dot(Dlambda(:,:,1),Dlambda(:,:,1),2)...
         +dot(Dlambda(:,:,1),Dlambda(:,:,2),2)...
         +dot(Dlambda(:,:,1),Dlambda(:,:,3),2)...
         +dot(Dlambda(:,:,2),Dlambda(:,:,2),2)...
         +dot(Dlambda(:,:,2),Dlambda(:,:,3),2)...
         +dot(Dlambda(:,:,3),Dlambda(:,:,3),2));
    if ~isempty(K)
        Mij = Mij./K;
    end
    M = M + sparse(ii,ii,Mij,2*NE+NT,2*NE+NT);
end


function layer = genNetworkFeedForward_obj_auto(inputDim, hiddenLayerSize, outputDim, costFn, LastActivation4MSE)
if nargin<5
    LastActivation4MSE = 'linear';
end
inputDim = double(inputDim);

inputStreamIdx = 1;
layer{1} = InputNode(inputStreamIdx,inputDim);

for i=1:length(hiddenLayerSize)
    layer{end+1} = AffineNode(hiddenLayerSize(i));
    layer{end+1} = SigmoidNode(hiddenLayerSize(i));
end
layer{end+1} = AffineNode(outputDim);

if strcmpi(costFn, 'CrossEntropy')
    layer{end+1} = SoftmaxNode(outputDim);
else    % there are a few options for MSE cost function
    switch LastActivation4MSE
        case 'linear'
            % do nothing
        case 'tanh'
            layer{end+1} = TanhNode(outputDim);
        case 'sigmoid'
            layer{end+1} = SigmoidNode(outputDim);
        case 'relu'
            layer{end+1} = ReluNode(outputDim);
        otherwise
            fprintf('Error: unknown activation for last hidden layer, skipped!\n');
    end
end
layer = ConnectNodesLinear(layer);

inputStreamIdx = inputStreamIdx +1;
if strcmpi(costFn, 'CrossEntropy')
    layer{end+1} = InputNode(inputStreamIdx, 1);
    layer{end+1} = CrossEntropyNode();
else
    layer{end+1} = InputNode(inputStreamIdx, outputDim);
    layer{end+1} = MeanSquareErrorNode(1);
end
layer{end}.prev = [-2 -1];
layer{end}.dim = [1 outputDim];
layer = FinishLayer_obj(layer);
end


%RELMTEST
%script to test two earthqauake rate hypotheses using earthquake data
%
region='Northern California Aftershock model';
nsim=100;
mt=2;
 park1=vRatesH;
 park2=vRatesN;
%load H1;
%load H2;
%park1=H1; %Hypothesis with variable b-values
%park2=H2; %Null hypothesis, uniform b-value
clear test null;
%     xmin(i)=park1(j,1);
%     xmax(i)=park1(j,2);
%     ymin(i)=park1(j,3);
%     ymax(i)=park1(j,4);
%     zmin(i)=park1(j,5);
%     zmax(i)=park1(j,6);
%     magmin(i)=park1(j,7);
%     magmax(i)=park1(j,8);
%     lamda1(i)=park1(j,9);
%     weight(i)=park1(j,10);
nquake=park1(:,11);
[m,n] = size(park1);
magmin=park1(:,7);
lamda1=park1(:,9);
lamda2=park2(:,9);
weight1=park1(:,10);
weight2=park2(:,10);
weight=weight1.*weight2.*(magmin>mt);
%
% Remove rows of matrix for which weight is zero
%
j=0;
for i = 1:m
    if weight(i)>0
        j=j+1;
        w(j)=weight(i);
        nq(j)=nquake(i);
        lam1(j)=lamda1(i);
        lam2(j)=lamda2(i);
        mmin(j)=magmin(i);
    end
end
nq=w.*nq;
Nquake=sum(nq);
lam1=w.*lam1;
lam2=w.*lam2;
clear park1 park2 lamda1 lamda2 nquake magmin weight weight1 weight2;
%
%make a weighted magnitude-frequency plot
%
mf=[mmin;nq;lam1;lam2]';
mfsort=sortrows(mf);
mag=mfsort(:,1);

Fobs=flip(cumsum(flip(mfsort(:,2))));
Fth1=flip(cumsum(flip(mfsort(:,3))));
Fth2=flip(cumsum(flip(mfsort(:,4))));
figure%(1)
semilogy(mag,Fobs,'r',mag,Fth1,'g',mag,Fth2,'b');
grid;
axis([3,8,.0001,100]);

%
%    Evaluate whether total number of quakes is consistent with H1
%
%
Nhat=sum(lam1)
peq=poisspdf(Nquake, Nhat); % probability of exactly Nquake
Ple=poisscdf(Nquake, Nhat); % probability of less than or equal to Nquake
Pless=Ple-peq;              % probability of less than Nquake
Pmore=1-Ple                 % probability of more than Nquake
P1_equal=peq;
P1_less=Pless;
P1_more=Pmore;
Nhat1=Nhat;
lamcum1=cumsum(lam1)/Nhat1;

%   Evaluate whether total number of quakes is consistent with H2

Nhat=sum(lam2)
peq=poisspdf(Nquake, Nhat); % probability of exactly Nquake
Ple=poisscdf(Nquake, Nhat); % probability of less than or equal to Nquake
Pless=Ple-peq;              % probability of less than Nquake
Pmore=1-Ple                 % probability of more than Nquake
P2_equal=peq;
P2_less=Pless;
P2_more=Pmore;
Nhat2=Nhat;
lamcum2=cumsum(lam2)/Nhat2;
%
%   simulate catalogs according to H1,
%   and evaluate likelihood scores of nsquake1 and real catalog using lamda1 and lamda2
%
nsquake=simulate(Nquake,lam1, nsim);
[LLR1, rank11,rank12] = Rtest(lam1, lam2, nq, nsquake, w);
%
%   simulate catalogs according to H2,
%   and evaluate likelihood scores of nsquake1 and real catalog using lamda1 and lamda2
%
nsquake=simulate(Nquake,lam2, nsim);
[LLR2, rank21,rank22] = Rtest(lam1, lam2, nq, nsquake, w);
%
%Plot cumulative likelihood scores for two hypotheses
%
alpha = sum(LLR2>0)/nsim
beta = sum(LLR1<0)/nsim
index=[1:nsim]/nsim;
x=[0,0];y=[0,1];
figure_w_normalized_uicontrolunits(2);
plot(LLR1,index,'g',LLR2,index,'r',x,y,'b')';
xlabel('Likelihood ratio (Variable b/Constant b)')';
ylabel('Fraction of cases');
title('Green assumes variable-b hypothesis; Red assumes constant=b hypothesis');

region, mt,Nquake, Nhat1,Nhat2,P1_less,P1_more,P2_less,P2_more, alpha, beta, rank11,rank12, rank21, rank22
%[rank1,rank2]
%[Nhat1,Nhat2]
%[P1_less, P2_less]
%[P1_more, P2_more]


% RES = histoMatch(MTX, N, X)
%
% Modify elements of MTX so that normalized histogram matches that
% specified by vectors X and N, where N contains the histogram counts
% and X the histogram bin positions (see histo).

% Eero Simoncelli, 7/96.

function res = histoMatch(mtx, N, X)

if ( exist('histo') == 3 )
  [oN, oX] = histo(mtx(:), size(X(:),1));
else
  [oN, oX] = hist(mtx(:), size(X(:),1));
end

oStep = oX(2) - oX(1);
oC = [0, cumsum(oN)]/sum(oN);
oX = [oX(1)-oStep/2, oX+oStep/2];

N = N(:)';
X = X(:)';
N = N + mean(N)/(1e8);   %% HACK: no empty bins ensures nC strictly monotonic

nStep = X(2) - X(1);
nC = [0, cumsum(N)]/sum(N);
nX = [X(1)-nStep/2, X+nStep/2];

nnX = interp1(nC, nX, oC, 'linear');

if ( exist('pointOp') == 3 )
  res = pointOp(mtx, nnX, oX(1), oStep);
else
  res = reshape(interp1(oX, nnX, mtx(:)),size(mtx,1),size(mtx,2));
end


function [oa, pa, K, CM] = USFE_PCA(HSI, Tr, Te, dim, Trees)
[nx,ny,nz]=size(HSI);
data=reshape(HSI,nx*ny,nz);
clear HSI
%% matlab PCA from the stats toolbox (C:\Program Files\MATLAB\R2018b\toolbox\stats\stats\pca.m)
[code] = pca(data');
FE_Mpca=reshape(code(:,1:dim),nx,ny,dim);
[acc_Mean,acc_std,CM]=RF_ntimes_overal(FE_Mpca,Tr,Te,Trees);
pa=acc_Mean(1:dim,1);
oa=acc_Mean(dim+2,1);
K=acc_Mean(dim+3,1);


function CM = Tpm_CM(P,X)
% TPM_CM  Chenoweth-Martin two-phase multiplier
% TPM_CM(P,X) Returns the Chenoweth-Martin two-phase
% multipier for a steam-water system
%  Called function: h2o_rhof(P), h2o_rhog(P)
%  Required Inputs are: P - pressure (kPa), X - quality (fraction)
% ---------------------------------------------------------------
% The MATLAB function was created by Tibor Balint, December 1998
% TBoreal Research Corporation, Toronto, Ont. Canada
% (tibor@netcom.ca) and also, University of Warwick, UK
% ---------------------------------------------------------------

format long g;  % set the format of the calculations

if X<=0
   CM=1;
else
   RF=h2o_rhof(P);
   RG=h2o_rhog(P);
% Liquid Volume Fraction
   LVF=1-(X*RF/(X*RF+(1-X)*RG));
%The two-phase multiplier is
   CM=LVF^(-0.8642);
end

return


function accuracy = rpca_src(TrainSet, TestSet, train_num, test_num, class_num, lambda, options)
% Robust PCA-based sparse representation classification (RobustPCA-SRC) algorithm
%
% Inputs:
%       TrainSet            train sets of size dxn, where d is dimension and n is number of sets
%       train_num           numner of train sets
%       class_num           numner of classes
%       lambda              regularization paramter
% Output:
%       accuracy            classification accurary
%
%
% Created by H.Kasai on July 07, 2017

    % extract options
    if ~isfield(options, 'verbose')
        verbose = false;
    else
        verbose = options.verbose;
    end

    if ~isfield(options, 'eigenface')
        eigenface = true;
    else
        eigenface = options.eigenface;
    end

    if ~isfield(options, 'eigenface_dim')
        eigenface_dim = train_num;
    else
        eigenface_dim = options.eigenface_dim;
    end

    if ~isfield(options, 'solver_max_iter')
        solver_max_iter = 100;
    else
        solver_max_iter = options.solver_max_iter;
    end

    % define problem definitions
    solver_lambda = 1/sqrt(max(size(TrainSet.X)));
    solver_lambda = solver_lambda/3;
    mask = logical(zeros(size(TrainSet.X)));
    problem = robust_pca(TrainSet.X, mask, solver_lambda);
    problem = robust_pca(TrainSet.X, mask, solver_lambda);

    % perform robust PCA
    solver_options.max_iter = solver_max_iter;
    solver_options.verbose = verbose;
    solver_options.mu = 10*solver_lambda/3;
    [w, ~] = admm_robust_pca(problem, solver_options);
    TrainSet.X = w.L;

    problem = robust_pca(TestSet.X, mask, solver_lambda);
    [w, ~] = admm_robust_pca(problem, solver_options);
    TestSet.X = w.L;

    % generate eigenface
    if eigenface
        [disc_set, ~, ~] = Eigenface_f(TrainSet.X, eigenface_dim);

        % project on subspace
        TrainSet.X  =  disc_set' * TrainSet.X;
        TestSet.X   =  disc_set' * TestSet.X;
    end

    % normalize data to l2-norm
    [TrainSet.X, ~] = data_normalization(TrainSet.X, TrainSet.y, 'std');
    [TestSet.X, ~] = data_normalization(TestSet.X, TestSet.y, 'std');

    % perform a standard SRC
    if 1
        % use src function
        options.eigenface = false;
        accuracy = src(TrainSet, TestSet, train_num, test_num, class_num, lambda, options);
    else

        % prepare class array
        classes = unique(TrainSet.y);

        % prepare predicted label array
        identity = zeros(1, test_num);

        for i = 1 : test_num

            y = TestSet.X(:, i);

            % calculate sparse code
            xp = l1_ls(TrainSet.X, y, lambda, 1e-3, 1);

            % prepare residual array
            residuals = zeros(1, class_num);

            % calculate residual for each class
            for j = 1 : class_num
                idx = find(TrainSet.y == classes(j));
                residuals(j) = norm(y-TrainSet.X(:,idx)*xp(idx))/sum(xp(idx).*xp(idx));
                %residuals(j) = norm(y - TrainSet.X(:,idx)*xp(idx));
            end

            % calculate the predicted label with minimum residual
            [dis, label] = min(residuals);
            identity(i) = label;

            if verbose
                correct = (label == TestSet.y(1, i));
                fprintf('# RobustPCA-SRC: test:%03d, predict class: %03d --> ground truth :%03d (%d)\n', i, label, TestSet.y(1, i), correct);
            end

        end

        % calculate accuracy
        correct_num = sum(identity == TestSet.y);
        accuracy = correct_num/test_num;
    end
end


function accuracy = src(TrainSet, TestSet, train_num, test_num, class_num, lambda, options)
% Sparse representation classification (SRC) algorithm
%
% Inputs:
%       TrainSet            train sets of size dxn, where d is dimension and n is number of sets
%       TestSet             test sets of size dxn, where d is dimension and n is number of sets
%       test_num            numner of test sets
%       class_num           numner of classes
%       lambda              regularization paramter
% Output:
%       accuracy            classification accurary
%
% References:
%       J. Wright, A. Yang, A. Ganesh, S. Sastry, and Y. Ma,
%       "Robust face recognition via sparse representation,"
%       IEEE Transaction on Pattern Analysis and Machine Intelligence, vol.31, no.2, pp.210-227, 2009.
%
%
% Created by H.Kasai on July 06, 2017

    % extract options
    if ~isfield(options, 'verbose')
        verbose = false;
    else
        verbose = options.verbose;
    end

    if ~isfield(options, 'eigenface')
        eigenface = true;
    else
        eigenface = options.eigenface;
    end

    if ~isfield(options, 'eigenface_dim')
        eigenface_dim = train_num;
    else
        eigenface_dim = options.eigenface_dim;
    end

    % generate eigenface
    if eigenface
        [disc_set, ~, ~] = Eigenface_f(TrainSet.X, eigenface_dim);

        % project on subspace
        TrainSet.X  =  disc_set' * TrainSet.X;
        TestSet.X   =  disc_set' * TestSet.X;
    end

    % normalize data to l2-norm
    [TrainSet.X, ~] = data_normalization(TrainSet.X, TrainSet.y, 'std');
    [TestSet.X, ~] = data_normalization(TestSet.X, TestSet.y, 'std');

    % prepare class array
    classes = unique(TrainSet.y);

    % prepare predicted label array
    identity = zeros(1, test_num);

    for i = 1 : test_num

        y = TestSet.X(:, i);

        if 0
            % calculate sparse code
            %tau = max(1e-4*max(abs(TrainSet.X'*y)),sigma*sqrt(log(train_num)));
            tau = lambda;

            in = [];
            in.tau = tau;
            delx_mode = 'mil'; % mil or qr
            in.delx_mode = delx_mode;
            in.debias = 0;
            in.verbose = 0;
            in.plots = 0;

            out = l1homotopy(TrainSet.X, y, in);
            xp = out.x_out;
        elseif 1

            P = inv(TrainSet.X'*TrainSet.X+0.001*eye(size(TrainSet.X,2)))*TrainSet.X';
            x0 = P*y;

            maxIteration = 5000;
            isNonnegative = false;
            lambda = 1e-2; %5e-3;
            tolerance = 0.05;
            STOPPING_GROUND_TRUTH = -1;
            STOPPING_DUALITY_GAP = 1;
            STOPPING_SPARSE_SUPPORT = 2;
            STOPPING_OBJECTIVE_VALUE = 3;
            STOPPING_SUBGRADIENT = 4;
            stoppingCriterion = STOPPING_GROUND_TRUTH;
            [xp, iterationCount] = SolveHomotopy(TrainSet.X, y, ...
                            'maxIteration', maxIteration,...
                            'isNonnegative', isNonnegative, ...
                            'stoppingCriterion', stoppingCriterion, ...
                            'groundtruth', x0, ...
                            'lambda', lambda, ...
                            'tolerance', tolerance);

        elseif 0
            xp = l1_ls(TrainSet.X, y, 1e-3);
        else

            param.lambda = lambda;
            param.lambda2 =  0;
            param.mode = 0;
            xp = full(mexLasso(y, TrainSet.X, param));
        end

        % prepare residual array
        residuals = zeros(1, class_num);

        % calculate residual for each class
        for j = 1 : class_num
            idx = find(TrainSet.y == classes(j));
            %residuals(j) = norm(y-TrainSet.X(:,idx)*xp(idx))/sum(xp(idx).*xp(idx));
            residuals(j) = norm(y - TrainSet.X(:,idx)*xp(idx));
        end

        % calculate the predicted label with minimum residual
        [~, label] = min(residuals);
        identity(i) = label;

        if verbose
            correct = (label == TestSet.y(1, i));
            fprintf('# SRC: test:%04d, predict class: %03d --> ground truth :%03d (%d)\n', i, label, TestSet.y(1, i), correct);
        end

        %identity(i) = src_based_classifier(xp, TrainSet.X, TrainSet.y, TestSet.X(:, i), TestSet.y(1, i), classes, i, class_num, 'SRC', verbose);

    end

    % calculate accuracy
    correct_num = sum(identity == TestSet.y);
    accuracy = correct_num/test_num;
end


% Description:
%
%     Remove one term at a time from a MANCOVAN model until all p-values are
%     below the specified threshold.
%
% Syntax:
%
%     [ T, p, stats ] = mStepwise(Y, groups, [], threshold)
%     [ T, p, stats ] = mStepwise(Y, [], covariates, threshold)
%     [ T, p, stats ] = mStepwise(Y, groups, covariates, threshold)
%     [ T, p, stats ] = mStepwise(Y, groups, covariates, threshold, options)
%
%     [ T, p, stats ] = mStepwise(Y, X, terms, threshold, options)
%
% Inputs:
%
%     Y          - [ N x M ] (double) - multivariate response
%     groups     - [ N x G ] (int)    - qualitative variables
%     covariates - [ N x C ] (double) - quantitative variables
%     threshold  - [ 1 x 1 ] (double) - p-value at which to stop dropping terms
%     options    - [ 1 x P ] (cell)   - see Options
%
%     X     - [ N x T ] (double) - design matrix
%     terms - [ 1 x T ] (cell)   - model terms
%
% Outputs:
%
%     T - [ (G + C) x 1 ] (double)
%     p - [ (G + C) x 1 ] (double)
%
%     stats.U - [ N x N ] (double) - U resulting from the SVD (option 'SVD').
%     stats.S - [ N x N ] (double) - S resulting from the SVD (option 'SVD').
%     stats.V - [ M x N ] (double) - V resulting from the SVD (option 'SVD').
%
%     stats.BIC - [ 1 x P ] (double) - values of the Bayesian information
%         criterion (BIC) associated with the SVD (option 'SVD').
%
%     stats.PVE - [ N x 1 ] (double) - the percentage of variance in Y explained
%         by each consecutive column of U (option 'SVD').
%
%     stats.Terms - [ 1 x B ] (cell) - full model terms numbering groups from
%         one through size(groups, 2) and covariates from size(groups, 2) + 1
%         through size(groups, 2) + size(covariates, 2) + 1, and interactions
%         according to combinations of these numbers.
%
%     stats.X - [ N x B ] (double) - full model design matrix, including columns
%         for the grand mean, groups, covariates, and interactions.
%
%     stats.Y - [ N x M ] (double) - the multivariate response used for the
%         computation.
%
%     stats.B - [ B x P ] (double) - regression coefficients associated with the
%         full model after stepwise removal of insignificant terms.
%
%     stats.SSE - [ P x P ] (int) - full model sum of squared errors associated
%         with each column of Y.
%
%     stats.DFE - [ 1 x M ] (int) - degrees of freedom used in the computation
%         of stats.MSE.
%
%     stats.MSE - [ P x P ] (int) - full model mean squared errors associated
%         with each column of Y.
%
% Details:
%
% Options:
%
%     'group-group'         - include group-group interactions
%     'covariate-covariate' - include covariate-covariate interactions
%     'group-covariate'     - include group-covariate interactions
%     'over-determined'     - use over-determined coding for the design matrix
%     'sigma-restricted'    - use sigma-restricted coding for the design matrix
%     'SVD'                 - reduce the dimensionality of Y using an SVD
%     'verbose'             - display extra information to the command window
%
% Examples:
%
%     The following example uses a simple additive model with covariates, but no
%     interactions and avoids using the Statistics Toolbox:
%
%         n          = 100;
%         groups     = round(2 * rand(n, 2) + 0.5);
%         covariates = 10 * randn(n, 2);
%         Y          = groups + covariates + randn(n, 2);
%
%         [ T, p, stats ] = mStepwise(Y, groups, covariates, 0.10, ...
%             { 'group-group' 'covariate-covariate' 'group-covariate' 'verbose' });
%
%     For other examples, refer to mancovan.m.  The setup and syntax is exactly
%     the same in every case except for the addition of a threshold.
%
% Notes:
%
% Author(s):
%
%     William Gruner (williamgruner@gmail.com)
%
% References:
%
%     Refer to the references listed in mancovan.m.
%
% Acknowledgements:
%
%     Many thanks to Dr. Erik Erhardt and Dr. Elena Allen of the Mind Research
%     Network (www.mrn.org) for their continued collaboration.
%
% Version:
%
%     $Author: williamgruner $
%     $Date: 2010-04-15 07:46:14 -0600 (Thu, 15 Apr 2010) $
%     $Revision: 496 $

function [ T, p, stats ] = mStepwise(Y, groups, covariates, threshold, options)

    if nargin == 0
        T = BIT(); return
    end

    if ~exist('options', 'var')
        options = cell(0);
    end

    if iscell(covariates)
        X     = groups;
        terms = covariates;
    else
        [ X, terms ] = mX(groups, covariates, options);
    end

    if ~isempty(strmatch('SVD', options, 'exact'))

        [ BIC, U, S, V ] = mSVD(Y, options);

        stats.U   = U;
        stats.S   = S;
        stats.V   = V;
        stats.BIC = BIC;
        stats.PVE = cumsum(diag(S) ./ sum(diag(S)));

        b = find(diff(BIC) > 0);
        b = b(1);

        U = U(  :, 1:b);
        S = S(1:b, 1:b);
        V = V(  :, 1:b);

    else

        U = Y;

    end

    if ~isempty(strmatch('verbose', options, 'exact'))
        fprintf('\n')
    end

    while length(terms) > 1

        if ~isempty(strmatch('over-determined', options, 'exact'))
            M = X * pinv(X' * X) * X';
        else
            M = X * inv(X' * X) * X';
        end

        B = mUnique(terms(2:end));
        T = repmat(NaN, length(B), 1);
        p = repmat(NaN, length(B), 1);

        for i = 1 : length(B)

            I0 = mTerms(B{i}, terms);
            X0 = X(:, I0);

            if ~isempty(strmatch('over-determined', options, 'exact'))
                M0 = X0 * pinv(X0' * X0) * X0';
            else
                M0 = X0 * inv(X0' * X0) * X0';
            end

            if ~isempty(strmatch('verbose', options, 'exact'))
                mDispModels([ {0} B ], mUnique(terms(I0)))
            end

            [ T(i), p(i) ] = mLHT(U, X, X0, M, M0, options);

            if ~isempty(strmatch('verbose', options, 'exact'))
                fprintf('\n')
            end

        end

        if max(p) < threshold
            break
        end

        [ q, I ] = sort(p, 'descend');

        for i = 1 : length(I)
            if mIsInteractionTerm(B{I(i)})
                break
            elseif mIsMainTerm(B{I(i)})
                if ~ismember(B{I(i)}, cat(2, B{mFindInteractionTerms(B)}))
                    break
                end
            end
        end

        if q(i) < threshold

            break

        else

            if ~isempty(strmatch('verbose', options, 'exact'))

                if mIsInteractionTerm(B{I(i)})
                    fprintf('Removing %d%d ...\n', B{I(i)}(1), B{I(i)}(2))
                elseif mIsMainTerm(B{I(i)})
                    fprintf('Removing %d ...\n', B{I(i)})
                end

                fprintf('\n')

            end

            X    (:, mFindTerms(B{I(i)}, terms)) = [];
            terms(:, mFindTerms(B{I(i)}, terms)) = [];

        end

    end

    if ~isempty(strmatch('over-determined', options, 'exact'))
        stats.B = pinv(X' * X) * X' * U;
    else
        stats.B = inv(X' * X) * X' * U;
    end

    stats.Terms     = terms;
    stats.X         = X;
    stats.Y         = Y;
    stats.SSE       = U' * (eye(size(M)) - M) * U;
    stats.DFE       = size(X, 1) - rank(X);
    stats.MSE       = stats.SSE / stats.DFE;
    stats.Residuals = U - stats.X * stats.B;

function b = BIT()

    b = true;

    % Compare the results to those obtained from the previous version.

    s = load('mStepwise-BIT-1.mat');

    [ T, p, stats ] = mStepwise(s.Y, s.groups, s.covariates, 0.10, ...
        { 'sigma-restricted' 'group-group' 'covariate-covariate' 'group-covariate' 'verbose' });

    e = s.T - T;

    if any(abs(e(:)) > sqrt(eps))
        b = false;
    end

    e = s.p - p;

    if any(abs(e(:)) > sqrt(eps))
        b = false;
    end

    % Compare the results to those obtained from the previous version.

    s = load('mStepwise-BIT-2.mat');

    [ T, p, stats ] = mStepwise(s.Y, s.groups, s.covariates, 0.01, ...
        { 'sigma-restricted' 'group-group' 'covariate-covariate' 'group-covariate' 'verbose' });

    e = s.T - T;

    if any(abs(e(:)) > sqrt(eps))
        b = false;
    end

    e = s.p - p;

    if any(abs(e(:)) > sqrt(eps))
        b = false;
    end


clc;
clearvars;
rng default;
A = magic(6);

[n1, n2] = size(A);

sz = n1 * n2;

factors = [0.05 0.1 0.2 0.3];
A
for f=factors
    m = round(f * sz);
    fprintf('Trying for factor=%f, m=%d\n', f, m);
    Omega = spx.stats.rand_subset(sz, m);
    [U, S, V] = svd(A);
    y = spx.fast.partial_svd_compose(U, diag(S), V, Omega);
    spx.io.print.vector(y);
    A2 = spx.sparse.join_data_indices(y, Omega, n1, n2);
    full(A2)
end
A


function y=qrpermute(x,p)
%QRPERMUTE transpose or permute a quaternion array y=[x,p]
%
% Inputs:   x(4m,...)  Real quaternions array
%           p          new order of dimensions [default [2 1 ...]
%
% Outputs:  y(4n,...)  output real quaternion array

%      Copyright (C) Mike Brookes 2012
%      Version: $Id: qrpermute.m 1619 2012-03-15 09:31:31Z 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.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
s=size(x);
if nargin<2
    p=[2 1 3:length(s)];
end
s(1)=s(1)/4;
t=s(p);
t(1)=4*t(1);
y=reshape(permute(reshape(x,[4 s]),[1 p+1]),t);


function corner_4_coordinates = Get4Points( corner_coordinates )
%GET4POINTS Summary of this function goes here
%
variance = 10;   % delta_x + delta_y: The distance of the 4 corners should not <= the designated variance
numberOfPoints = 0; % should be 4 corners eventually for a quadrilateral

%corner_coordinates = sort(corner_coordinates,2);
sizeOfCornerPoints = size(corner_coordinates); % 1 element of the vector is the number of row

delta_x = variance; delta_y = 1;    % ensure (delta_x + delta_y) > variance to start with

% for the 4 corners
numberOfPoint1 = 0; numberOfPoint2 = 0; numberOfPoint3 = 0; numberOfPoint4 = 0;

% get the 4 designated points
        for i=1:sizeOfCornerPoints(1)
            if (i+1) < sizeOfCornerPoints(1)
                % appoint it as the candidate point
                if (numberOfPoints < 4) & ((delta_x + delta_y) > variance )
                    numberOfPoints = numberOfPoints+1;
                    designatedPoint(numberOfPoints,:) = corner_coordinates(i,:);
                end

                delta_x = abs(designatedPoint(numberOfPoints,1) - corner_coordinates(i+1,1));    % difference of the 2 x values
                delta_y = abs(designatedPoint(numberOfPoints,2) - corner_coordinates(i+1,2));    % difference of the 2 y values

            end
        end

        corner_4_coordinates = designatedPoint;
end

% Notes
% =====
%  Recommendation: The points may be averaged as well
%


% Computes the speed difference between Matlab's binornd and
% Lightspeed's randbinom.

p = 0.13;
n = 123;
tim = [];

nsamples = 1e4;
y = zeros(nsamples,1);
tic
for i = 1:nsamples
  y(i) = randbinom(p,n);
end
tim(1) = toc;
%g = int_hist(y+1,n+1)/nsamples;
tic
for i = 1:nsamples
  y(i) = binornd(n,p);
end
tim(2) = toc;
fprintf('Time for binornd: %g\n', tim(2));
fprintf('Time for randbinom: %g (%g times faster)\n', tim(1), tim(2)/tim(1));

if 0
  % test validity of the sampler (use nsamples = 1e5)
  x = 0:n;
  f = binopdf(x,n,p);
  plot(x,f,x,g)
  legend('true','estimated')
end


function I2 = lensdistort(I, k, varargin)
%LENSDISTORT corrects for barrel and pincusion lens abberations
%   I = LENSDISTORT(I, k)corrects for radially symmetric distortions, where
%   I is the input image and k is the distortion parameter. lens distortion
%   can be one of two types: barrel distortion and pincushion distortion.
%   In "barrel distortion", image magnification decreases with
%   distance from the optical axis. The apparent effect is that of an image
%   which has been mapped around a sphere (or barrel). In "pincushion
%   distortion", image magnification increases with the distance from the
%   optical axis. The visible effect is that lines that do not go through the
%   centre of the image are bowed inwards, towards the centre of the image,
%   like a pincushion [1].
%
%   I = LENSDISTORT(...,PARAM1,VAL1,PARAM2,VAL2,...) creates a new image image,
%   specifying parameters and corresponding values that control various aspects
%   of the image distortion correction. Parameter names case does not matter.
%
%   Parameters include:
%
%   'bordertype'            String that controls the treatment of the image
%                           edges. Valid strings are 'fit' and 'crop'. By
%                           default, 'bordertype' is set to 'crop'.
%
%   'interpolation'         String that specifies the interpolating kernel
%                           that the separable resampler uses. Valid
%                           strings are 'cubic', 'linear' and 'nearest'. By
%                           default, the 'interpolation' is set to 'cubic'
%
%   'padmethod'             string that controls how the resampler
%                           interpolates or assigns values to output elements
%                           that map close to or outside the edge of the input
%                           array. Valid strings are 'bound', circular',
%                           'fill', 'replicate', and symmetric'. By
%                           default, the 'padmethod' is set to 'fill'
%
%   'ftype'                 Integer between 1 and 4 that specifies the
%                           distortion model to be used. The models
%                           available are
%
%                           'ftype' = 1:    s = r.*(1./(1+k.*r));
%
%                           'ftype' = 2:    s = r.*(1./(1+k.*(r.^2)));
%
%                           'ftype' = 3:    s = r.*(1+k.*r);
%
%                           'ftype' = 4:    s = r.*(1+k.*(r.^2));
%
%                           By default, the 'ftype' is set to 4.
%
%   Class Support
%   -------------
%   An input intensity image can be uint8, int8, uint16, int16, uint32,
%   int32, single, double, or logical. An input indexed image can be uint8,
%   uint16, single, double, or logical.
%
%   Examples
%   --------
%       % read image
%       I = imread('cameraman.tif');
%
%       % Distort Image
%       I2 = lensdistort(I, 0.1);
%
%       % Display both images
%       imshow(I), figure, imshow(I2)
%
%   References
%   --------------
%   [1] http://en.wikipedia.org/wiki/Distortion_(optics), August 2012.
%
%   [2] Harri Ojanen, "Automatic Correction of Lens Distortion by Using
%       Digital Image Processing," July 10, 1999.
%
%   [3] G.Vassy and T.Perlaki, "Applying and removing lens distortion in post
%       production," year???
%
%   [4] http://www.mathworks.com/products/demos/image/...
%       create_gallery/tform.html#34594, August 2012.
%
%   Created by Jaap de Vries, 8/31/2012
%   jpdvrs@yahoo.com
%
%-----------------------------------------------------------------------%

%-------------------------------------------------------------------------
% This part of the codes creates variable input parameters using the input
% parser object
p = inputParser;
%   Make input string case independant
p.CaseSensitive = false;

%   Specifies the required inputs
addRequired(p,'I',@isnumeric);
addRequired(p,'k',@isnumeric);

%   Sets the default values for the optional parameters
defaultFtype = 4;
defaultBorder = 'crop';
defaultInterpolation = 'cubic';
defaultPadmethod = 'fill';

%   Specifies valid strings for the optional parameters
validBorder = {'fit','crop'};
validInterpolation = {'cubic','linear', 'nearest'};
validPadmethod = {'bound','circular', 'fill', 'replicate', 'symmetric'};

%   Funtion handles to determine wheter a proper input string has been used
checkBorder = @(x) any(validatestring(x,validBorder));
checkInterpolation = @(x) any(validatestring(x,validInterpolation));
checkPadmethod = @(x) any(validatestring(x,validPadmethod));

%   Create optional inputs
addParamValue(p,'bordertype',defaultBorder,checkBorder);
addParamValue(p,'interpolation',defaultInterpolation,checkInterpolation);
addParamValue(p,'padmethod',defaultPadmethod,checkPadmethod);
addParamValue(p,'ftype',defaultFtype,@isnumeric);

%   Pass all parameters and input to the parse method
parse(p,I,k,varargin{:});

%-------------------------------------------------------------------------
% This determines wether its a color (M,N,3) or gray scale (M,N,1) image
if ndims(I) == 3
     for i=1:3
        I2(:,:,i) = imdistcorrect(I(:,:,i),k);
     end
elseif ismatrix(I)
    I2 = imdistcorrect(I,k);
else
    error('Unknown image dimensions')
end

%-------------------------------------------------------------------------
% Nested function that perfoms the transformation
    function I3 = imdistcorrect(I,k)
    % Determine the size of the image to be distorted
    [M N]=size(I);
    center = [round(N/2) round(M/2)];
    % Creates N x M (#pixels) x-y points
    [xi,yi] = meshgrid(1:N,1:M);
    % Creates converst the mesh into a colum vector of coordiantes relative to
    % the center
    xt = xi(:) - center(1);
    yt = yi(:) - center(2);
    % Converts the x-y coordinates to polar coordinates
    [theta,r] = cart2pol(xt,yt);
    % Calculate the maximum vector (image center to image corner) to be used
    % for normalization
    R = sqrt(center(1)^2 + center(2)^2);
    % Normalize the polar coordinate r to range between 0 and 1
    r = r/R;
    % Aply the r-based transformation
    s = distortfun(r,k,p.Results.ftype);
    % un-normalize s
    s2 = s * R;
    % Find a scaling parameter based on selected border type
    brcor = bordercorrect(r,s,k, center, R);

    s2 = s2 * brcor;

    % Convert back to cartesian coordinates
    [ut,vt] = pol2cart(theta,s2);

    u = reshape(ut,size(xi)) + center(1);
    v = reshape(vt,size(yi)) + center(2);
    tmap_B = cat(3,u,v);
    resamp = makeresampler(p.Results.interpolation, p.Results.padmethod);
    I3 = tformarray(I,[],resamp,[2 1],[1 2],[],tmap_B,255);
    end

%-------------------------------------------------------------------------
% Nested function that creates a scaling parameter based on the
% 'bordertype' selected
    function x = bordercorrect(r,s,k,center, R)
        if k < 0
            if strcmp(p.Results.bordertype, 'fit')
               x = r(1)/s(1);
            end
            if strcmp(p.Results.bordertype,'crop')
               x = 1/(1 + k*(min(center)/R)^2);
            end
        elseif k > 0
            if strcmp(p.Results.bordertype, 'fit')
               x = 1/(1 + k*(min(center)/R)^2);
            end
            if strcmp(p.Results.bordertype, 'crop')
               x = r(1)/s(1);
            end
        end
    end

%-------------------------------------------------------------------------
% Nested function that pics the model type to be used
    function s = distortfun(r,k,fcnum)
        switch fcnum
        case(1)
            s = r.*(1./(1+k.*r));
        case(2)
            s = r.*(1./(1+k.*(r.^2)));
        case(3)
            s = r.*(1+k.*r);
        case(4)
            s = r.*(1+k.*(r.^2));
        end
    end

end


function [ ptab, b, c, d, eps, ierror ] =  least_set ( ntab, xtab, ytab, ndeg )

%% LEAST_SET constructs the least squares polynomial approximation to data.
%
%  Discussion:
%
%    The least squares polynomial is not returned directly as a simple
%    polynomial.  Instead, it is represented in terms of a set of
%    orthogonal polynomials appopriate for the given data.  This makes
%    the computation more accurate, but means that the user can not
%    easily evaluate the computed polynomial.  Instead, the routine
%    LEAST_EVAL should be used to evaluate the least squares polynomial
%    at any point.  (However, the value of the least squares polynomial
%    at each of the data points is returned as part of this computation.)
%
%
%    A discrete unweighted inner product is used, so that
%
%      ( F(X), G(X) ) = sum ( 1 <= I <= NTAB ) F(XTAB(I)) * G(XTAB(I)).
%
%    The least squares polynomial is determined using a set of
%    orthogonal polynomials PHI.  These polynomials can be defined
%    recursively by:
%
%      PHI(0)(X) = 1
%      PHI(1)(X) = X - B(1)
%      PHI(I)(X) = ( X - B(I) ) * PHI(I-1)(X) - D(I) * PHI(I-2)(X)
%
%    The array B(1:NDEG) contains the values
%
%      B(I) = ( X*PHI(I-1), PHI(I-1) ) / ( PHI(I-1), PHI(I-1) )
%
%    The array D(2:NDEG) contains the values
%
%      D(I) = ( PHI(I-1), PHI(I-1) ) / ( PHI(I-2), PHI(I-2) )
%
%    Using this basis, the least squares polynomial can be represented as
%
%      P(X)(I) = sum ( 0 <= I <= NDEG ) C(I) * PHI(I)(X)
%
%    The array C(0:NDEG) contains the values
%
%      C(I) = ( YTAB(I), PHI(I) ) / ( PHI(I), PHI(I) )
%
%  Modified:
%
%    16 May 2004
%
%  Reference:
%
%    Gisela Engeln-Muellges and Frank Uhlig,
%    Numerical Algorithms with C, pages 191-193.
%    Springer, 1996.
%
%  Parameters:
%
%    Input, integer NTAB, the number of data points.
%
%    Input, real XTAB(NTAB), the X data.  The values in XTAB
%    should be distinct, and in increasing order.
%
%    Input, real YTAB(NTAB), the Y data values corresponding
%    to the X data in XTAB.
%
%    Input, integer NDEG, the degree of the polynomial which the
%    program is to use.  NDEG must be at least 1, and less than or
%    equal to NTAB-1.
%
%    Output, real PTAB(NTAB), the value of the least squares polynomial
%    at the points XTAB(1:NTAB).
%
%    Output, real B(1:NDEG), C(1:NDEG+1), D(1:NDEG-1), arrays containing
%    data about the polynomial.
%
%    Output, real EPS, the root-mean-square discrepancy of the
%    polynomial fit.
%
%    Output, integer IERROR, error flag.
%    zero, no error occurred;
%    nonzero, an error occurred, and the polynomial could not be computed.
%
  ierror = 0;
  C_OFFSET = 1;
  D_OFFSET = -1;
%
%  Check NDEG.
%
  if ( ndeg < 1 )
    ierror = 1;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LEAST_SET - Fatal error!\n' );
    fprintf ( 1, '  NDEG < 1.\n' );
    error ( 'LEAST_SET - Fatal error!' );
  end

  if ( ntab <= ndeg )
    ierror = 1;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'LEAST_SET - Fatal error!\n' );
    fprintf ( 1, '  NTAB <= NDEG.\n' );
    error ( 'LEAST_SET - Fatal error!' );
  end
%
%  Check that the abscissas are strictly increasing.
%
  for ( i = 1 : ntab-1 )
    if ( xtab(i+1) <= xtab(i) )
      ierror = 1;
      fprintf ( 1, '\n' );
      fprintf ( 1, 'LEAST_SET - Fatal error!\n' );
      fprintf ( 1, '  XTAB must be strictly increasing, but\n' );
      fprintf ( 1, '  XTAB(%d) = %f\n', i,   xtab(i)   );
      fprintf ( 1, '  XTAB(%d) = %f\n', i+1, xtab(i+1) );
      error ( 'LEAST_SET - Fatal error!' );
    end
  end

  i0l1 = 0;
  i1l1 = ntab;
%
%  The polynomial is of degree at least 0.
%
  y_sum = sum ( ytab(1:ntab) );
  rn0 = ntab;
  c(0+C_OFFSET) = y_sum / ntab;

  ptab(1:ntab) = y_sum / ntab;

  if ( ndeg == 0 )
    eps = sum ( ( ptab(1:ntab) - ytab(1:ntab) ).^2 );
    eps = sqrt ( eps / ntab );
    b = [];
    d = [];
    return;
  end
%
%  The polynomial is of degree at least 1.
%
  b(1) = sum ( xtab(1:ntab) ) / ntab;

  s = 0.0E+00;
  sum2 = 0.0E+00;
  for ( i = 1 : ntab )
    ztab(i1l1+i) = xtab(i) - b(1);
    s = s + ztab(i1l1+i)^2;
    sum2 = sum2 + ztab(i1l1+i) * ( ytab(i) - ptab(i) );
  end

  rn1 = s;
  c(1+C_OFFSET) = sum2 / s;

  for ( i = 1 : ntab )
    ptab(i) = ptab(i) + c(1+C_OFFSET) * ztab(i1l1+i);
  end

  if ( ndeg == 1 )
    eps = sum ( ( ptab(1:ntab) - ytab(1:ntab) ).^2 );
    eps = sqrt ( eps / ntab );
    d = [];
    return;
  end

  ztable(1:ntab) = 1.0E+00;

  mdeg = 2;
  k = 2;

  while ( 1 )

    d(k+D_OFFSET) = rn1 / rn0;

    sum2 = 0.0E+00;
    for ( i = 1 : ntab )
      sum2 = sum2 + xtab(i) * ztab(i1l1+i) * ztab(i1l1+i);
    end

    b(k) = sum2 / rn1;

    s = 0.0E+00;
    sum2 = 0.0E+00;
    for ( i = 1 : ntab )
      ztab(i0l1+i) = ( xtab(i) - b(k) ) * ztab(i1l1+i) ...
        - d(k+D_OFFSET) * ztab(i0l1+i);
      s = s + ztab(i0l1+i) * ztab(i0l1+i);
      sum2 = sum2 + ztab(i0l1+i) * ( ytab(i) - ptab(i) );
    end

    rn0 = rn1;
    rn1 = s;

    c(k+C_OFFSET) = sum2 / rn1;

    it = i0l1;
    i0l1 = i1l1;
    i1l1 = it;

    for ( i = 1 : ntab )
      ptab(i) = ptab(i) + c(k+C_OFFSET) * ztab(i1l1+i);
    end

    if ( ndeg <= mdeg )
      break;
    end

    mdeg = mdeg + 1;
    k = k + 1;

  end
%
%  Compute the RMS error.
%
  eps = sum ( ( ptab(1:ntab) - ytab(1:ntab) ).^2 );
  eps = sqrt ( eps / ntab );


function [hmg, HMG_u, HMG_s, HMG_k, HMG_c] = invPinHoleHmg(u,s,k,c)

% INVPINHOLEHMG Retro-project anchored homogeneous point AHP.
%   HMG = INVPINHOLEHMG(U,S) gives the retroprojected anchored homogeneous
%   point (HMG) of a pixel U at inverse-depth S, from a canonical pin-hole
%   camera, that is, with calibration parameters
%     u0 = 0, v0 = 0, au = 1, av = 1
%   It uses reference frames {RDF,RD} (right-down-front for the 3D world
%   points and right-down for the pixel), according to this scheme:
%
%         / z (forward)
%        /
%       +------- x                 +------- u
%       |                          |
%       |      3D : P=[x;y;z]      |     image : U=[u;v]
%       | y                        | v
%
%   HMG = INVPINHOLEHMG(U,S,K) allows the introduction of the camera's
%   calibration parameters:
%     K = [u0 v0 au av]'
%
%   HMG = INVPINHOLEHMG(U,S,K,C) allows the introduction of the camera's radial
%   distortion correction parameters:
%     C = [c2 c4 c6 ...]'
%   so that the new pixel is corrected following the distortion equation:
%     U = U_D * (1 + K2*R^2 + K4*R^4 + ...)
%   with R^2 = sum(U_D.^2), being U_D the distorted pixel in the image
%   plane for a camera with unit focal length.
%
%   If U is a pixels matrix, INVPINHOLEHMG(U,...) returns a HMGS matrix HMG,
%   with these matrices defined as
%     U   = [U1 ... Un];       Ui   = [ui;vi]
%     HMG = [HMG1 ... HMGn];   HMGi = [xi,yi,zi,ri]
%   where xi, yi, zi are the non-homogeneous parts of HMG, defining the
%   optical ray, and ri is the inverse of the distance (wrongly named
%   "inverse depth")
%
%   [HMG,HMG_u,HMG_s,HMG_k,HMG_c] returns the Jacobians of HMG wrt U, S, K and C. It
%   only works for single pixels U=[u;v], and for distortion correction
%   vectors C of up to 3 parameters C=[c2;c4;c6]. See UNDISTORT for
%   information on longer distortion vectors.
%
%   See also RETRO, UNDISTORT, DEPIXELLISE, PINHOLEHMG.

%   Copyright 2008-2009 Joan Sola @ LAAS-CNRS.

if nargout == 1 % only point

    switch nargin
        case 2
            v = retro(u,1);
        case 3
            v = retro(depixellise(u,k),1);
        case 4
            v = retro(undistort(depixellise(u,k),c),1);
    end
    n = normvec(v);
    hmg  = [n;s];

else % Jacobians

    if size(u,2) > 1
        error('Jacobians not available for multiple pixels')
    else

        switch nargin
            case 2
                [v, V_u] = invPinHole(u,1);
                [n,N_v]  = normvec(v,1);
                hmg      = [n;s];
                HMG_v    = [N_v;zeros(1,3)];
                HMG_s    = [0;0;0;1];
                HMG_u    = HMG_v*V_u;

            case 3
                [v, V_u, V_1, V_k] = invPinHole(u,1,k);
                [n,N_v]  = normvec(v,1);
                hmg      = [n;s];
                HMG_v    = [N_v;zeros(1,3)];
                HMG_s    = [0;0;0;1];
                HMG_u    = HMG_v*V_u;
                HMG_k    = HMG_v*V_k;

            case 4
                [v, V_u, V_1, V_k, V_c] = invPinHole(u,1,k,c);
                [n,N_v]  = normvec(v,1);
                hmg      = [n;s];
                HMG_v    = [N_v;zeros(1,3)];
                HMG_s    = [0;0;0;1];
                HMG_u    = HMG_v*V_u;
                HMG_k    = HMG_v*V_k;
                HMG_c    = HMG_v*V_c;

        end
    end

end

return

%% jacobians
syms u v s u0 v0 au av c2 c4 c6 real
U=[u;v];
k=[u0;v0;au;av];
c=[c2;c4;c6];

% [hmg,HMG_u,HMG_s] = invPinHoleHmg(U,s);
% [hmg,HMG_u,HMG_s,HMG_k] = invPinHoleHmg(U,s,k);
[hmg,HMG_u,HMG_s,HMG_k,HMG_c] = invPinHoleHmg(U,s,k,c);

simplify(HMG_u - jacobian(hmg,U))
simplify(HMG_s - jacobian(hmg,s))
simplify(HMG_k - jacobian(hmg,k))
% simplify(HMG_c - jacobian(hmg,c))

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

%   # START GPL LICENSE

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

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

%   # END GPL LICENSE


function [point,sc] = harris_strongest(im,sigma,mrg,edgerej)
% HARRIS_STRONGEST Extract strongest Harris point.
%   HARRIS_STRONGEST(IM) extracts the strongest harris point in image IM.
%
%   HARRIS_STRONGEST(IM, SG, MRG, EDGEREJ) accepts additional inputs as
%   follows:
%
%   INPUT
%   =====
%   im     : the graylevel image
%   sigma  : STD of the smoothing mask in pixels
%   mrg    : inner margin to be ignored
%   edgerej: maximum ratio allowed between largest and smallest eigenvalues
%
%   [P,SC] = HARRIS_STRONGEST(...) returns also the point's strength as a
%   scalar score (non-normalized).
%
%   OUTPUT
%   ======
%   point  : the interest point extracted
%   sc     : strength of corner point
%
%   EXAMPLE
%   =======
%   [point,sc] = harris_strongest(im)

% Author :: Vincent Garcia - multiple point detector
% Date   :: 05/12/2007
%
% Author :: Joan Sola - strongest point detector, margin ignoring, edge
% rejection
% Date   :: 01/08/2008
%
% REFERENCES
% ==========
% C.G. Harris and M.J. Stephens. "A combined corner and edge detector",
% Proceedings Fourth Alvey Vision Conference, Manchester.
% pp 147-151, 1988.
%
% Alison Noble, "Descriptions of Image Surfaces", PhD thesis, Department
% of Engineering Science, Oxford University 1989, p45.
%
% C. Schmid, R. Mohrand and C. Bauckhage, "Evaluation of Interest Point Detectors",
% Int. Journal of Computer Vision, 37(2), 151-172, 2000.
%

persistent x dx dy ex g; % gaussian filter

% Input options management
switch nargin
    case 1
        sigma = 2;
        mrg = 0;
        edgerej = 20;
    case 2
        mrg = 0;
        edgerej = 20;
    case 3
        edgerej = 20;
end

% only luminance value
im = single(im(:,:,1));

% image size
[sx,sy] = size(im);

% derivative masks
s_D = 0.5*sigma;
if isempty(x)
    x  = -round(2.0*s_D):round(2.0*s_D);
    ex = exp(-x.*x/(2*s_D^2)) ./ (s_D*sqrt(2*pi));
    dx = s_D^2 * x .* ex;
    dy = dx';
    g = conv2(ex,ex');
    g = g/sum(sum(g));
end

% image derivatives
Ix = conv2(im, dx, 'same');
Iy = conv2(im, dy, 'same');

Ix2 = conv2(Ix.^2, g, 'same'); % Smoothed squared image derivatives
Iy2 = conv2(Iy.^2, g, 'same');
Ixy = conv2(Ix.*Iy, g, 'same');

% interest point response
% Original Harris measure.
% k = 0.06; cim = (Ix2.*Iy2 - Ixy.^2) - k*(Ix2 + Iy2).^2;

% Alison Noble measure.
% cim = (Ix2.*Iy2 - Ixy.^2)./(Ix2 + Iy2 + eps);

% Shi and Tomasi -- smallest eigenvalue
a = Ix2+Iy2;
b = sqrt((Ix2-Iy2).^2+4*Ixy.^2);
cim = a-b;  % Smallest eigenvalue.

% supress corner measures close to margin
cim([1:mrg sx-mrg+1:sx],:) = -9e9;
cim(:,[1:mrg sy-mrg+1:sy]) = -9e9;

% Find strongest corner [u;v] and score
[scv,v] = max(cim);
[sc,u]  = max(scv);     % score and u-coordinate
v       = v(u);         % v-coordinate

% reject edges
l = sc;                 % smallest eigenvalue is the score
L = a(v,u) + b(v,u);    %  largest eigenvalue
if L/l > edgerej        % reject edge detections
    sc = 0;             % return nothing if winner is an edge
end

point = [u;v];

% comment out this part for displaying purposes
% figure(98)
% imshow(im,[0 255]);colormap(gray(255))
% axis on
% hold on;
% sz = 3;
% rectangle('Position',[u-sz,v-sz,2*sz,2*sz],'Curvature',[0 0],'EdgeColor','b','LineWidth',1);
% figure(99)
% imshow(cim,[0 max(max(cim))]); axis on;colormap(gray(255))
% rectangle('Position',[u-sz,v-sz,2*sz,2*sz],'Curvature',[0 0],'EdgeColor','b','LineWidth',1);
% point;
% sc;

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

%   # START GPL LICENSE

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

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

%   # END GPL LICENSE


function cvx_optval = norms_largest( varargin )

%NORMS_LARGEST Computation of multiple norm_largest() norms.
%   NORMS_LARGEST( X, K, DIM ) provides a means to compute the largest-k
%   norms of multiple vectors packed into a matrix or N-D vector. This is
%   useful for performing max-of-norms or sum-of-norms calculations.
%
%   If DIM is omitted, the norms are computed along the first non-singleton
%   dimension.
%
%   See NORM_LARGEST.
%
%   Disciplined convex programming information:
%       NORMS_LARGEST is convex and non-monotonic, so its input must be affine.

[ sx, x, k, dim ] = cvx_get_dimension( varargin, 3 );

if ~isnumeric( k ) || ~isreal( k ) || length( k ) ~= 1,
    cvx_throw( 'Second argument must be a real scalar.' );
end

cvx_optval = sum_largest( abs( x ), k, dim );

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function xyt = Xt(s)
x = s ;
y = 1-3*s+3*s^2 ;

xyt = [x ; y] ;


function M = femUnk2Qud(fe,domain)
%+========================================================================+
%|                                                                        |
%|              OPENFEM - LIBRARY FOR FINITE ELEMENT METHOD               |
%|           openFem is part of the GYPSILAB toolbox for Matlab           |
%|                                                                        |
%| COPYRIGHT : Matthieu Aussal & Francois Alouges (c) 2017-2018.          |
%| PROPERTY  : Centre de Mathematiques Appliquees, Ecole polytechnique,   |
%| route de Saclay, 91128 Palaiseau, France. All rights reserved.         |
%| LICENCE   : This program is free software, distributed in the hope that|
%| it will be useful, but WITHOUT ANY WARRANTY. Natively, you can use,    |
%| redistribute and/or modify it under the terms of the GNU General Public|
%| License, as published by the Free Software Foundation (version 3 or    |
%| later,  http://www.gnu.org/licenses). For private use, dual licencing  |
%| is available, please contact us to activate a "pay for remove" option. |
%| CONTACT   : matthieu.aussal@polytechnique.edu                          |
%|             francois.alouges@polytechnique.edu                         |
%| WEBSITE   : www.cmap.polytechnique.fr/~aussal/gypsilab                 |
%|                                                                        |
%| Please acknowledge the gypsilab toolbox in programs or publications in |
%| which you use it.                                                      |
%|________________________________________________________________________|
%|   '&`   |                                                              |
%|    #    |   FILE       : femUnknown.m                                  |
%|    #    |   VERSION    : 0.40                                          |
%|   _#_   |   AUTHOR(S)  : Matthieu Aussal & François Alouges            |
%|  ( # )  |   CREATION   : 14.03.2017                                    |
%|  / 0 \  |   LAST MODIF : 14.03.2018                                    |
%| ( === ) |   SYNOPSIS   : Unknowns and reduction matrix for constrained |
%|  `---'  |                finite elements                               |
%+========================================================================+

% Unknown to degrees of freedom matrix
[~,P] = fe.unk;

% Surfacic restriction (trace)
if (size(fe.msh.elt,2) == size(domain.msh.elt,2) + 1)
    bound  = fe.msh.bnd;
    P      = restriction(fe,bound) * P;
    fe.msh = bound;
end

% Degrees of freedom to quadrature matrix
if strcmp(fe.typ(1),'P')
    M = femLagrangePn(fe,domain);
elseif strcmp(fe.typ,'RWG')
    M = femRaoWiltonGlisson(fe,domain);
elseif strcmp(fe.typ,'NED')
    M = femNedelec(fe,domain);
else
    error('fem.m : unavailable case')
end

% Unknown to quadrature
if iscell(M)
    M{1} = M{1} * P;
    M{2} = M{2} * P;
    M{3} = M{3} * P;
else
    M = M * P;
end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sh7.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% function f = sh7(x)
% Shekel7 function
function f = sh7(x)
a = [4, 1, 8, 6, 3, 2, 5;
     4, 1, 8, 6, 7, 9, 5;
     4, 1, 8, 6, 3, 2, 3;
     4, 1, 8, 6, 7, 9, 3];
c = [0.1 0.2 0.2 0.4 0.4 0.6 0.3];
if size(x,1) == 1
 x = x';
end
for i=1:7
 b = (x - a(:,i)).^2;
 d(i) = sum(b);
end
f = -sum((c+d).^(-1));


function pce_ode_hermite_test01 ( )

%*****************************************************************************80
%
%% PCE_ODE_HERMITE_TEST01 runs a test problem with PCE_ODE_HERMITE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2012
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'PCE_ODE_HERMITE_TEST01:\n' );
  fprintf ( 1, '  Call PCE_ODE_HERMITE to compute a polynomial chaos expansion\n' );
  fprintf ( 1, '  for the ODE:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '    u'' = - alpha * u,\n' );
  fprintf ( 1, '    u(0) = 1.\n' );

  ti = 0.0;
  tf = 2.0;
  nt = 200;
  ui = 1.0;
  np = 4;
  alpha_mu = 0.0;
  alpha_sigma = 1.0;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Initial time         TI = %g\n', ti );
  fprintf ( 1, '  Final time           TF = %g\n', tf );
  fprintf ( 1, '  Number of time steps NT = %d\n', nt );
  fprintf ( 1, '  Initial condition    UI = %g\n', ui );
  fprintf ( 1, '  Expansion degree     NP = %d\n', np );
  fprintf ( 1, '  E(ALPHA)       ALPHA_MU = %g\n', alpha_mu );
  fprintf ( 1, '  STD(ALPHA)  ALPHA_SIGMA = %g\n', alpha_sigma );

  [ t, u ] = pce_ode_hermite ( ti, tf, nt, ui, np, alpha_mu, alpha_sigma );
%
%  Evaluate the exact expected value function.
%
  uex = ui * exp ( t.^2 / 2 );
%
%  Compare the first computed component against the exact expected value.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, ' i  T(i)  E(U(T(i)))    U(T(i),0)\n' );
  fprintf ( 1, '\n' );
  for i = 0 : 10 : nt
    fprintf ( 1, '  %4d  %6.3f  %14.6g  %14.6g  %14.6g\n', ...
      i, t(i+1), uex(i+1), u(i+1,1), abs ( uex(i+1) - u(i+1,1) ) );
  end
%
%  Plot the first computed component against the exact expected value function.
%
  figure ( 1 )
  plot ( t, u(:,1), t, uex )
  grid on
  xlabel ( '<--- T --->' )
  ylabel ( '<--- U --->' )
  title ( 'PCE Expected Value Versus Exact Expected Value' )

  filename = 'expected_value_plot.png';
  print ( '-dpng', filename );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Expected value comparison plotted in "%s".\n', filename );

  return
end


function [pt,p0,v0,t,idx]=surfinterior(node,face)
%
% [pt,p0,v0,t,idx]=surfinterior(node,face)
%
% identify a point that is enclosed by the (closed) surface
%
% author: Qianqian Fang, <q.fang at neu.edu>
%
% input:
%   node: a list of node coordinates (nn x 3)
%   face: a surface mesh triangle list (ne x 3)
%
% output:
%   pt: the interior point coordinates [x y z]
%   p0: ray origin used to determine the interior point
%   v0: the vector used to determine the interior point
%   t : ray-tracing intersection distances (with signs) from p0. the
%       intersection coordinates can be expressed as p0+t(i)*v0
%   idx: index to the face elements that intersect with the ray, order
%       match that of t
%
% -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net)
%

pt=[];
len=size(face,1);
for i=1:len
   p0=mean(node(face(i,1:3),:));
   plane=surfplane(node,face(i,:));
   v0=plane(1:3);

   [t,u,v]=raytrace(p0,v0,node,face(:,1:3));

   idx=find(u>=0 & v>=0 & u+v<=1.0 & ~isinf(t));
   [ts, uidx]=unique(sort(t(idx)));
   if(~isempty(ts) && mod(length(ts),2)==0)
       ts=reshape(ts,[2 length(ts)/2]);
       tdiff=ts(2,:)-ts(1,:);
       [maxv,maxi]=max(tdiff);
       pt=p0+v0*(ts(1,maxi)+ts(2,maxi))*0.5;
       idx=idx(uidx);
       t=t(idx);
       break;
   end
end


function [bar] = mmHg2bar(mmHg)
% Convert pressure from millimeters of mercury at 0 degrees C to bar
% Chad Greene 2012
bar = mmHg*0.00133322;


function ADEM_lorenz_surprise
% This demo computes the cost-function (negative reward) for a Lorenz
% system; to show cost can be computed easily from value (negative
% surprise or sojourn time). However, value is not a Lyapunov function
% because the flow is not curl-free (i.e., is not irrotational).
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: ADEM_lorenz_surprise.m 4804 2012-07-26 13:14:18Z karl $

% dynamics and parameters
%-------------------------------------------------------------------------
DEMO     = 0;                          % switch for demo
LOR      = 1;                          % Lorenz vs a linear system

% generative model
%==========================================================================                       % switch for demo
G(1).E.s = 1/4;                        % smoothness
G(1).E.n = 6;                          % smoothness
G(1).E.d = 2;                          % smoothness

% dynamics and parameters
%--------------------------------------------------------------------------
if LOR
    fL  = '[v; 0; 0] + [-P(1) P(1) 0; P(3) -1 -x(1); x(2) 0 P(2)]*x/64';
    PL  = [10; -8/3; 32];
    x0  = [1; 1; 24];
    W   = exp(8);
else
    fL  = '[v; 0; 0] + [-P(1) 0 0; 0 -P(2) 0; 0 0 -P(3)]*x/64';
    PL  = [1; 1; 8];
    x0  = [-16; 16; 0];
    W   = diag([32; 32; exp(8)]);
end

% level 1
%--------------------------------------------------------------------------
G(1).x  = x0;
G(1).f  = inline(fL ,'x','v','P');
G(1).g  = inline('x','x','v','P');
G(1).pE = PL;
G(1).V  = exp(8);                           % error precision
G(1).W  = W;                                % error precision

% level 2
%--------------------------------------------------------------------------
G(2).a  = [0;0;0];                          % action variables
G(2).v  = 0;                                % inputs
G(2).V  = exp(16);
G       = spm_DEM_M_set(G);

% space
%--------------------------------------------------------------------------
N        = 66;
if LOR
    x{1} = linspace(-32,32,N);
    x{2} = linspace(-32,32,N);
    x{3} = linspace(  4,64,N);
else
    x{1} = linspace(-8,8,N);
    x{2} = linspace(-8,8,N);
    x{3} = linspace(-1,1,3);
end

% equilibrium density (q0), loss (L) and value (V) functions
%==========================================================================
if DEMO

    % Fokker-Planck operator and equilibrium density
    %----------------------------------------------------------------------
    [M0,q0] = spm_fp(G,x);

    % loss-function and negative surprise (value)
    %----------------------------------------------------------------------
    V    = log(q0);
    L    = spm_unvec(spm_vec(V)'*M0,q0);

    % trim
    %----------------------------------------------------------------------
    q0   = q0(2:end - 1,2:end - 1,2:end - 1);
    L    =  L(2:end - 1,2:end - 1,2:end - 1);
    V    =  V(2:end - 1,2:end - 1,2:end - 1);
    x{1} = x{1}(2:end - 1);
    x{2} = x{2}(2:end - 1);
    x{3} = x{3}(2:end - 1);

    if LOR
        save DEM_lorenz_suprise q0 L V x
    end
else
    load DEM_lorenz_suprise
end

% axes and trajectory
%--------------------------------------------------------------------------
spm_figure('GetWin','DEM');

if LOR, z = 24; else, z = 1; end

i    = 3;
j    = 1:3;
j(i) = [];
T    = 1024;
U.u  = sparse(T,G(1).m);
t    = spm_int_J(G(1).pE,G,U);

% surprise
%--------------------------------------------------------------------------
a    = [x{j(2)}(1) x{j(2)}(end) x{j(1)}(1) x{j(1)}(end)];
subplot(3,2,1)
imagesc(x{j(2)},x{j(1)},V(:,:,z))
hold on, plot(t(:,j(2)),t(:,j(1)),'r'), hold off
axis(a)
axis square xy
title('value','Fontsize',16)

% cost function
%--------------------------------------------------------------------------
subplot(3,2,2)
imagesc(x{j(2)},x{j(1)},L(:,:,z))
hold on, plot(t(:,j(2)),t(:,j(1)),'r'), hold off
axis(a)
axis square xy
title('cost','Fontsize',16)

% equilibrium density
%--------------------------------------------------------------------------
subplot(3,2,3)
imagesc(x{j(2)},x{j(1)},squeeze(max(q0,[],i)))
hold on, plot(t(:,j(2)),t(:,j(1)),'r'), hold off
axis(a)
axis square xy
title('density','Fontsize',16)

% exemplar trajectory
%--------------------------------------------------------------------------
subplot(3,2,4)
plot(t(:,j(2)),t(:,j(1)),'k')
axis(a)
axis square xy
title('trajectory','Fontsize',16)

% evaluate V(t)
%--------------------------------------------------------------------------
for i = 1:T
    [q ii] = min(abs(t(i,1) - x{1}));
    [q ij] = min(abs(t(i,2) - x{2}));
    [q ik] = min(abs(t(i,3) - x{3}));
    v(i)   = V(ii,ij,ik);
end

% and plot
%--------------------------------------------------------------------------
maxV = max(V(:));
subplot(3,1,3)
plot(v,'k'), hold on
plot([1 T],[maxV maxV],'r:'), hold off
title('value','Fontsize',16)
set(gca,'XLim',[1 T]);
box off