function v = dq2vel(dq)

% DQ2VEL     Transforms a dual quaternion point velocity representation
%            into a vector representation.
%
%        V = DQ2VEL(DQ) transforms the dual quaternion representation of
%        a point velocity (in the euclidean space) into a vector v, which
%        represents the point velocity coordinates.
%        DQ is either a vector of size 8 or an array of size 8*N (each
%        column represents a point velocity dual quaternion) where N is the
%        number of points. V is a vector of size 3 or an array of size 3*N
%        depending on the input format.
%
% See also VEL2DQ, DQ2POS, DQ2LINE, DQ2LINEVEL

sdq = size(dq);
if sdq == [1 8]
    dq = dq.';
    sdq = size(dq);
end

% wrong format
if sdq(1) ~= 8
    error('DualQuaternion:dquat2vel:wrongsize',...
        '%d rows in the DQ array. It should be 8.',sdq(1));
end

% extraction of the point velocity coordinates
v = dq(6:8,:);


function log_evidence = ldae_chibms(words, topics, topic_prior, ms_iters)
%LDAE_CHIBMS Approximate evidence for LDA using Murray & Salakhutdinov's Chib-style method
%
% log_evidence = ldae_chibms(words, topics, topic_prior);
%
% Inputs:
%             words 1xNd
%            topics TxV each row is a distribution over a vocabulary of size V
%       topic_prior 1xT parameters of Dirichlet from which document topic vector is drawn
%          ms_iters 1x1 Default: 1000
%
% Outputs:
%     log_evidence  1x1

% Iain Murray, January 2009

BURN_ITERS = 3;

if ~exist('ms_iters', 'var')
    ms_iters = 1000;
end

[T, V] = size(topics);
Nd = length(words);

% Sanity checking input sizes
assert(isvector(topic_prior));
assert(T == length(topic_prior));
assert(isvector(words));

topic_prior = topic_prior(:)';
topic_alpha = sum(topic_prior);
%topic_mean = topic_prior / topic_alpha;

% Assign latents to words in isolation as a simple initialization
Nz = zeros(1, T);
for t = 1:Nd
    pz = topics(:, words(t))' .* topic_prior;
    zz(t) = discreternd(1, pz);
    Nz(zz(t)) = Nz(zz(t)) + 1;
end

% Run some sweeps of Gibbs sampling
for sweeps = 1:BURN_ITERS
    for t = 1:Nd
        Nz(zz(t)) = Nz(zz(t)) - 1;
        pz = topics(:, words(t))' .* (Nz + topic_prior);
        zz(t) = discreternd(1, pz);
        Nz(zz(t)) = Nz(zz(t)) + 1;
    end
end

% Find local optimim to use as z^*, "iterative conditional modes"
% But don't spend forever on this, bail out if necessary
for i = 1:12
    old_zz = zz;
    for t = 1:Nd
        Nz(zz(t)) = Nz(zz(t)) - 1;
        pz = topics(:, words(t))' .* (Nz + topic_prior);
        [dummy, zz(t)] = max(pz);
        Nz(zz(t)) = Nz(zz(t)) + 1;
    end
    if ~isequal(old_zz, zz)
        break;
    end
end

% Run Murray & Salakhutdinov algorithm
zstar = zz;
log_Tvals = zeros(ms_iters, 1);
log_Tprob = @(zto, zfrom, Nzfrom) log_Tprob_base(zto, zfrom, Nzfrom, words, topics, topic_prior);
% draw starting position
ss = ceil(rand() * ms_iters);
% Draw z^(s)
for t = Nd:-1:1
    Nz(zz(t)) = Nz(zz(t)) - 1;
    pz = topics(:, words(t))' .* (Nz + topic_prior);
    zz(t) = discreternd(1, pz);
    Nz(zz(t)) = Nz(zz(t)) + 1;
end
zs = zz;
log_Tvals(ss) = log_Tprob(zstar, zz, Nz);
% Draw forward stuff
for sprime = (ss+1):ms_iters
    for t = 1:Nd
        Nz(zz(t)) = Nz(zz(t)) - 1;
        pz = topics(:, words(t))' .* (Nz + topic_prior);
        zz(t) = discreternd(1, pz);
        Nz(zz(t)) = Nz(zz(t)) + 1;
    end
    log_Tvals(sprime) = log_Tprob(zstar, zz, Nz);
end
% Draw backward stuff
for sprime = (ss-1):-1:1
    for t = Nd:-1:1
        Nz(zz(t)) = Nz(zz(t)) - 1;
        pz = topics(:, words(t))' .* (Nz + topic_prior);
        zz(t) = discreternd(1, pz);
        Nz(zz(t)) = Nz(zz(t)) + 1;
    end
    log_Tvals(sprime) = log_Tprob(zstar, zz, Nz);
end
% Final estimate
Nkstar = histc(zstar, 1:T); Nkstar = Nkstar(:)'; % 1xT
log_pz = sum(gammaln(Nkstar + topic_prior)) + gammaln(topic_alpha) ...
        - sum(gammaln(topic_prior)) - gammaln(Nd + topic_alpha);
log_w_given_z = 0;
for t = 1:Nd
    log_w_given_z = log_w_given_z + log(topics(zstar(t), words(t)));
end
log_joint = log_pz + log_w_given_z;
log_evidence = log_joint - (logsumexp(log_Tvals) - log(ms_iters));

function lp = log_Tprob_base(zto, zfrom, Nz, words, topics, topic_prior)
Nd = length(words);
lp = 0;
for t = 1:Nd
    Nz(zfrom(t)) = Nz(zfrom(t)) - 1;
    pz = topics(:, words(t))' .* (Nz + topic_prior);
    pz = pz/sum(pz);
    lp = lp + log(pz(zto(t)));
    Nz(zto(t)) = Nz(zto(t)) + 1;
end


function imgLogLuv = float2LogLuv(img)
%
%       imgLogLuv=float2LogLuv(img)
%
%
%        Input:
%           -img: a HDR image in RGB
%
%        Output:
%           -imgLogLuv: the HDR image in the 32-bit LogLuv format
%
%     Copyright (C) 2011  Francesco Banterle
%
%     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/>.
%

%is it a three color channels image?
check3Color(img);

%Conversion from RGB to XYZ
imgXYZ = ConvertRGBtoXYZ(img, 0);

imgLogLuv = zeros(size(img));

%Encoding luminance Y
Le = floor(256*(log2(imgXYZ(:,:,2))+64));
imgLogLuv(:,:,1) = ClampImg(Le,0,65535);

%CIE (u,v) chromaticity values
norm = (imgXYZ(:,:,1)+imgXYZ(:,:,2)+imgXYZ(:,:,3));
x = imgXYZ(:,:,1)./ norm;
y = imgXYZ(:,:,2)./ norm;

%Encoding chromaticity
norm_uv = (-2*x+12*y+3);
u_prime = 4*x./norm_uv;
v_prime = 9*y./norm_uv;

Ue = floor(410*u_prime);
imgLogLuv(:,:,2) = ClampImg(Ue,0,255);

Ve = floor(410*v_prime);
imgLogLuv(:,:,3) = ClampImg(Ve,0,255);

end


%%***************************************************
%% min sum_k bk*yk
%% s.t. sum yk*Hk  <= 0
%%      y1 = 1
%% Hk = -hankel(ek) if   1 <= k <= n
%%    = -hankel(0,e(k-n+1)) if n+1 <= k <=2*n-1
%%
%% [blk,At,C,b] = sdphankel(n);
%%***************************************************

   function [blk,At,C,b] = sdphankel(n);

   randn('seed',0);
   tmp = randn(n,n);
   tmp = tmp+tmp';
   X{1} = tmp + norm(tmp,'fro')*speye(n,n);
%%
   for k = 1:n
      ek = zeros(n,1); ek(k) = -1;
      AA{k} = sparse(hankel(ek));
   end
   zz = zeros(n,1);
   for k = n+1:2*n-1
      ek = zeros(n,1); ek(k-n+1) = -1;
      AA{k} = sparse(hankel(zz,ek));
   end
   blk{1,1} = 's'; blk{1,2} = n;
   At = svec(blk,AA,1);
   C{1} = spconvert([n n 0]);
   b = AXfun(blk,At,[],X);
%%
   blk{2,1} = 'u'; blk{2,2} = 1;
   ee = zeros(1,2*n-1); ee(1) = 1;
   At{2,1} = ee;
   C{2,1} = 1;
%%***************************************************


% Compute the per-pixel perceptual energy over each window

function F = WinAvgPE(img, R)

    ff = fft2(img);
    ffc = fftshift(ff);

    [m, n]=size(img);
    [u,v]=freqspace([m,n],'meshgrid');
%     u = u/2*m; v = v/2*n;
%     u = u/m*R; v = v/n*R;
    u = u/2*R; v = v/2*R;
    r=sqrt(u.^2+v.^2);
    fw = MannosSkarision(r);

    affc = abs(ffc(:));
    energ = sqrt(sum(affc.*affc));
    F = abs(ffc.*fw);

    F = sqrt(sum(F(:).*F(:)))/(m*n);
end

%%
function fc = MannosSkarision(r)
    fc = 2.6*(0.0192+0.114*r).*exp(-(0.114*r).^1.1);
end


function [o, p, k] = R2opk(R)

% % phi --------------------------------------------------------------------------
%
% try
%
%     p = asing( R(1,3));
%     p = ang0400(p);
%
% catch
%
%     p = NaN;
%
% end
%
% % omega ------------------------------------------------------------------------
%
% try
%
%     o = asing(-R(2,3) / cosg(p));
%
% catch
%
%     o = NaN;
%
% end
%
% % kappa ------------------------------------------------------------------------
%
% try
%
%     k1_1 = asing(-R(1,2) / cosg(p)); % pos or neg
%
%     if k1_1 >= 0, k1_2 = ang0400(200 - k1_1);      end
%     if k1_1 <  0, k1_2 = ang0400(200 + abs(k1_1)); end
%
%     k1_1 = ang0400(k1_1); % always pos
%
%     k2_1 = acosg(R(1,1) / cosg(p)); % always pos
%     k2_2 = ang0400(-k2_1);
%
%     if abs(k1_1 - k2_1) < 1, k = mean([k1_1 k2_1]); end
%     if abs(k1_1 - k2_2) < 1, k = mean([k1_1 k2_2]); end
%     if abs(k1_2 - k2_1) < 1, k = mean([k1_2 k2_1]); end
%     if abs(k1_2 - k2_2) < 1, k = mean([k1_2 k2_2]); end
%
%     if ~exist('k'), k = NaN; end
%
% catch
%
%     k = NaN;
%
% end

% From omphika.m
o = atan2(-R(2,3), R(3,3)) * 200/pi;
p = asin(R(1,3))           * 200/pi;
k = atan2(-R(1,2), R(1,1)) * 200/pi;

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Example code for estimating the HRF using the Inverse-Logit Model, a
% Finte Impluse Response Model and the Canonical HRF with 2 derivatives.
% Also the code illustrates our code for detecting model misspecification.
%
% This example illustrates the multi-stimulus version
%
% By Martin Lindquist
% Created: 05/26/10
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Load time course
%

mypath = which('ilogit');
if isempty(mypath), error('Cannot find directory with ilogit.m and other functions. Not on path?'); end
[mydir] = fileparts(mypath)

h = spm_hrf(1);
h = h./max(h);

RunA = zeros(60,10);
RunA(1,:) = 1;
RunA = reshape(RunA,600,1);
RunB = zeros(60,10);
RunB(31,:) = 1;
RunB = reshape(RunB,600,1);

tc = 2*conv(RunA,h) + conv(RunB,h);
tc = tc(1:600);
tc = tc+normrnd(0,1,600,1);

Run =[];
Run{1} = RunA;
Run{2} = RunB;

len = length(tc);

figure; subplot(3,1,1); han = plot(tc);
title('Sample time course'); drawnow

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Settings
%

TR = 1;
T = round(30/TR);
t = 1:T;                        % samples at which to get Logit HRF Estimate
FWHM = 4;                       % FWHM for residual scan
pval = 0.01;
df = 600;
alpha = 0.001;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Create stick function (sample event onsets)
% Variable R contains onset times
% Variable Run contains stick (a.k.a. delta or indicator) function

RA = [1 61 121 181 241 301 361 421 481 541];
RB = [31 91 151 211 271 331 391 451 511 571];

try
    hold on;
    hh = plot_onsets(RA,'k',-3,1);
    hh = plot_onsets(RB,'r',-3,0.5);
    drawnow
catch
    disp('Couldn''t find function to add onset sticks to plot. Skipping.')
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fit HRF using IL-function

% Choose mode (deterministic/stochastic)

mode = 0;   % 0 - deterministic aproach
            % 1 - simulated annealing approach
            % Please note that when using simulated annealing approach you
            % may need to perform some tuning before use.

[h1, fit1, e1, param] = Fit_Logit(tc,Run,t,mode);
[pv sres sres_ns1] = ResidScan(e1, FWHM);
[PowLoss1] = PowerLoss(e1, fit1, (len-7) , tc, TR, Run, alpha);

hold on; han(2) = plot(fit1,'r');

disp('Summary: IL_function');

disp('HRF - Event A');
disp('Amplitude:'); disp(param(1,1));
disp('Time-to-peak:'); disp(param(2,1));
disp('Width:'); disp(param(3,1));

disp('HRF - Event B');
disp('Amplitude:'); disp(param(1,2));
disp('Time-to-peak:'); disp(param(2,2));
disp('Width:'); disp(param(3,2));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fit HRF using FIR-model

% Choose mode (FIR/sFIR)

mode = 1;   % 0 - FIR
            % 1 - smooth FIR

[h2, fit2, e2, param] = Fit_sFIR(tc,TR,Run,T,mode);
[pv sres sres_ns2] = ResidScan(e2, FWHM);
[PowLoss2] = PowerLoss(e2, fit2, (len-T) , tc, TR, Run, alpha);

hold on; han(3) = plot(fit2,'g');

disp('Summary: FIR');

disp('HRF - Event A');
disp('Amplitude:'); disp(param(1,1));
disp('Time-to-peak:'); disp(param(2,1));
disp('Width:'); disp(param(3,1));

disp('HRF - Event B');
disp('Amplitude:'); disp(param(1,2));
disp('Time-to-peak:'); disp(param(2,2));
disp('Width:'); disp(param(3,2));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fit HRF using Canonical HRF + 2 derivatives

p=1;

[h3, fit3, e3, param, info] = Fit_Canonical_HRF(tc,TR,Run,T,p);
[pv sres sres_ns3] = ResidScan(e3, FWHM);
[PowLoss3] = PowerLoss(e3, fit3, (len-p) , tc, TR, Run, alpha);

hold on; han(4) = plot(fit3,'m');

legend(han,{'Data' 'IL' 'sFIR' 'DD'})

disp('Summary: Canonical + 2 derivatives');

disp('HRF - Event A');
disp('Amplitude:'); disp(param(1,1));
disp('Time-to-peak:'); disp(param(2,1));
disp('Width:'); disp(param(3,1));

disp('HRF - Event B');
disp('Amplitude:'); disp(param(1,2));
disp('Time-to-peak:'); disp(param(2,2));
disp('Width:'); disp(param(3,2));

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

%figure;

subplot(3,2,5);
han2 = plot(h1(:,1),'r');
hold on; han2(2) = plot(h2(:,1),'g');
hold on; han2(3) = plot(h3(:,1),'m');
legend(han2,{'IL' 'sFIR' 'DD'})
title('Estimated HRF - Event A');

subplot(3,1,2); hold on;
hh = plot_onsets(RA,'k',-3,1);
hh = plot_onsets(RB,'r',-3,0.5);
drawnow

han3 = plot(sres_ns1,'r');
hold on; han3(2) = plot(sres_ns2,'g');
hold on; han3(3) = plot(sres_ns3,'m');
hold on; plot((1:len),zeros(len,1),'--k');
legend(han3,{'IL' 'sFIR' 'DD'})
title('Mis-modeling (time course)');

subplot(3,2,6); hold on;

han4 = plot(h2(:,1),'r');
hold on; han4(2) = plot(h2(:,2),'g');
hold on; han4(3) = plot(h3(:,2),'m');
legend(han4,{'IL' 'sFIR' 'DD'})
title('Estimated HRF - Event A');


function [Dr] = Dmatrix1D(N,r,V)

% function [Dr] = Dmatrix1D(N,r,V)
% Purpose : Initialize the (r) differentiation matrices on the interval,
%	        evaluated at (r) at order N

Vr = GradVandermonde1D(N, r);
Dr = Vr/V;
return


function d =  generate(a)

x=randn(a.l,length(a.mean));
n=length(a.mean);

if size(a.cov,2)==1
  cov=eye(n)*a.cov;   %% make cov matrix with only diagonal elems (all same)
end;
if size(a.cov,1)==1
  cov=diag(a.cov);   %% make cov matrix with only diagonal elems (different)
end

for i=1:a.l
  if length(a.cov)==1
    x(i,:)= (x(i,:)*sqrt(a.cov)) + a.mean; continue;
  else
    if size(a.cov,1)==1
      x(i,:)= (x(i,:).* sqrt(a.cov)) + a.mean; continue;
    else
      x(i,:)= x(i,:) * a.cov^0.5 + a.mean;
    end
  end
end

d=data(['gauss' ' l=' num2str(a.l)],x,[]);


% change in angle to closest point on wall in fly's coordinate system
function [data,units] = compute_dangle2closestroi2(trx,n)

flies = trx.exp2flies{n};
nflies = numel(flies);
data = cell(1,nflies);
for i = 1:nflies,
  fly = flies(i);
  % set sign so that negative means going toward 0, positive means going
  % away from 0
  if trx(fly).nframes <= 1,
    data{i} = [];
  else
    data{i} = sign(trx(fly).angle2closestroi2(1:end-1)).*...
      modrange(diff(trx(fly).angle2closestroi2,1,2),-pi,pi)./trx(fly).dt;
  end
end
units = parseunits('rad/s');


function [ n_data, n, x, fx ] = t_polynomial_values ( n_data )

%*****************************************************************************80
%
%% T_POLYNOMIAL_VALUES returns values of the Chebyshev polynomial T(n,x).
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    26 May 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Milton Abramowitz and Irene Stegun,
%    Handbook of Mathematical Functions,
%    US Department of Commerce, 1964.
%
%  Parameters:
%
%    Input, integer N_DATA, indicates the index of the previous test data
%    returned, or is 0 if this is the first call.  For repeated calls,
%    set the input value of N_DATA to the output value of N_DATA
%    from the previous call.
%
%    Output, integer N_DATA, the index of the test data.
%
%    Output, integer N, the order of the function.
%
%    Output, real X, the point where the function is evaluated.
%
%    Output, real FX, the value of the function.
%
  n_max = 13;
  fx_vec = [ ...
     1.0000000000E+00,  0.8000000000E+00,  0.2800000000E+00, ...
    -0.3520000000E+00, -0.8432000000E+00, -0.9971200000E+00, ...
    -0.7521920000E+00, -0.2063872000E+00,  0.4219724800E+00, ...
     0.8815431680E+00,  0.9884965888E+00,  0.7000513741E+00, ...
     0.1315856097E+00 ];
  n_vec = [ ...
     0,  1,  2, ...
     3,  4,  5, ...
     6,  7,  8, ...
     9, 10, 11, ...
    12 ];
  x_vec = [ ...
    0.8E+00,  0.8E+00,  0.8E+00, ...
    0.8E+00,  0.8E+00,  0.8E+00, ...
    0.8E+00,  0.8E+00,  0.8E+00, ...
    0.8E+00,  0.8E+00,  0.8E+00, ...
    0.8E+00 ];

  if ( n_data < 0 )
    n_data = 0;
  end

  n_data = n_data + 1;

  if ( n_max < n_data )
    n_data = 0;
    n = 0;
    x = 0.0E+00;
    fx = 0.0E+00;
  else
    n = n_vec(n_data);
    x = x_vec(n_data);
    fx = fx_vec(n_data);
  end

  return
end


%POINTS2D_DEMO  One-line description here, please.
%
%   output = points2d_demo(input)
%
%   Example
%   points2d_demo
%
%   See also
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2020-01-08,    using Matlab 9.7.0.1247435 (R2019b) Update 2
% Copyright 2020 INRA - Cepia Software Platform.

%% generate data

rng(42);
pts = randn([100 2]) * 15 + 50;

figure; hold on; axis([0 100 0 100]);
drawPoint(pts, 'k+');
print(gcf, 'points2d.png', '-dpng');

centPts = centroid(pts);

%% bounding box

bbox = boundingBox(pts);

figure; hold on; axis([0 100 0 100]);
drawPoint(pts, 'k+');
drawBox(bbox, 'color', 'b', 'linewidth', 2);
print(gcf, 'points2d_bbox.png', '-dpng');

%% equivalent ellipse

elli = equivalentEllipse(pts);

figure; hold on; axis([0 100 0 100]);
drawPoint(pts, 'k+');
drawEllipse(elli, 'color', 'b', 'linewidth', 2);
print(gcf, 'points2d_ellipse.png', '-dpng');

%% equivalent ellipse

hull = convexHull(pts);

figure; hold on; axis([0 100 0 100]);
drawPoint(pts, 'k+');
drawPolygon(hull, 'color', 'b', 'linewidth', 2);
print(gcf, 'points2d_hull.png', '-dpng');

%% everything together

figure; hold on; axis([0 100 0 100]);
hp = drawPoint(pts, 'color', 'k', 'marker', 'o', 'linewidth', 2);
hc = drawPoint(centPts, 'color', 'b', 'marker', '*', 'linewidth', 2, 'MarkerSize', 10);
hb = drawBox(bbox, 'color', [0 0 .7], 'linewidth', 2);
he = drawEllipse(elli, 'color', [.7 0 0], 'linewidth', 2);
hh = drawPolygon(hull, 'color', [0 .7 0], 'linewidth', 2);
legend({'Points', 'Centroid', 'BoundingBox', 'Equiv. Ellipse', 'Conv. Hull'}, 'Location', 'NorthEast');
print(gcf, 'points2d_demo.png', '-dpng');


function k = outerProd(f, g, h)
%OUTERPRODUCT    The outer product of three CHEBFUN objects.
%
% This should be moved to chebfun/outerProduct

%   K = OUTERPRODUCT(F, G, H) returns the CHEBFUN3 representing
%   H(x,y) = F(x)G(y)H(z),
%   where F, G and H are three CHEBFUN objects.

% TODO: This command could use a compression-like algorithm, but instead
%   here we are just concatenating cols, rows and tubes.

% Empty check:
if ( isempty(f) || isempty(g) || isempty(h) )
    k = chebfun3();
    return
end

% Check they are all chebfun objects
if ( ~isa(f, 'chebfun') || ~isa(g, 'chebfun') || ~isa(h, 'chebfun'))
   error('CHEBFUN:CHEBFUN3:outerProd:badInputs', ...
       'Outer product must involve three chebfun objects.');
end

% Extract out information:
fdom = domain(f);
gdom = domain(g);
hdom = domain(h);
dom = [fdom, gdom, hdom];

k = chebfun3();
% Form outerproduct:
if ( size(f, 2) == size(g, 2) && size(f, 2) == size(h, 2) )
    k.cols = f;
    k.rows = g;
    k.tubes = h;
    k.core = zeros(size(f, 2), size(g, 2), size(h, 2));
    for i=1:size(f, 2)
        k.core(i,i,i) = 1;
    end
    k.domain = dom;
else
    error('CHEBFUN:CHEBFUN3:outerProd:sizes', ...
        'Sizes not consistent for outer product.');
end

end


function C3 = C3f(epsi, C3x)
%C3F  Evaluate C_3
%
%   C3 = C3F(EPSI, C3X) evaluates C_{3,l} using Eq. (25) and the
%   coefficient vector C3X.  EPSI is a K x 1 array.  C3X is a 1 x 15 array.
%   C3 is a K x 5 array.

  nC3 = 6;
  nC3x = size(C3x, 2);
  j = nC3x;
  C3 = zeros(length(epsi), nC3 - 1);
  for k = nC3 - 1 : -1 : 1
    t = C3(:, k);
    for i = nC3 - k : -1 : 1
      t = epsi .* t + C3x(j);
      j = j - 1;
    end
    C3(:, k) = t;
  end
  mult = ones(length(epsi), 1);
  for k = 1 : nC3 - 1
    mult = mult .* epsi;
    C3(:, k) = C3(:, k) .* mult;
  end
end


function [textures] = getNGTDMtextures(NGTDM,countValid)
% -------------------------------------------------------------------------
% function [textures] = getNGTDMtextures(NGTDM,countValid)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function computes texture features from an input Neighborhood
% Gray-Tone Difference Matrix (NGTDM).
% -------------------------------------------------------------------------
% REFERENCE:
% [1] Amadasun, M., & King, R. (1989). Textural Features Corresponding to
%     Textural Properties. IEEE Transactions on Systems Man and Cybernetics,
%     19(5), 1264–1274.
% -------------------------------------------------------------------------
% INPUTS:
% - NGTDM: Neighborhood Gray-Tone Difference Matrix.
% - countValid: Number of valid voxels used in the NGTDM computation.
%               Required for the computation of texture features in
%               'getNGTDMtextures.m'
%
% ** 'NGTDM' and 'countValid' should be outputs from 'getNGTDM.m' **
% -------------------------------------------------------------------------
% OUTPUTS:
% - textures: Struture specifying the values of different NGTDM texture
%             features as defined below.
% -------------------------------------------------------------------------
% AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: January 2013
% - Revision: May 2015
% -------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015  Martin Vallieres
%
%    This package 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 package 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 package.  If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------

% PRELIMINARY
nTot = sum(countValid);
countValid = countValid./nTot; % Now representing the probability of gray-level occurences
NL = length(NGTDM);
Ng = sum(countValid~=0);
pValid = find(countValid>0);
nValid = length(pValid);

% COMPUTATION OF TEXTURES
% 1. Coarseness, Ref.[1]
textures.Coarseness = (((countValid')*NGTDM) + eps)^(-1);

% 2. Contrast, Ref.[1]
val = 0;
for i = 1:NL
    for j = 1:NL
        val = val + countValid(i)*countValid(j)*(i-j)^2;
    end
end
textures.Contrast = val*sum(NGTDM)/(Ng*(Ng-1)*nTot);

% 3. Busyness, Ref.[1]
denom = 0;
for i = 1:nValid
    for j = 1:nValid
        denom = denom + abs(pValid(i)*countValid(pValid(i))-pValid(j)*countValid(pValid(j)));
    end
end
textures.Busyness = ((countValid')*NGTDM)/denom;

% 4. Complexity, Ref.[1]
val = 0;
for i = 1:nValid
    for j = 1:nValid
        val = val + (abs(pValid(i)-pValid(j))/(nTot*(countValid(pValid(i)) + countValid(pValid(j)))))*(countValid(pValid(i))*NGTDM(pValid(i)) + countValid(pValid(j))*NGTDM(pValid(j)));
    end
end
textures.Complexity = val;

% 5. Strength, Ref.[1]
val = 0;
for i = 1:nValid
    for j = 1:nValid
        val = val + (countValid(pValid(i))+countValid(pValid(j)))*(pValid(i)-pValid(j))^2;
    end
end
textures.Strength = val/(eps+sum(NGTDM));

end


function [Nv, VX, K, EToV] = MeshGenDistMesh1D()

% function [VX, K, EToV] = MeshGenDistMesh1D()
% Purpose  : Generate 1D mesh using DistMesh;

% distance function for a circle about xc=0
fd=inline('abs(p)-1','p');

% distribution weight function
fh=inline('abs(p)*0.075+0.0125','p');

% generate non-uniform example mesh in 1D using DistMesh
h0 = 0.025;            % chosen element spacing
[p,t]=distmeshnd(fd,fh,h0,[-1;1],[]);
K = size(t,1); Nv = K+1;

% Sort elements in acending order
[x,i]=sort(p(t));
t=t(i,:);
Met=sort(t','ascend')';
EToV = t; VX = p(:,1);
return


% normalize a vector
function result = norma(v)
    result = v / norm(v);
end


% ITK_PSTRANSFORM: Spatial transformation (i.e. warp) of a set of points,
% defined from a known landmark correspondence
%
% This MEX-function provides a Matlab interface to run ITK's Kernel
% and B-spline transforms:
%
%   itk::ElasticBodySplineKernelTransform
%   itk::ElasticBodyReciprocalSplineKernelTransform
%   itk::ThinPlateSplineKernelTransform
%   itk::ThinPlateR2LogRSplineKernelTransform
%   itk::VolumeSplineKernelTransform
%   itk::BSplineScatteredDataPointSetToImageFilter
%
%
% YI = itk_pstransform(TRANSFORM, X, Y, XI)
%
%   X, Y are 2-column (2D) or 3-column (3D) matrices. Each row has
%   the coordinates of a point. The warp is defined so that
%   X(i,:)->Y(i,:).
%
%   XI is a matrix with the same number of columns as X, Y. Each row
%   has the coordinates of a point to be warped.
%
%   YI has the same dimensions as XI. YI contains the coordinates of
%   the warped points.
%
%   TRANSFORM is a string that allows to select the type of warp (no
%   defaults):
%
% YI = itk_pstransform('elastic', X, Y, XI)
% YI = itk_pstransform('elasticr', X, Y, XI)
% YI = itk_pstransform('tps', X, Y, XI)
% YI = itk_pstransform('tpsr2', X, Y, XI)
% YI = itk_pstransform('volume', X, Y, XI)
%
%   'elastic':  itk::ElasticBodySplineKernelTransform
%   'elasticr': itk::ElasticBodyReciprocalSplineKernelTransform
%   'tps':      itk::ThinPlateSplineKernelTransform
%   'tpsr2':    itk::ThinPlateR2LogRSplineKernelTransform
%   'volume':   itk::VolumeSplineKernelTransform
%
%   Note that 'tpsr2' produces the same result as our Matlab implementation
%   pts_tps_map(), as it implements the classic kernel proposed by
%   Bookstein, r^2 ln(r^2).
%
% YI = itk_pstransform('bspline', X, Y, XI, ORDER, LEVELS)
%
%   'bspline':  itk::BSplineScatteredDataPointSetToImageFilter
%
%   By Nicholas J. Tustison, James C. Gee in the Insight Journal
%   paper: http://hdl.handle.net/1926/140
%
%   ORDER is an integer with the B-spline order. By default, ORDER=3,
%   and the B-spline is cubic.
%
%   LEVELS is an integer with the number of multi-resolution levels
%   in the algorithm. A higher number of levels will make the spline
%   more flexible and match the landmarks better. By default, LEVELS=5.
%
% See also: pts_tps_map, pts_tps_weights.

% Author: Ramon Casero <rcasero@gmail.com>
% Copyright © 2011 University of Oxford
% Version: 0.1.1
%
% University of Oxford means the Chancellor, Masters and Scholars of
% the University of Oxford, having an administrative office at
% Wellington Square, Oxford OX1 2JD, UK.
%
% This file is part of Gerardus.
%
% 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. The offer of this
% program under the terms of the License is subject to the License
% being interpreted in accordance with English Law and subject to any
% action against the University of Oxford being under the jurisdiction
% of the English Courts.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see
% <http://www.gnu.org/licenses/>.

error('MEX file not found')


% Local Regression and Likelihood, Figure 11.4.
% Author: Catherine Loader
%
% Local Adaptive Smooth - Dopler example.
%
% NEED: Improve plot - curve is hard to see.

x = (0:2047)'/2047;
m = 20*sqrt(x.*(1-x)) .* sin(2*pi*1.05 ./ (x+0.05));
y = m + normrnd(0,1,2048,1);
fit = locfit(x,y,'pen',4,'acri','cp','maxk',500);
figure('Name','fig11_4: local adaptive smooth: dopler example');
lfplot(fit,'red');


function [ vX ] = SolveL1NormSetMinimization( mY )
% ----------------------------------------------------------------------------------------------- %
% [ vX, mX ] = SolveLsBoxConstraints( mA, vB, vC, vD, vX, numIterations, stopTol )
%   Solves \arg \min_{x} 0.5 || A x - b ||, s.t. c <= x <= d using
%   Gradient Descent Method.
% Input:
%   - mA            -   Model Matrix.
%                       Input model matrix.
%                       Structure: Matrix (m x n).
%                       Type: 'Single' / 'Double'.
%                       Range: (-inf, inf).
% Output:
%   - vX            -   Solution Vector.
%                       The solution to the optimization problem..
%                       Structure: Vector (m x 1).
%                       Type: 'Single' / 'Double'.
%                       Range: (-inf, inf).
% References
%   1.  A
% Remarks:
%   1.  B
% TODO:
%   1.  C
% Release Notes:
%   -   1.0.000     02/03/2020  Royi Avital
%       *   First release version.
% ----------------------------------------------------------------------------------------------- %

FALSE   = 0;
TRUE    = 1;

OFF     = 0;
ON      = 1;

vecDim      = size(mY, 1);
numSamples  = size(mY, 2);

% vX = [vX; vT]
numElements = vecDim * numSamples;

% Summing over all {t}_{ij}
vF = [zeros(vecDim, 1); ones(numElements, 1)];

% Building the matrix where we run on {x}_{i}, {t}_{i, j}, {y}_{i, j} in
% column wise manner. Where i is the element index and j is the sample
% index.
mA = [repmat(speye(vecDim), numSamples, 1), -speye(numSamples * vecDim); repmat(-speye(vecDim), numSamples, 1), -speye(numSamples * vecDim)];
vB = [mY(:); -mY(:)];

sSolverOptions = optimoptions('linprog', 'Display', 'off');
vX = linprog(vF, mA, vB, [], [], [], [], sSolverOptions);
vX = vX(1:vecDim);

end


function y = noise(varargin)
%  NOISE    Adds noise to an image.
%
%     NOISE creates a new image by adding noise to the original image.
%     NOISE can be used to any matrix (1D, 2D, 3D, nD)
%
%     Noisetypes are:
%       'ag' : additive gaussian (default)    'au' : additive uniform
%       'mg' : multiplicative gaussian        'mu' : multiplicative uniform
%       'sp' : salt and pepper
%
%     Additive noise sums an random value to the image value at each pixel,
%     Multiplicative noise replaces a pixel value with an random value,
%     Salt and Pepper noise replaces a pixel value with the maximum or minimum possible values.
%
%     For 'ag' noisetype use:  y = NOISE(x,'ag', variance, [incidence])
%       where 'variance' is the variance of the gaussian noise added and the optional parameter
%       'incidence' is the percetual of pixels affected be the noise (default for additive noise=1).
%       For a 50% incidence use 'incidence' = .5 and so on.
%
%     For 'au' noisetype use :  y = NOISE(x,'au', maximum, [incidence])
%       where 'maximum' is the maximum value the uniform noise can achieve
%
%     For 'mg' noisetype use :  y = NOISE(x,'mg', incidence)
%     For 'mu' noisetype use :  y = NOISE(x,'mu', incidence)
%       Multiplicative noisetypes require that the 'incidence' parameter. For this kind of noise
%       the variance or the maximum (respectivelly for gaussian and uniform noisetypes) are allways
%       set to the maximum image value.
%
%     For 'sp' noisetype use :  y = NOISE(x,'sp', incidence)
%
%     The 'maximum' and 'variance' parameters can be set as percentual of the maximum - minimum image
%     values by using these values as strings containg the percentual rate followed by the percent symbol.
%     The 'incidence' can also be expressed as a pecentual in this same way
%
%     Example:  y = NOISE(x,'ag', '25%')
%               y = NOISE(x,'mu', 10, .5) -> same as y = NOISE(x,'mu',10, '50%')
%

[u, noisetype,  scale, incid] = parse_inputs(varargin{:});

if ~isa(u,'double')
   u = double(u);
end

y = u;

n = zeros(size(u));
if incid == 1
   m_incid = logical(ones(size(u)));
else
   m_incid = rand(size(u));
   m_incid = find(m_incid <= incid);
end

if strcmp(noisetype, 'ag')
   n(m_incid) = scale*randn(size(m_incid));
   y = u + n;

elseif strcmp(noisetype, 'au')
   n(m_incid) = scale*rand(size(m_incid));
   y = u + n;

elseif strcmp(noisetype, 'mg')
   n(m_incid) = scale*randn(size(m_incid));
   y(m_incid) = n(m_incid);

elseif strcmp(noisetype, 'mu')
   n(m_incid) = scale*rand(size(m_incid));
   y(m_incid) = n(m_incid);

elseif strcmp(noisetype, 'sp')
   n(m_incid) = sign(randn(size(m_incid)));
   umax = max(u(:));
   umin = min(u(:));
   salt = find(n==-1);
   pepper = find(n==1);
   y(salt) = umax;
   y(pepper) = umin;
end

function [u, noisetype, scale, incid] = parse_inputs(varargin)
switch nargin
case 0
   error('Too few inputs')

case 1
   u = varargin{1};
   noisetype = 'ag';
   scale = double(max(u(:)));
   incid = 1;

case 2
   u = varargin{1};
   if strmatch(varargin{2},['ag';'au'])
      noisetype = varargin{2};
      scale = double(max(u(:)));
      incid = 1;
   elseif strmatch(varargin{2},['mg'; 'mu'; 'sp'])
      error('Incidence missing');
   else
      noisetype = 'ag';
      scale = varargin{2};
      incid = 1;
   end

case 3
   u = varargin{1};
   if strmatch(varargin{2},['ag';'au'])
      noisetype = varargin{2};
      scale = varargin{3};
      incid = 1;
   elseif strmatch(varargin{2},['mg'; 'mu'; 'sp'])
      noisetype = varargin{2};
      scale = double(max(u(:)));
      incid = varargin{3};
   else
      noisetype = 'ag';
      scale = varargin{2};
      incid = varargin{3};
   end

case 4
   u = varargin{1};
   if strmatch(varargin{2},['ag';'au'])
      noisetype = varargin{2};
      scale = varargin{3};
      incid = varargin{4};
   else
      error('Too many parameters')
   end

otherwise
   error('Too many parameters')
end

if findstr(scale,'%')
   scale = ( double(max(u(:))) - double(min(u(:))) )*str2num(scale(1:end-1))/100;
end
if findstr(incid,'%')
   incid = str2num(incid(1:end-1))/100;
end


function o = boxoverlap(a, b)
% Compute the symmetric intersection over union overlap between a set of
% bounding boxes in a and a single bounding box in b.
%
% a  a matrix where each row specifies a bounding box
% b  a single bounding box

% AUTORIGHTS
% -------------------------------------------------------
% Copyright (C) 2011-2012 Ross Girshick
% Copyright (C) 2008, 2009, 2010 Pedro Felzenszwalb, Ross Girshick
%
% This file is part of the voc-releaseX code
% (http://people.cs.uchicago.edu/~rbg/latent/)
% and is available under the terms of an MIT-like license
% provided in COPYING. Please retain this notice and
% COPYING if you use this file (or a portion of it) in
% your project.
% -------------------------------------------------------

x1 = max(a(:,1), b(1));
y1 = max(a(:,2), b(2));
x2 = min(a(:,3), b(3));
y2 = min(a(:,4), b(4));

w = x2-x1+1;
h = y2-y1+1;
inter = w.*h;
aarea = (a(:,3)-a(:,1)+1) .* (a(:,4)-a(:,2)+1);
barea = (b(3)-b(1)+1) * (b(4)-b(2)+1);
% intersection over union overlap
o = inter ./ (aarea+barea-inter);
% set invalid entries to 0 overlap
o(w <= 0) = 0;
o(h <= 0) = 0;


function [cl] = l2cl(l)
% Convert volume from liters to centiliters.
% Chad Greene 2012
cl = l*100;


% test for a simple anisotropic metric
name = 'fixed-2d';
name = 'fixed-3d';
name = 'varying-2d';

rep = 'results/anisotropic-fm/';
if not(exist(rep))
    mkdir(rep);
end

% create the main direction of the field
switch name
    case 'fixed-3d' % Fixed 3D tensor field
        n = 20;
        s = [n n n]; % size
        % main direction of the tensor
        u = [1 .1 .1];
        U = repmat( reshape(u,1,1,1,3),[n n n 1] );
    case 'fixed-2d' % Fixed 2D tensor field
        n = 40;
        s = [n n 1];
        % main direction of the tensor
        u = [1 .1];
        U = repmat( reshape(u,1,1,2),[n n 1] );
    case 'varying-2d' % spacially varying 2D field
        n = 200;
        % create 2D vector field
        s = [n n 1];
        U = randn(n,n,2);
        sigma = 30;
        for it=1:10
            U = perform_vf_normalization( perform_blurring(U, sigma) );
        end

end
U = perform_vf_normalization( U );

% test for various degree of anisotropy
aniso_list = [0.01 0.05 .1 .2 .5 1];

nstart = 1;
nstart = 8;
if nstart==1
    start_points = [n/2 n/2];
else
    start_points = rand(2,nstart);
    start_points(1,:) = rescale(start_points(1,:),.1,.9);
    start_points(2,:) = rescale(start_points(2,:),.1,.9);
    start_points = round( start_points*(n-1)+1 );
end
if strcmp(name(end-1:end), '3d')
    start_points(end/2) = ceil(s(end)/2);
end

for ianiso = 1:length(aniso_list)

    aniso = aniso_list(ianiso);

    % use cross product to compute the 2 remaining orthogonal directions
    if strcmp(name(end-1:end), '2d')
        % 3D field
        V = cat(3, -U(:,:,2), U(:,:,1)); % orthogonal vector
        T = perform_tensor_recomp(U,V, ones(n),ones(n)*aniso );
    else
        % 3D field
        U = cat(5, U, randn(s(1),s(2),s(3),3,2));
        U(:,:,:,:,3) = cross( U(:,:,:,:,1),U(:,:,:,:,2), 4 );
        U(:,:,:,:,3) = perform_vf_normalization( U(:,:,:,:,3) );
        U(:,:,:,:,2) = cross( U(:,:,:,:,1),U(:,:,:,:,3), 4 );
        U(:,:,:,:,2) = perform_vf_normalization( U(:,:,:,:,2) );
        Lambda = ones(s(1),s(2),s(3),3);
        Lambda(:,:,:,2:3) = aniso;
        T = perform_tensor_decomp_3d(U,Lambda);
    end

    D = perform_fast_marching(T, start_points);

    D1 = D(:,:,ceil(s(end)/2));
    if strcmp(name(end-1:end),'3d')
        T1 = T(:,:,ceil(s(end)/2), 1:2,1:2);
    else
        T1 = T;
    end

    clf;
    imageplot(D1);
    colormap jet(256);

    clf;
    hold on;
    options.sub = round(n/15);
    options.color = 'k';
    plot_tensor_field(T1, D1, options);
    h = plot(start_points(2,:),start_points(1,:), 'r.');
    set(h, 'MarkerSize', 20);
    colormap jet(256);

    saveas(gcf, [rep name '-aniso-' num2str(ianiso) '.png'], 'png');

end


function dxdt=ideal(t,x)
% Here you define your differential equation
% dxdt=your outputs, as initialized with zero array,
dxdt=zeros(2,1);

k=0.5;
u=-k*x(1);
% the differential eq is
%   x1dot=x2;
%   x2dot=u
% which can formulized as follows for the solver
dxdt(1)=x(2);
dxdt(2)=u;


function [nodeInterface, elemInterface, nodeBg, elemBg] = get2dpolymesh(node, elem, phi)
%% GET2DPOLYMESH gets the interface fitted polygonal mesh for a 2d quadtree mesh

%% Prepare
if ~iscell(elem); elem = num2cell(elem,2); end

elemBg = elem;
nodeBg = node;
T = auxstructurepoly(elem);
edge = T.edge;
edge2elem = double(T.edge2elem);

N = size(node,1);
NT = size(elem,1);

%% compute the level set value at each vertex
%
phiValue = phi(node);
vSign = msign(phiValue);

%% Step 1: Find points ON interface
% Find the intersection points between edges and the interface
isCutEdge = (vSign(edge(:,1)).*vSign(edge(:,2))<0);
A = node(edge(isCutEdge,1),:);
B = node(edge(isCutEdge,2),:);
nodeCut = findintersectbisect(phi,A,B);
Ncut = size(nodeCut, 1);
ixCutNode = N+(1:Ncut)';
ixIntersectNode = find(abs(vSign) <= eps);
Nintersect = size(ixIntersectNode,1);
vSign(N+1:N+Ncut) = 0;
vSign(N+Ncut+1:N+Ncut+Nintersect) = 0;

%% Step 2: find interface elem and nodes
isInterfaceElem = false(NT,1);
interfaceElem = edge2elem(isCutEdge,[1,2]);
isInterfaceElem(interfaceElem) = true;
% new vertices needed to be merged into interface element
elemUpdate = accumarray(interfaceElem(:),[ixCutNode;ixCutNode], [NT,1],@(x){x'});
elem = cellfun(@horzcat, elem, elemUpdate, 'UniformOutput', false);
elemVertNum = cellfun('length',elem);

vSign2elem = mat2cell(vSign([elem{:}]),elemVertNum);
vSign2elem = cellfun(@transpose, vSign2elem, 'UniformOutput', 0);
isInterfaceElem(cellfun(@(x) sum(x==0)==2, vSign2elem)) = true; % 2 vertices on interface
ixIFElem = find(isInterfaceElem);
% elemOnInterface = elem(isInterfaceElem,:);

nodeInterface = [node; nodeCut];

%% cut polygonal element into sub elements for computation
numInterfaceElem = length(ixIFElem);
elem(NT+1:NT+numInterfaceElem) = cell(numInterfaceElem,1);

for i = 1:numInterfaceElem
   ix = ixIFElem(i);
   ixLocElem1= [find(vSign2elem{ix}==0), find(vSign2elem{ix}==1)];
   ixLocElem2 = [find(vSign2elem{ix}==0), find(vSign2elem{ix}==-1)];
%    elem{ix} = {elem{ix}(ixLocElem1); elem{ix}(ixLocElem2)};
    elem{NT+i} = elem{ix}(ixLocElem2);
    elem{ix} = elem{ix}(ixLocElem1);
end

% ixIFElemNew = [ixIFElem; ((NT+1):(NT+numInterfaceElem))'];
elemInterface = fixorientationpoly(nodeInterface,elem);

end


function [L,D] = ldldecom(Q)
%LDLDECOM: Find LtDL-decompostion of Q-matrix
%
% This routine finds the LtDL decomposition of a given variance/
% covariance matrix.
%
% Input arguments:
%    Q: Symmetric n by n matrix to be factored
%
% Output arguments:
%    L: Out - n by n factor matrix (strict lower triangular)
%    D: Out - Diagonal n-vector

% ----------------------------------------------------------------------
% File.....: ldldecom
% Date.....: 19-MAY-1999
% Author...: Peter Joosten
%            Mathematical Geodesy and Positioning
%            Delft University of Technology
% ----------------------------------------------------------------------

n = size (Q,1);

for i = n:-1:1;

   D(i) = Q(i,i);
   L(i,1:i) = Q(i,1:i)/sqrt(Q(i,i));

   for j = 1:i-1
      Q(j,1:j) = Q(j,1:j)-L(i,1:j)*L(i,j);
   end

   L(i,1:i) = L(i,1:i)/L(i,i);

end;

if (sum(D < 1E-10));

  error ('Matrix on input is not positive definite!');

end;

% ----------------------------------------------------------------------
% End of routine: ldldecom
% ----------------------------------------------------------------------


function f12=f12(x)
Bound=[-50 50];

if nargin==0
    f12 = Bound;
else
    y=1+(x+1)./4;
    a=x>10;
    b=x<-10;
    [row col]=size(x);

    y1=y(1:row-1,:);
    y2=y(2:row,:);

    usum=sum(a*.100.*((x-10)).^4)+sum(b*.100.*(x+10).^4);
    f12=(10*sin(pi*y(1,:)).^2+sum((y1-1).^2.*(1+10*sin(pi.*y2).^2))+(y(row,:)-1).^2)*(pi/30)+usum;
end


 function y = reshapee(x, varargin)
%|function y = reshapee(x, varargin)
%|
%| reshape function that allows possibly one null argument, and all
%| other arguments can be vectors, unlike matlab that requires scalars.
%| example: reshape(rand(2*3*5,7), [2 3], [], 7) will become [2 3 5 7]
%|
%| in
%|	x		[(*dim)]
%|	varargin	dimensions
%|
%| out
%|	y		[dim]
%|
%| Copyright 2004-8-22, Jeff Fessler, University of Michigan

if nargin == 1 && streq(x, 'test'), reshapee_test, return, end
if nargin < 2, ir_usage, end

dim_i = size(x);

ndim = 0;
edim = [];
dim_o = [];
for ii=1:length(varargin)
	arg = varargin{ii};
	ndim = ndim + length(arg);
	if isempty(arg)
		if ~isempty(edim)
			fail 'only one empty dim allowed'
		end
		edim = 1+length(dim_o);
		dim_o = [dim_o, 1]; % trick: place holder
	else
		dim_o = [dim_o, arg];
	end
end

if ~isempty(edim) % fill in empty dim if present
	if prod(dim_o) <= 0, fail('nonpositive dims?'), end
	dim_o(edim) = prod(dim_i) / prod(dim_o);
	if round(dim_o(edim)) ~= dim_o(edim)
		pr dim_i
		pr dim_o
		fail('bad dim')
	end
end

y = reshape(x, dim_o);

% self test
function reshapee_test
dim = [2 3 5 7];
x = 1:prod(dim);
y = reshapee(x, dim(1:2), [], dim(4));
z = reshape(x, dim);
jf_equal(y,z)