function test_inverse ( )

%*****************************************************************************80
%
%% TEST_INVERSE tests the inverse computations.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    17 April 2015
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'TEST_INVERSE\n' );
  fprintf ( 1, '  A = a test matrix of order N;\n' );
  fprintf ( 1, '  B = inverse as computed by a routine.\n' );
  fprintf ( 1, '  C = inverse as computed by Matlab''s INV function.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  ||A||    = Frobenius norm of A.\n' );
  fprintf ( 1, '  ||C||    = Frobenius norm of C.\n' );
  fprintf ( 1, '  ||I-AC|| = Frobenius norm of I-A*C.\n' );
  fprintf ( 1, '  ||I-AB|| = Frobenius norm of I-A*B.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Title                    N      ' );
  fprintf ( 1, '||A||      ||C||      ||I-AC||        ||I-AB||\n' );
  fprintf ( 1, '\n' );
%
%  AEGERTER
%
  title = 'AEGERTER';
  n = 5;
  a = aegerter ( n );
  b = aegerter_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BAB
%
  title = 'BAB';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ beta, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = bab ( n, alpha, beta );
  b = bab_inverse ( n, alpha, beta );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BAUER
%
  title = 'BAUER';
  n = 6;
  a = bauer ( );
  b = bauer_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BERNSTEIN
%
  title = 'BERNSTEIN';
  n = 5;
  a = bernstein ( n );
  b = bernstein_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BIS
%
  title = 'BIS';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ beta, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = bis ( alpha, beta, n, n );
  b = bis_inverse ( alpha, beta, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BIW
%
  title = 'BIW';
  n = 5;
  a = biw ( n );
  b = biw_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BODEWIG
%
  title = 'BODEWIG';
  n = 4;
  a = bodewig ( );
  b = bodewig_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BOOTHROYD
%
  title = 'BOOTHROYD';
  n = 5;
  a = boothroyd ( n );
  b = boothroyd_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  BORDERBAND
%
  title = 'BORDERBAND';
  n = 5;
  a = borderband ( n );
  b = borderband_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CARRY
%
  title = 'CARRY';
  n = 5;
  i4_lo = 2;
  i4_hi = 20;
  seed = 123456789;
  [ k, seed ] = i4_uniform_ab ( i4_lo, i4_hi, seed );
  a = carry ( n, k );
  b = carry_inverse ( n, k );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CAUCHY
%
  title = 'CAUCHY';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  [ y, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = cauchy ( n, x, y );
  b = cauchy_inverse ( n, x, y );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CHEBY_T
%
  title = 'CHEBY_T';
  n = 5;
  a = cheby_t ( n );
  b = cheby_t_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CHEBY_U
%
  title = 'CHEBY_U';
  n = 5;
  a = cheby_u ( n );
  b = cheby_u_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CHEBY_VAN2
%
  title = 'CHEBY_VAN2';
  n = 5;
  a = cheby_van2 ( n );
  b = cheby_van2_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CHEBY_VAN3
%
  title = 'CHEBY_VAN3';
  n = 5;
  a = cheby_van3 ( n );
  b = cheby_van3_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CHOW
%
  title = 'CHOW';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ beta, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = chow ( alpha, beta, n, n );
  b = chow_inverse ( alpha, beta, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CIRCULANT
%
  title = 'CIRCULANT';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = circulant ( n, n, x );
  b = circulant_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CIRCULANT2
%
  title = 'CIRCULANT2';
  n = 5;
  a = circulant2 ( n );
  b = circulant2_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CLEMENT1
%  N must be even.
%
  title = 'CLEMENT1';
  n = 6;
  a = clement1 ( n );
  b = clement1_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CLEMENT2
%  N must be even.
%
  title = 'CLEMENT2';
  n = 6;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n - 1, r8_lo, r8_hi, seed );
  [ y, seed ] = r8vec_uniform_ab ( n - 1, r8_lo, r8_hi, seed );
  a = clement2 ( n, x, y );
  b = clement2_inverse ( n, x, y );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  COMBIN
%
  title = 'COMBIN';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ beta, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = combin ( alpha, beta, n );
  b = combin_inverse ( alpha, beta, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  COMPANION
%
  title = 'COMPANION';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = companion ( n, x );
  b = companion_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  COMPLEX_I
%
  title = 'COMPLEX_I';
  n = 2;
  a = complex_i ( );
  b = complex_i_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CONEX1
%
  title = 'CONEX1';
  n = 4;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = conex1 ( alpha );
  b = conex1_inverse ( alpha );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CONEX2
%
  title = 'CONEX2';
  n = 3;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = conex2 ( alpha );
  b = conex2_inverse ( alpha );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CONEX3
%
  title = 'CONEX3';
  n = 5;
  a = conex3 ( n );
  b = conex3_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  CONFERENCE
%
  title = 'CONFERENCE';
  n = 6;
  a = conference ( n );
  b = conference_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DAUB2
%
  title = 'DAUB2';
  n = 4;
  a = daub2 ( n );
  b = daub2_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DAUB4
%
  title = 'DAUB4';
  n = 8;
  a = daub4 ( n );
  b = daub4_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DAUB6
%
  title = 'DAUB6';
  n = 12;
  a = daub6 ( n );
  b = daub6_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DAUB8
%
  title = 'DAUB8';
  n = 16;
  a = daub8 ( n );
  b = daub8_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DAUB10
%
  title = 'DAUB10';
  n = 20;
  a = daub10 ( n );
  b = daub10_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DAUB12
%
  title = 'DAUB12';
  n = 24;
  a = daub12 ( n );
  b = daub12_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DIAGONAL
%
  title = 'DIAGONAL';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = diagonal ( n, n, x );
  b = diagonal_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DIF1
%  N must be even.
%
  title = 'DIF1';
  n = 6;
  a = dif1 ( n, n );
  b = dif1_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DIF2
%
  title = 'DIF2';
  n = 5;
  a = dif2 ( n, n );
  b = dif2_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DORR
%
  title = 'DORR';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = dorr ( alpha, n );
  b = dorr_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  DOWNSHIFT
%
  title = 'DOWNSHIFT';
  n = 5;
  a = downshift ( n );
  b = downshift_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  EULERIAN
%
  title = 'EULERIAN';
  n = 5;
  a = eulerian ( n, n );
  b = eulerian_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  EXCHANGE
%
  title = 'EXCHANGE';
  n = 5;
  a = exchange ( n, n );
  b = exchange_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FIBONACCI2
%
  title = 'FIBONACCI2';
  n = 5;
  a = fibonacci2 ( n );
  b = fibonacci2_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FIBONACCI3
%
  title = 'FIBONACCI3';
  n = 5;
  a = fibonacci3 ( n );
  b = fibonacci3_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FIEDLER.
%  The FIEDLER_INVERSE routine assumes the X vector is sorted.
%
  title = 'FIEDLER';
  n = 7;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  x = sort ( x );
  a = fiedler ( n, n, x );
  b = fiedler_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FORSYTHE
%
  title = 'FORSYTHE';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ beta, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = forsythe ( alpha, beta, n );
  b = forsythe_inverse ( alpha, beta, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FOURIER_COSINE
%
  title = 'FOURIER_COSINE';
  n = 5;
  a = fourier_cosine ( n );
  b = fourier_cosine_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FOURIER_SINE
%
  title = 'FOURIER_SINE';
  n = 5;
  a = fourier_sine ( n );
  b = fourier_sine_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  FRANK
%
  title = 'FRANK';
  n = 5;
  a = frank ( n );
  b = frank_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  GFPP
%
  title = 'GFPP';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = gfpp ( n, alpha );
  b = gfpp_inverse ( n, alpha );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  GIVENS
%
  title = 'GIVENS';
  n = 5;
  a = givens ( n, n );
  b = givens_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  GK316
%
  title = 'GK316';
  n = 5;
  a = gk316 ( n );
  b = gk316_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  GK323
%
  title = 'GK323';
  n = 5;
  a = gk323 ( n, n );
  b = gk323_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  GK324
%
  title = 'GK324';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n - 1, r8_lo, r8_hi, seed );
  a = gk324 ( n, n, x );
  b = gk324_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HANKEL_N
%
  title = 'HANKEL_N';
  n = 6;
  a = hankel_n ( n );
  b = hankel_n_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HANOWA
%
  title = 'HANOWA';
  n = 6;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = hanowa ( alpha, n );
  b = hanowa_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HARMAN
%
  title = 'HARMAN';
  n = 8;
  a = harman ( );
  b = harman_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HARTLEY
%
  title = 'HARTLEY';
  n = 5;
  a = hartley ( n );
  b = hartley_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HELMERT
%
  title = 'HELMERT';
  n = 5;
  a = helmert ( n );
  b = helmert_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HELMERT2
%
  title = 'HELMERT2';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = helmert2 ( n, x );
  b = helmert2_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HERMITE
%
  title = 'HERMITE';
  n = 5;
  a = hermite ( n );
  b = hermite_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HERNDON
%
  title = 'HERNDON';
  n = 5;
  a = herndon ( n );
  b = herndon_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HILBERT
%
  title = 'HILBERT';
  n = 5;
  a = hilbert ( n, n );
  b = hilbert_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  HOUSEHOLDER
%
  title = 'HOUSEHOLDER';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = householder ( n, x );
  b = householder_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  IDENTITY
%
  title = 'IDENTITY';
  n = 5;
  a = identity ( n, n );
  b = identity_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  ILL3
%
  title = 'ILL3';
  n = 3;
  a = ill3 ( );
  b = ill3_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  INTEGRATION
%
  title = 'INTEGRATION';
  n = 6;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = integration ( alpha, n );
  b = integration_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  INVOL
%
  title = 'INVOL';
  n = 5;
  a = invol ( n );
  b = invol_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  JACOBI
%  N must be even.
%
  title = 'JACOBI';
  n = 6
  a = jacobi ( n, n );
  b = jacobi_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  JORDAN
%
  title = 'JORDAN';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = jordan ( n, n, alpha );
  b = jordan_inverse ( n, alpha );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  KAHAN
%
  title = 'KAHAN';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = kahan ( alpha, n, n );
  b = kahan_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  KERSHAW
%
  title = 'KERSHAW';
  n = 4;
  a = kershaw ( );
  b = kershaw_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  KERSHAWTRI
%
  title = 'KERSHAWTRI';
  n = 5;
  x_n = floor ( ( n + 1 ) / 2 );
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( x_n, r8_lo, r8_hi, seed );
  a = kershawtri ( n, x );
  b = kershawtri_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  KMS
%
  title = 'KMS';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = kms ( alpha, n, n );
  b = kms_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LAGUERRE
%
  title = 'LAGUERRE';
  n = 5;
  a = laguerre ( n );
  b = laguerre_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LEGENDRE
%
  title = 'LEGENDRE';
  n = 5;
  a = legendre ( n );
  b = legendre_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LEHMER
%
  title = 'LEHMER';
  n = 5;
  a = lehmer ( n, n );
  b = lehmer_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LESP
%
  title = 'LESP';
  n = 5;
  a = lesp ( n, n );
  b = lesp_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LIETZKE
%
  title = 'LIETZKE';
  n = 5;
  a = lietzke ( n );
  b = lietzke_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LINE_ADJ
%  N must be even.
%
  title = 'LINE_ADJ';
  n = 6;
  a = line_adj ( n );
  b = line_adj_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  LOTKIN
%
  title = 'LOTKIN';
  n = 5;
  a = lotkin ( n, n );
  b = lotkin_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  MAXIJ
%
  title = 'MAXIJ';
  n = 5;
  a = maxij ( n, n );
  b = maxij_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  MILNES
%
  title = 'MILNES';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = milnes ( n, n, x );
  b = milnes_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  MINIJ
%
  title = 'MINIJ';
  n = 5;
  a = minij ( n, n );
  b = minij_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  MOLER1
%
  title = 'MOLER1';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = moler1 ( alpha, n, n );
  b = moler1_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  MOLER3
%
  title = 'MOLER3';
  n = 5;
  a = moler3 ( n, n );
  b = moler3_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  ORTEGA
%
  title = 'ORTEGA';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ v1, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  [ v2, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  [ v3, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = ortega ( n, v1, v2, v3 );
  b = ortega_inverse ( n, v1, v2, v3 );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  ORTH_SYMM
%
  title = 'ORTH_SYMM';
  n = 5;
  a = orth_symm ( n );
  b = orth_symm_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  OTO
%
  title = 'OTO';
  n = 5;
  a = oto ( n, n );
  b = oto_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PARTER
%
  title = 'PARTER';
  n = 5;
  a = parter ( n, n );
  b = parter_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PASCAL1
%
  title = 'PASCAL1';
  n = 5;
  a = pascal1 ( n );
  b = pascal1_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PASCAL2
%
  title = 'PASCAL2';
  n = 5;
  a = pascal2 ( n );
  b = pascal2_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PASCAL3
%
  title = 'PASCAL3';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = pascal3 ( n, alpha );
  b = pascal3_inverse ( n, alpha );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PDS_RANDOM
%
  title = 'PDS_RANDOM';
  n = 5;
  key = 123456789;
  a = pds_random ( n, key );
  b = pds_random_inverse ( n, key );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PEI
%
  title = 'PEI';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = pei ( alpha, n );
  b = pei_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PERMUTATION_RANDOM
%
  title = 'PERMUTATION_RANDOM';
  n = 5;
  key = 123456789;
  a = permutation_random ( n, key );
  b = permutation_random_inverse ( n, key );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  PLU
%
  title = 'PLU';
  n = 5;
  seed = 123456789;
  for i = 1 : n
    i4_lo = i;
    i4_hi = n;
    [ j, seed ] = i4_uniform_ab ( i4_lo, i4_hi, seed );
    pivot(i) = j;
  end
  a = plu ( n, pivot );
  b = plu_inverse ( n, pivot );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RIS
%
  title = 'RIS';
  n = 5;
  a = ris ( n );
  b = ris_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RODMAN
%
  title = 'RODMAN';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = rodman ( n, n, alpha );
  b = rodman_inverse ( n, alpha );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RUTIS1
%
  title = 'RUTIS1';
  n = 4;
  a = rutis1 ( );
  b = rutis1_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RUTIS2
%
  title = 'RUTIS2';
  n = 4;
  a = rutis2 ( );
  b = rutis2_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RUTIS3
%
  title = 'RUTIS3';
  n = 4;
  a = rutis3 ( );
  b = rutis3_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RUTIS4
%
  title = 'RUTIS4';
  n = 4;
  a = rutis4 ( n );
  b = rutis4_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  RUTIS5
%
  title = 'RUTIS5';
  n = 4;
  a = rutis5 ( );
  b = rutis5_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SCHUR_BLOCK
%
  title = 'SCHUR_BLOCK';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  x_n = floor ( ( n + 1 ) / 2 );
  [ x, seed ] = r8vec_uniform_ab ( x_n, r8_lo, r8_hi, seed );
  y_n = floor ( n / 2 );
  [ y, seed ] = r8vec_uniform_ab ( y_n, r8_lo, r8_hi, seed );
  a = schur_block ( n, x, y );
  b = schur_block_inverse ( n, x, y );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SPLINE
%
  title = 'SPLINE';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n - 1, r8_lo, r8_hi, seed );
  a = spline ( n, x );
  b = spline_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  STIRLING
%
  title = 'STIRLING';
  n = 5;
  a = stirling ( n, n );
  b = stirling_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SUMMATION
%
  title = 'SUMMATION';
  n = 5;
  a = summation ( n, n );
  b = summation_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SWEET1
%
  title = 'SWEET1';
  n = 6;
  a = sweet1 ( );
  b = sweet1_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SWEET2
%
  title = 'SWEET2';
  n = 6;
  a = sweet2 ( );
  b = sweet2_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SWEET3
%
  title = 'SWEET3';
  n = 6;
  a = sweet3 ( );
  b = sweet3_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SWEET4
%
  title = 'SWEET4';
  n = 13;
  a = sweet4 ( );
  b = sweet4_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SYLVESTER_KAC
%  N must be even.
%
  title = 'SYLVESTER_KAC';
  n = 6;
  a = sylvester_kac ( n );
  b = sylvester_kac_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  SYMM_RANDOM
%
  title = 'SYMM_RANDOM';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  key = 123456789;
  a = symm_random ( n, x, key );
  b = symm_random_inverse ( n, x, key );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  TRI_UPPER
%
  title = 'TRI_UPPER';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = tri_upper ( alpha, n );
  b = tri_upper_inverse ( alpha, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  TRIS
%
  title = 'TRIS';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ beta, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  [ gamma, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = tris ( n, n, alpha, beta, gamma );
  b = tris_inverse ( n, alpha, beta, gamma );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  TRIV
%
  title = 'TRIV';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n - 1, r8_lo, r8_hi, seed );
  [ y, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  [ z, seed ] = r8vec_uniform_ab ( n - 1, r8_lo, r8_hi, seed );
  a = triv ( n, x, y, z );
  b = triv_inverse ( n, x, y, z );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  TRIW
%
  title = 'TRIW';
  n = 5;
  i4_lo = 0;
  i4_hi = n - 1;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ k, seed ] = i4_uniform_ab ( i4_lo, i4_hi, seed );
  [ alpha, seed ] = r8_uniform_ab ( r8_lo, r8_hi, seed );
  a = triw ( alpha, k, n );
  b = triw_inverse ( alpha, k, n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  UNITARY_RANDOM
%
  title = 'UNITARY_RANDOM';
  n = 5;
  key = 123456789;
  a = unitary_random ( n, key );
  b = unitary_random_inverse ( n, key );
  c = inv ( a );
  error_ab = c8mat_is_inverse ( n, a, b );
  error_ac = c8mat_is_inverse ( n, a, c );
  norma_frobenius = c8mat_norm_fro ( n, n, a );
  normc_frobenius = c8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  UPSHIFT
%
  title = 'UPSHIFT';
  n = 5;
  a = upshift ( n );
  b = upshift_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  VAND1
%
  title = 'VAND1';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = vand1 ( n, x );
  b = vand1_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  VAND2
%
  title = 'VAND2';
  n = 5;
  r8_lo = -5.0;
  r8_hi = +5.0;
  seed = 123456789;
  [ x, seed ] = r8vec_uniform_ab ( n, r8_lo, r8_hi, seed );
  a = vand2 ( n, x );
  b = vand2_inverse ( n, x );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  WILK03
%
  title = 'WILK03';
  n = 3;
  a = wilk03 ( );
  b = wilk03_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  WILK04
%
  title = 'WILK04';
  n = 4;
  a = wilk04 ( );
  b = wilk04_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  WILK05
%
  title = 'WILK05';
  n = 5;
  a = wilk05 ( );
  b = wilk05_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  WILK21
%
  title = 'WILK21';
  n = 21;
  a = wilk21 ( n );
  b = wilk21_inverse ( n );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );
%
%  WILSON
%
  title = 'WILSON';
  n = 4;
  a = wilson ( );
  b = wilson_inverse ( );
  c = inv ( a );
  error_ab = r8mat_is_inverse ( n, a, b );
  error_ac = r8mat_is_inverse ( n, a, c );
  norma_frobenius = r8mat_norm_fro ( n, n, a );
  normc_frobenius = r8mat_norm_fro ( n, n, c );
  fprintf ( 1, '  %-20s  %4d  %10.2g  %10.2g  %14g  %14g\n', ...
    title, n, norma_frobenius, normc_frobenius, error_ac, error_ab );

  return
end


function Amatrix=createDFTAmatrix(X,H);
% function Amatrix=createDFTAmatrix(X,H);
% Creates matrix of DFT-amplitudes for a signal X.
% In each column is a spectrum (1:N/2+1), row indices are time-frame indices.
% H is the analysis window. N is the frame length, 50% overlap is used.

% Turn into column vector
X=X(:);
H=H(:);
Nx=length(X);
N=length(H);
M=floor(2*Nx/N-1);
Amatrix=zeros(N/2+1,M);
for k=1:M
    index=(k-1)*N/2+1:(k+1)*N/2;
    F=abs(fft(X(index).*H'));
    Amatrix(:,k)=F(1:N/2+1);
end


% Fig. W1 Web Appendix W8    Feedback Control of Dynamic Systems, 6e
%                                 Franklin, Powell, Emami
%

clear all;
close all;

F=[0 1;0 0];
G=[0;1];
H=[1 0];
J=0;
T=1;
[Phi,Gam]=c2d(F,G,T);
j=sqrt(-1);
Pc=[.78+.18*j;.78-.18*j];
K=acker(Phi,Gam,Pc);
Pe=[.2+.2*j;.2-.2*j];
L=acker(Phi',H',Pe)';
[A,B,C,D]=dreg(Phi,Gam,H,J,K,L);
A=Phi-Gam*K-L*H;
B=L;
C=K;
D=0;
[Ac,Bc,Cc,Dc]=series(A,B,C,D,Phi,Gam,H,J);
[Acl,Bcl,Ccl,Dcl]=feedback(Ac,Bc,Cc,Dc,0,0,0,1);
tf=30;
N=tf/T+1;
td=0:1:tf;
yd=dstep(Acl,Bcl,Ccl,Dcl,1,N);
axis([0 30 0 1.5])
plot(td,yd,'-',td,yd,'*'),
xlabel('time (sec)')
ylabel('plant output  y(t)')
title('Fig. 8.20  Step response of the continuous and digital systems')
nicegrid;
hold on

% use command structure from section 7.8

Nx=[1;0];
A2=[Phi  -Gam*K;
   L*H  Phi-L*H-Gam*K];
B2=[Gam*K*Nx;Gam*K*Nx];
C2=[1 0 0 0];
D2=0;
y2=dstep(A2,B2,C2,D2,1,N);
plot(td,y2,'-',td,y2,'o')
text(6.5,.25,'o-----o-----o-----o  Command structure from Fig 7.48(b)')
text(6.5,.45,'*-----*-----*-----*  Command structure from Fig 7.15')
hold off


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% GEOMETRIC ASIAN OPTION PRICER  (RUN SCRIPT)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Descritpion: Script to Price Geometric Asian options in Levy Models using the PROJ method
% Author:      Justin Kirkby
%
% Reference:   (1) An Efficient Transform Method For Asian Option Pricing, SIAM J. Financial Math., 2016
%              (2) Efficient Option Pricing by Frame Duality with the Fast Fourier Transform.
%                  SIAM J. Financial Math (2015), Kirkby, J.L
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[folder, name, ext] = fileparts(which( mfilename('fullpath')));
cd(folder);
addpath('../RN_CHF')
addpath('../Helper_Functions')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%  Step 1) CHOOSE CONTRACT/GENERAL PARAMETERS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
call = 1;    %For call use 1 (else, its a put)
S_0  = 100;  %Initial price
W    = 100;  %Strike            %NOTE: no error handling in place for extreme values of W (increase grid if strike falls outside)
r    = 0.05;  %Interest rate
q    = 0.00;  %dividend yield
T    = 1;    %Time (in years)
M    = 52;   %Number of monitoring points

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%  Step 2) CHOOSE MODEL PARAMETERS (Levy Models)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
model = 1;   %See Models Below (e.g. model 1 is Black Scholes), and choose specific params
params = {};

if model == 1 %BSM (Black Scholes Merton)
    params.sigmaBSM = 0.15;    %CHOOSE

elseif model == 2 %CGMY
    params.C  = 0.02;
    params.G  = 5;
    params.MM = 15;
    params.Y  = 1.2;

elseif model == 3 %NIG
    params.alpha = 15;
    params.beta  = -5;
    params.delta = 0.5;

elseif model == 4 %MJD (Merton Jump Diffusion)
    params.sigma  = 0.12;
    params.lam    = 0.4;
    params.muj    = -0.12;
    params.sigmaj = 0.18;

elseif model == 5 %Kou Double Expo
    params.sigma = 0.15;
    params.lam   = 3;
    params.p_up  = 0.2;
    params.eta1  = 25;
    params.eta2  = 10;

elseif model == 8 % Variance Gamma
    params.sigma = 0.2;
    params.nu = 0.85;
    params.theta = 0;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%  Step 3) CHOOSE PROJ PARAMETERS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
UseCumulant = 1;  %Set to 1 to use the cumulant base rule (Approach 1) to determine gridwidth, else used fixed witdth (Approach 2)

%---------------------
% APPROACH 1: Cumulant Based approach for grid width
% (see "Robust Option Pricing with Characteritics Functions and the BSpline Order of Density Projection")
%---------------------
if UseCumulant ==1  %With cumulant based rule, choose N and Alpha (N = 2^(P+Pbar) based on second approach)
    logN  = 8;   %Uses N = 2^logN  gridpoint
    L1 = 10;  % determines grid witdth (usually set L1 = 8 to 15 for Levy)
%---------------------
% APPROACH 2: Manual GridWidth approach
%---------------------
else %Manually specify resolution and Pbar
    P     = 6;  % resolution is 2^P
    Pbar  = 3;  % Determines density truncation grid with, 2^Pbar
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% PRICE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%  Note: rnCHF is the risk netural CHF, c1,c2,c4 are the cumulants
dt = T/M;
modelInput = getModelInput(model, dt, r, q, params);

if UseCumulant ==1  % Choose density truncation width based on cumulants
    alpha = getTruncationAlpha(T, L1, modelInput, model);
else    % Manually supply density truncation width above
    logN = P + Pbar;
    alpha = 2^Pbar/2;
end
N = 2^logN;    % grid roughly centered on [c1 - alph, c1 + alph]

tic
price = PROJ_Geometric_Asian(N, alpha, S_0, M, W, call, T, r, q, modelInput.rnSYMB);
toc

fprintf('Geometric Price: %.8f \n', price)

compare_arithmetic = 1;

if compare_arithmetic
    addpath('../Asian_Options')
    price_arith = PROJ_Asian( N,alpha,S_0,M,W,call,T,r,q, modelInput.rnCHF, modelInput.RNmu*dt);
    fprintf('Arithmetic Price: %.8f \n', price_arith)
end


function [H] = rigidbody(f);

% RIGIDBODY creates the homogenous spatial transformation matrix
% for a 6 parameter rigid-body transformation
%
% Use as
%   [H] = rigidbody(f)
%
% The transformation vector f should contain the
%   x-shift
%   y-shift
%   z-shift
% followed by the
%   pitch (rotation around x-axis)
%   roll  (rotation around y-axis)
%   yaw   (rotation around z-axis)

% Copyright (C) 2000-2005, Robert Oostenveld
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

% $Log: rigidbody.m,v $
% Revision 1.1  2009/01/30 04:02:11  arno
% *** empty log message ***
%
% Revision 1.4  2006/04/13 10:37:38  roboos
% added a ; to the end of a line
%
% Revision 1.3  2005/08/15 08:15:32  roboos
% reimplemented the rotate function, which contained an error (the error is in the AIR technical reference)
% changed all functions to be dependent on the rotate, translate and scale function
% all functions now behave consistenly, which also means that they are not compleetly backward compatible w.r.t. the order of the rotations
%
% Revision 1.2  2004/05/19 09:57:07  roberto
% added GPL copyright statement, added CVS log item
%

% compute the homogenous transformation matrix for the translation
T = translate(f([1 2 3]));

% compute the homogenous transformation matrix for the rotation
R = rotate_new(f([4 5 6]));

% compute the homogenous transformation matrix for the combination
H = T*R;


function [embedding_layer_state, hidden_layer_state, output_layer_state] = ...
  fprop(input_batch, word_embedding_weights, embed_to_hid_weights,...
  hid_to_output_weights, hid_bias, output_bias)
% This method forward propagates through a neural network.
% Inputs:
%   input_batch: The input data as a matrix of size numwords X batchsize where,
%     numwords is the number of words, batchsize is the number of data points.
%     So, if input_batch(i, j) = k then the ith word in data point j is word
%     index k of the vocabulary.
%
%   word_embedding_weights: Word embedding as a matrix of size
%     vocab_size X numhid1, where vocab_size is the size of the vocabulary
%     numhid1 is the dimensionality of the embedding space.
%
%   embed_to_hid_weights: Weights between the word embedding layer and hidden
%     layer as a matrix of size numhid1*numwords X numhid2, numhid2 is the
%     number of hidden units.
%
%   hid_to_output_weights: Weights between the hidden layer and output softmax
%               unit as a matrix of size numhid2 X vocab_size
%
%   hid_bias: Bias of the hidden layer as a matrix of size numhid2 X 1.
%
%   output_bias: Bias of the output layer as a matrix of size vocab_size X 1.
%
% Outputs:
%   embedding_layer_state: State of units in the embedding layer as a matrix of
%     size numhid1*numwords X batchsize
%
%   hidden_layer_state: State of units in the hidden layer as a matrix of size
%     numhid2 X batchsize
%
%   output_layer_state: State of units in the output layer as a matrix of size
%     vocab_size X batchsize
%

[numwords, batchsize] = size(input_batch);
[vocab_size, numhid1] = size(word_embedding_weights);
numhid2 = size(embed_to_hid_weights, 2);

%% COMPUTE STATE OF WORD EMBEDDING LAYER.
% Look up the inputs word indices in the word_embedding_weights matrix.
embedding_layer_state = reshape(...
  word_embedding_weights(reshape(input_batch, 1, []),:)',...
  numhid1 * numwords, []);

%% COMPUTE STATE OF HIDDEN LAYER.
% Compute inputs to hidden units.
inputs_to_hidden_units = embed_to_hid_weights' * embedding_layer_state + ...
  repmat(hid_bias, 1, batchsize);

% Apply logistic activation function.
% FILL IN CODE. Replace the line below by one of the options.
hidden_layer_state = zeros(numhid2, batchsize);
% Options
% (a) hidden_layer_state = 1 ./ (1 + exp(inputs_to_hidden_units));
% (b) hidden_layer_state = 1 ./ (1 - exp(-inputs_to_hidden_units));
hidden_layer_state = 1 ./ (1 + exp(-inputs_to_hidden_units));
% (d) hidden_layer_state = -1 ./ (1 + exp(-inputs_to_hidden_units));

%% COMPUTE STATE OF OUTPUT LAYER.
% Compute inputs to softmax.
% FILL IN CODE. Replace the line below by one of the options.
inputs_to_softmax = zeros(vocab_size, batchsize);
% Options
inputs_to_softmax = hid_to_output_weights' * hidden_layer_state +  repmat(output_bias, 1, batchsize);
% (b) inputs_to_softmax = hid_to_output_weights' * hidden_layer_state +  repmat(output_bias, batchsize, 1);
% (c) inputs_to_softmax = hidden_layer_state * hid_to_output_weights' +  repmat(output_bias, 1, batchsize);
% (d) inputs_to_softmax = hid_to_output_weights * hidden_layer_state +  repmat(output_bias, batchsize, 1);

% Subtract maximum.
% Remember that adding or subtracting the same constant from each input to a
% softmax unit does not affect the outputs. Here we are subtracting maximum to
% make all inputs <= 0. This prevents overflows when computing their
% exponents.
inputs_to_softmax = inputs_to_softmax...
  - repmat(max(inputs_to_softmax), vocab_size, 1);

% Compute exp.
output_layer_state = exp(inputs_to_softmax);

% Normalize to get probability distribution.
output_layer_state = output_layer_state ./ repmat(...
  sum(output_layer_state, 1), vocab_size, 1);


function checkdiff(problem, x, d)
% Checks the consistency of the cost function and directional derivatives.
%
% function checkdiff(problem)
% function checkdiff(problem, x)
% function checkdiff(problem, x, d)
%
% checkdiff performs a numerical test to check that the directional
% derivatives defined in the problem structure agree up to first order with
% the cost function at some point x, along some direction d. The test is
% based on a truncated Taylor series (see online Manopt documentation).
%
% Both x and d are optional and will be sampled at random if omitted.
%
% See also: checkgradient checkhessian

% This file is part of Manopt: www.manopt.org.
% Original author: Nicolas Boumal, Dec. 30, 2012.
% Contributors:
% Change log:
%
%   April 3, 2015 (NB):
%       Works with the new StoreDB class system.

    % Verify that the problem description is sufficient.
    if ~canGetCost(problem)
        error('It seems no cost was provided.');
    end
    if ~canGetDirectionalDerivative(problem)
        error('It seems no directional derivatives were provided.');
    end

    x_isprovided = exist('x', 'var') && ~isempty(x);
    d_isprovided = exist('d', 'var') && ~isempty(d);

    if ~x_isprovided && d_isprovided
        error('If d is provided, x must be too, since d is tangent at x.');
    end

    % If x and / or d are not specified, pick them at random.
    if ~x_isprovided
        x = problem.M.rand();
    end
    if ~d_isprovided
        d = problem.M.randvec(x);
    end

    % Compute the value f0 at f and directional derivative at x along d.
    storedb = StoreDB();
    xkey = storedb.getNewKey();
    f0 = getCost(problem, x, storedb, xkey);
    df0 = getDirectionalDerivative(problem, x, d, storedb, xkey);

    % Compute the value of f at points on the geodesic (or approximation
    % of it) originating from x, along direction d, for stepsizes in a
    % large range given by h.
    h = logspace(-8, 0, 51);
    value = zeros(size(h));
    for i = 1 : length(h)
        y = problem.M.exp(x, d, h(i));
        ykey = storedb.getNewKey();
        value(i) = getCost(problem, y, storedb, ykey);
    end

    % Compute the linear approximation of the cost function using f0 and
    % df0 at the same points.
    model = polyval([df0 f0], h);

    % Compute the approximation error
    err = abs(model - value);

    % And plot it.
    loglog(h, err);
    title(sprintf(['Directional derivative check.\nThe slope of the '...
                   'continuous line should match that of the dashed '...
                   '(reference) line\nover at least a few orders of '...
                   'magnitude for h.']));
    xlabel('h');
    ylabel('Approximation error');

    line('xdata', [1e-8 1e0], 'ydata', [1e-8 1e8], ...
         'color', 'k', 'LineStyle', '--', ...
         'YLimInclude', 'off', 'XLimInclude', 'off');

    % In a numerically reasonable neighborhood, the error should decrease
    % as the square of the stepsize, i.e., in loglog scale, the error
    % should have a slope of 2.
    window_len = 10;
    [range, poly] = identify_linear_piece(log10(h), log10(err), window_len);
    hold on;
        loglog(h(range), 10.^polyval(poly, log10(h(range))), ...
               'r-', 'LineWidth', 3);
    hold off;

    fprintf('The slope should be 2. It appears to be: %g.\n', poly(1));
    fprintf(['If it is far from 2, then directional derivatives ' ...
             'might be erroneous.\n']);

end


function y = reflect(x,minx,maxx)

% function y = reflect(x,minx,maxx)
% Reflect the values in matrix x about the scalar values minx and maxx.
% Hence a vector x containing a long linearly increasing series
% is converted into a waveform which ramps linearly up and down
% between minx and maxx.
% If x contains integers and minx and maxx are (integers + 0.5),
% the ramps will have repeated max and min samples.
%
% Nick Kingsbury, Cambridge University, January 1999.

y = x;

% Reflect y in maxx.
t = find(y > maxx);
y(t) = 2*maxx - y(t);

% Reflect y in minx.
t = find(y < minx);
while ~isempty(t)
   y(t) = 2*minx - y(t);

   % Repeat until no more values out of range.
   t = find(y > maxx);
   if ~isempty(t), y(t) = 2*maxx - y(t); end
   t = find(y < minx);
end

return;


function value = boothroyd_condition ( n )

%*****************************************************************************80
%
%% BOOTHROYD_CONDITION returns the L1 condition of the BOOTHROYD matrix.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 April 2015
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer N, the order of A.
%
%    Output, real VALUE, the L1 condition.
%
  a_norm = 0.0;
  for j = 1 : n
    s = 0.0;
    for i = 1 : n

      s = s + r8_choose ( n + i - 1, i - 1 ) * r8_choose ( n - 1, n - j ) ...
        * n / ( i + j - 1 );

    end
    a_norm = max ( a_norm, s );
  end

  b_norm = a_norm;

  value = a_norm * b_norm;

  return
end


function [node,elem,T] = squarequadmesh(square,h)
%% SQUAREMESH uniform mesh of a square
%
% [node,elem] = squarequadmesh([x0,x1,y0,y1],h) generates a uniform mesh of the
% rectangle [x0,x1]*[y0,y1] with mesh size h.
%
% Example
%
%   [node,elem] = squarequadmesh([0,1,0,2],0.5);
%   showmesh(node,elem);
%   findnode(node);
%   findquadelem(node,elem);
%
% See also: squaregradmeshquad, cubehexmesh
%
% Copyright (C) Long Chen. See COPYRIGHT.txt for details.

%% Generate nodes
x0 = square(1); x1 = square(2);
y0 = square(3); y1 = square(4);
% [x,y] = meshgrid(x0:h:x1,y1:-h:y0);
[x,y] = ndgrid(x0:h:x1,y0:h:y1);
node = [x(:),y(:)];

%% Generate elements
ni = size(x,1); % number of rows
nj = size(x,2);
N = size(node,1);
nodeidx = reshape(1:N,ni,nj);
t2nidxMap = nodeidx(1:ni-1,1:nj-1);
k = t2nidxMap(:);
elem = [k k+ni k+ni+1 k+1];
NT = size(elem,1);
% 4 k+1 --- k+ni+1 3
%    |        |
% 1  k  ---  k+ni  2

%% Check if further structure is needed
if nargout<=2
    return;
end

%% Generate edges
Ne1 = (ni-1)*nj;
Ne2 = ni*(nj-1);
edge = zeros(Ne1+Ne2,2,'int32');
% vertical edges
e2nidxMap = nodeidx(1:ni-1,1:nj);
k = e2nidxMap(:);
edge(1:Ne1,:) = [k k+1];
% horizontal edges
e2nidxMap = nodeidx(1:ni,1:nj-1);
k = e2nidxMap(:);
edge(Ne1+(1:Ne2),:) = [k k+ni];

%% Generate index map between element and edges
elem2edge = zeros(NT,4,'int32');
edge2elem = zeros(Ne1+Ne2,2,'int32');
k = 1:NT;
veidx = k; % veidx = sub2ind([ni-1,nj],i,j);
heidx = Ne1 + (1:Ne2); % linear indexing
heidx = reshape(heidx,ni,nj-1); % matrix indexing
heidx = heidx(1:ni-1,:); % without top edges
elem2edge(k,1) = heidx(:);
elem2edge(k,3) = heidx(:)+1;
elem2edge(k,2) = veidx + (ni-1);
elem2edge(k,4) = veidx;
% vertical edges
edge2elem(veidx,2) = k;   % right element
edge2elem(veidx+ni-1,1) = k; % left element
% horizontal edges
edge2elem(heidx,1) = k;
edge2elem(heidx+1,2) = k;

%% Generate boundary edges
% for boundary edges, set the another element idx to zero
idx1 = edge2elem(:,1) == 0; % left and top
idx2 = edge2elem(:,2) == 0;
bdEdge = [edge(idx1,[2 1]); edge(idx2,:)];
% switch edge index on the left and top to have a consistent orientation

%% Auxstructure
T = struct('edge',edge,'elem2edge',elem2edge,'edge2elem',edge2elem,'bdEdge',bdEdge);
% neighbor and bdElem can be easily get from 2-D index of all elements


function [U, S, V, info] = truncated_svd(A, p)
% Returns an SVD decomposition of A truncated to rank p.
%
% function [U, S, V, info] = truncated_svd(A, p)
%
% Input: A real matrix A of size mxn and an integer p <= min(m, n).
% Output: An orthonormal matrix U of size mxp, an orthonormal matrix Y of
%         size nxp and a diagonal matrix S of size pxp with nonnegative and
%         decreasing diagonal entries such that USV.' is the best rank p
%         approximation of A according to the Frobenius norm. All real.
%         This function produces an output akin to svds.
%
% The decomposition is obtained by maximizing
%   f(U, V) = .5*norm(U'*A*V, 'fro')^2
% where U, V are orthonormal. Notice that f(U*Q, V*R) = f(U, V) for all
% Q, R orthogonal pxp matrices. Hence, only the column spaces of U and V
% matter and we may perform the optimization over a product of two
% Grassmannian manifolds.
%
% It is easy to show that maximizing f is equivalent to minimizing g with
%   g(U, V) = min_S norm(U*S*V' - A, 'fro')^2,
% which confirms that we are going for a best low-rank approximation of A.
%
% The inner workings of the Grassmann manifold use the built-in svd
% function of Matlab but only for matrices of size mxp and nxp to
% re-orthonormalize them.
%
% Notice that we are actually chasing a best fixed-rank approximation of a
% matrix, which is best obtained by working directly over a manifold of
% fixed-rank matrices. This is simply an example script to demonstrate some
% functionalities of the toolbox.
%
% The code can be modified to accept a function handle for A(x) = A*x
% instead of a matrix A, which is often useful. This would further require
% a function handle At for the transpose of A, such that At(x) = A.'*x.

% This file is part of Manopt and is copyrighted. See the license file.
%
% Main author: Nicolas Boumal, July 5, 2013
% Contributors:
%
% Change log:
%
%   Aug. 23, 2021 (XJ):
%       Added AD to compute the egrad and the ehess

    % Generate some random data to test the function if none is given.
    if ~exist('A', 'var') || isempty(A)
        A = randn(42, 60);
    end
    if ~exist('p', 'var') || isempty(p)
        p = 5;
    end

    % Retrieve the size of the problem and make sure the requested
    % approximation rank is at most the maximum possible rank.
    [m, n] = size(A);
    assert(p <= min(m, n), 'p must be smaller than the smallest dimension of A.');

    % Define the cost and its derivatives on the Grassmann manifold
    tuple.U = grassmannfactory(m, p);
    tuple.V = grassmannfactory(n, p);
    % All of the code will work just as well if we ignore the invariance
    % property of the cost function indicated above and thus place U and V
    % on the Stiefel manifold (orthonormal matrices) instead of the
    % Grassmann manifold. Working on Stiefel is expected to be slower
    % though, partly because de search space is higher dimensional and
    % partly because the optimizers are not isolated.
    % tuple.U = stiefelfactory(m, p);
    % tuple.V = stiefelfactory(n, p);
    M = productmanifold(tuple);

    % Define a problem structure, specifying the manifold M, the cost
    % function and its derivatives. Here, to demonstrate the rapid
    % prototyping capabilities of Manopt, we directly define the Euclidean
    % gradient and the Euclidean Hessian egrad and ehess instead of the
    % Riemannian gradient and Hessian grad and hess. Manopt will take care
    % of the conversion. This automatic conversion is usually not
    % computationally optimal though, because much of the computations
    % involved in obtaining the gradient could be reused to obtain the
    % Hessian. After the prototyping stage, when efficiency becomes
    % important, it makes sense to define grad and hess rather than egrad
    % an ehess, and to use the caching system (the store structure).
    problem.M = M;
    problem.cost  = @cost;
    problem.egrad = @egrad;
    problem.ehess = @ehess;

    % The functions below make many redundant computations. This
    % performance hit can be alleviated by using the caching system.

    % Cost function
    function f = cost(X)
        U = X.U;
        V = X.V;
        f = -.5*norm(U'*A*V, 'fro')^2;
    end
    % Euclidean gradient of the cost function
    function g = egrad(X)
        U = X.U;
        V = X.V;
        AV = A*V;
        AtU = A'*U;
        g.U = -AV*(AV'*U);
        g.V = -AtU*(AtU'*V);
    end
    % Euclidean Hessian of the cost function
    function h = ehess(X, H)
        U = X.U;
        V = X.V;
        Udot = H.U;
        Vdot = H.V;
        AV = A*V;
        AtU = A'*U;
        AVdot = A*Vdot;
        AtUdot = A'*Udot;
        h.U = -(AVdot*AV'*U + AV*AVdot'*U + AV*AV'*Udot);
        h.V = -(AtUdot*AtU'*V + AtU*AtUdot'*V + AtU*AtU'*Vdot);
    end

    % An alternative way to compute the egrad and the ehess is to use
    % automatic differentiation provided in the deep learning toolbox
    % (slower). Notice that the function norm is not supported for AD so
    % far. Replace norm(...,'fro') with the backup function cnormsqfro
    % described in manoptADhelp
    % problem.cost = @cost_AD;
    %    function f = cost_AD(X)
    %        U = X.U;
    %        V = X.V;
    %        f = -.5*cnormsqfro(U'*A*V);
    %    end
    % call manoptAD to prepare AD for the problem structure
    % problem = manoptAD(problem);

    % Execute some checks on the derivatives for early debugging.
    % These things can be commented out of course.
    % checkgradient(problem);
    % pause;
    % checkhessian(problem);
    % pause;

    % Issue a call to a solver. A random initial guess will be chosen and
    % default options are selected. Here, we specify a maximum trust
    % region radius (which in turn induces an initial trust region radius).
    % Note that this is not required: default values are used if we omit
    % this. The diameter of the manifold scales like sqrt(2*p), hence the
    % form of our (empirical) choice.
    options.Delta_bar = 4*sqrt(2*p);
    [X, Xcost, info] = trustregions(problem, [], options); %#ok<ASGLU>
    U = X.U;
    V = X.V;

    % Finish the job by rotating U and V such that the middle matrix S can
    % be diagonal with nonnegative, decreasing entries. This requires a
    % small svd of size pxp.
    Spp = U'*A*V;
    [Upp, Spp, Vpp] = svd(Spp);
    U = U*Upp;
    S = Spp;
    V = V*Vpp;

    % For our information, Manopt can also compute the spectrum of the
    % Riemannian Hessian on the tangent space at (any) X. Computing the
    % spectrum at the solution gives us some idea of the conditioning of
    % the problem. If we were to implement a preconditioner for the
    % Hessian, this would also inform us on its performance.
    %
    % Notice that if the optimization is performed on a product of Stiefel
    % manifolds instead of a product of Grassmannians, the double
    % invariance under the orthogonal group O(p) will appear as twice
    % p*(p-1)/2, thus p*(p-1) zero eigenvalues in the spectrum of the
    % Hessian. This means that the minimizers are not isolated, which
    % typically hinders convergence of second order algorithms.
    if M.dim() < 512
        evs = hessianspectrum(problem, X);
        stairs(sort(evs));
        title(['Eigenvalues of the Hessian of the cost function ' ...
               'at the solution']);
    end

end


function cvx_optval = sum_smallest( x, varargin )

%SUM_SMALLEST Sum of the smallest k elements of a vector.
%   For a real vector X and an integer k between 1 and length(X) inclusive,
%   y = SUM_SMALLEST(X,k) is the sum of the k smallest elements of X; e.g.,
%       temp = sort( x )
%       y = sum( temp( 1 : k ) )
%   If k=1, then SUM_SMALLEST(X,k) is equivalent to MIN(X); if k=length(X),
%   then SUM_SMALLEST(X,k) is equivalent to SUM(X).
%
%   Both X and k must be real, and k must be a scalar. But k is not, in
%   fact, constrained to be an integer between 1 and length(X); the
%   function is extended continuously and logically to all real k. For
%   example, if k <= 0, then SUM_SMALLEST(X,k)=0. If k > length(X), then
%   SUM_SMALLEST(X,k)=SUM(X). Non-integer values of k interpolate linearly
%   between their integral neighbors.
%
%   For matrices, SUM_SMALLEST(X,k) is a row vector containing the
%   application of SUM_SMALLEST to each column. For N-D arrays, the
%   SUM_SMALLEST operation is applied to the first non-singleton dimension
%   of X.
%
%   SUM_SMALLEST(X,k,DIM) performs the operation along dimension DIM of X.
%
%   Disciplined convex programming information:
%       SUM_SMALLEST(X,...) is concave and nondecreasing in X. Thus, when
%       used in CVX expressions, X must be concave (or affine). k and DIM
%       must both be constant.

narginchk(2,3);
cvx_optval = -sum_largest( -x, varargin{:} );

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


%  Figure 3.30b      Feedback Control of Dynamic Systems, 5e
%                        Franklin, Powell, Emami
%

clf;
num=1;
a=5;

zeta =1;
den2=[1/(zeta*a) 1];
den1=[1 2*zeta 1];
den=conv(den1,den2);
t=0:.1:8;
y1=step(num,den,t);

zeta =.7;
den2=[1/(zeta*a) 1];
den1=[1 2*zeta 1];
den=conv(den1,den2);
y2=step(num,den,t);

zeta =.5;
den2=[1/(zeta*a) 1];
den1=[1 2*zeta 1];
den=conv(den1,den2);
y3=step(num,den,t);

axis([0 5 .1 .9])
plot(t,y1,'-',t,y2,'--',t,y3,'-.'),grid
title('Fig. 3.30b Step response with extra pole, \alpha= 5')
xlabel('\omega_n t')
ylabel('y(t)')


function fx = p11_fun ( n, x )

%*****************************************************************************80
%
%% P11_FUN evaluates the integrand for problem 11.
%
%  Discussion:
%
%    S&S gives exact value as pi =  3.1415926535897932385...
%    S&S gives Laguerre(16) as      2.6652685196...
%    S&S gives EXP_TRANSFORM(16) as 2.3629036166...
%
%  Integral:
%
%    Integral ( 0 <= x < +oo ) 1/((1+x)*sqrt(x)) dx
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    29 July 2007
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Arthur Stroud, Don Secrest,
%    Gaussian Quadrature Formulas,
%    Prentice Hall, 1966,
%    LC: QA299.4G3S7.
%
%  Parameters:
%
%    Input, integer N, the number of points.
%
%    Input, real X(N), the evaluation points.
%
%    Output, real FX(N), the function values.
%
  for i = 1 : n
    if ( x(i) == 0.0 )
      fx(i) = 0.0;
    else
      fx(i) = 1.0 / ( ( 1.0 + x(i) ) * sqrt ( x(i) ) );
    end
  end

  return
end


%  Figure 7.55      Feedback Control of Dynamic Systems, 6e
%                        Franklin, Powell, Emami
%
% script for Fig. 7.55
%
clf;
dp=[1 1 0];
np=[1];
nc=conv([1 1],[8.32 0.8]);
dc=conv([1 4.08],[1 0.0196]);
num=conv(np,nc);
den=conv(dp,dc);
dcl=[0 0 num]+den; % closed-loop denominator
t=0:.1:5;
sys=tf(num,dcl);
y=step(sys,t);
plot(t,y)
grid;
xlabel('Time (sec)');
ylabel('y');
title('Fig.7.55 Step response for lag compensation design');
[a,b,c,d]=tf2ss(nc,dc);
% Samplig period
ts=0.1;
% Convert controller to discrete
[ad,bd,cd,dd]=c2dm(a,b,c,d,ts,'zoh');
[ncd,dcd]=ss2tf(ad,bd,cd,dd);
% response comparison of continuous and digital control.
sim('fig7_54')
figure(1)
plot(ycd(:,1),ycd(:,2))
hold on
plot(ycd(:,1),ycd(:,3),'g--')
title('Figure 7.53(a) Output Responses of Digital and Continuous Controllers')
xlabel('Time (sec)');
ylabel('y');
text(0.5,0.5,'continuous controller')
text(0.1,1.15,'digital controller')
nicegrid
hold off
%pause;
figure(2)
plot(ucd(:,1),ucd(:,2))
hold on
plot(ucd(:,1),ucd(:,3),'g--')
title('Figure 7.55(b)  Control Responses of Digital and Continuous Controllers')
xlabel('Time (sec)');
ylabel('u');
text(0.5,0.5,'continuous controller')
text(1.1,-1.5,'digital controller')
nicegrid
hold off


function pvand_test ( )

%*****************************************************************************80
%
%% PVAND_TEST tests PVAND.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 November 2013
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'PVAND_TEST:\n' );
  fprintf ( 1, '  Solve a Vandermonde linear system A*x=b\n' );

  n = 5;

  for test = 1 : 2

    if ( test == 1 )
      alpha = [ 0.0; 1.0; 2.0; 3.0; 4.0 ];
    elseif ( test == 2 )
      alpha = rand ( n, 1 );
    end

    r8vec_print ( n, alpha, '  Vandermonde vector ALPHA:' );

    a = vand1 ( n, alpha );

    x = [ 5.0; 3.0; 4.0; 1.0; 2.0 ];
    b = a * x;
    r8vec_print ( n, b, '  Right hand side B:' );

    x = pvand ( n, alpha, b );
    r8vec_print ( n, x, '  Solution X:' );

  end

  return
end


function [MHz] = kHz2MHz(kHz)
% Convert frequency from kilohertz to megahertz.
% Chad A. Greene 2012
MHz = kHz*1e-3;


function element_num = grid_t6_element_num ( nelemx, nelemy )

%*****************************************************************************80
%
%% GRID_T6_ELEMENT_NUM counts the elements in a grid of 6 node triangles.
%
%  Example:
%
%    Input:
%
%      NELEMX = 3, NELEMY = 2
%
%    Output:
%
%      ELEMENT_NUM = 2 * NELEMX * NELEMY = 12
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 June 2005
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NELEMX, NELEMY, the number of elements along the
%    X and Y directions.  The number of elements generated will be
%    NELEMX * NELEMY.
%
%    Output, integer ELEMENT_NUM, the number of elements in the grid.
%
  element_num = 2 * nelemx * nelemy;

  return
end


function c = crossProduct3d(a,b)
%CROSSPRODUCT3D Vector cross product faster than inbuilt MATLAB cross.
%
%   C = crossProduct3d(A, B)
%   returns the cross product of the two 3D vectors A and B, that is:
%       C = A x B
%   A and B must be N-by-3 element vectors. If either A or B is a 1-by-3
%   row vector, the result C will have the size of the other input and will
%   be the  concatenation of each row's cross product.
%
%   Example
%     v1 = [2 0 0];
%     v2 = [0 3 0];
%     crossProduct3d(v1, v2)
%     ans =
%         0   0   6
%
%
%   Class support for inputs A,B:
%      float: double, single
%
%   See also DOT.

%   Sven Holcombe

% HISTORY
% 2017-11-24 rename from vectorCross3d to crossProduct3d

% size of inputs
sizeA = size(a);
sizeB = size(b);

% Initialise c to the size of a or b, whichever has more dimensions. If
% they have the same dimensions, initialise to the larger of the two
switch sign(numel(sizeA) - numel(sizeB))
    case 1
        c = zeros(sizeA);
    case -1
        c = zeros(sizeB);
    otherwise
        c = zeros(max(sizeA, sizeB));
end

c(:) = bsxfun(@times, a(:,[2 3 1],:), b(:,[3 1 2],:)) - ...
       bsxfun(@times, b(:,[2 3 1],:), a(:,[3 1 2],:));


function [RCM1, RCM2, RCM3, RCM4, RCM5] = region_covariance(img, options)
% Region covariance matrix (GCM) algorithm
%
% Inputs:
%       img                 image data
%       options             options
% Output:
%       RCM1                region covariance matrix of size 7x7 (RCM1)
%                           pixel location, intensity, 1st&2nd-order gradient
%       RCM2                region covariance matrix of size 7x7 (RCM2)
%                           pixel location, 1st&2nd-order gradient, and edge orientation
%       RCM3                region covariance matrix of size 6x6 (RCM3)
%                           pixel location, and 1st&2nd-order gradient
%       RCM4                region covariance matrix of size 8x8 (RCM4) with
%                           pixel location, intensity, 1st&2nd-order gradient, and
%                           edge orientation
%       RCM5                region covariance matrix of size 5x5 (RCM5) with
%                           intensity, 1st&2nd-order gradient (not appear in the paper)
%
%
% References:
%       Yanwei Pang, Yuan Yuan, and Xuelong Li
%       'Gabor-Based Region Covariance Matrices for Face Recognition'
%       IEEE Transactions on Circuits and Systems for Video Technology vol.18, no.7, 2008.
%
%
% Created by H.Kasai on June 23, 2017

    symm = @(X) .5*(X+X');

    % check correct number of arguments
    if (nargin ~= 2)
        error('Please use the correct number of input arguments!')
    end

    % extract options
    if ~isfield(options, 'spd_projection')
        spd_projection = true;
    else
        spd_projection = options.spd_projection;
    end

    % check if the input image is grayscale
    if size(img,3) == 3
        warning('The input RGB image is converted to grayscale!')
        img = rgb2gray(img);
    end

    % obtain image size
    [ysize, xsize] = size(img);
    num_of_pixels = ysize * xsize;

    % prepare array
    Feature_Mat = zeros(8, num_of_pixels);

    % calculate first-order and second-order derivatives
    img = double(img);
    [Ix, Iy] = gradient(img);   % first order partials
    [Ixx, Ixy] = gradient(Ix);  % second order partials
    [Iyx, Iyy] = gradient(Iy);  % second order partials

    % calculate 9-dimensional feature vectior for every pixels
    pixel_cnt = 0;
    for y = 1 : ysize
        for x = 1 : xsize
            %fprintf('[%d %d] %d)\n', y, x, pixel_cnt);
            pixel_cnt = pixel_cnt + 1;

            Feature_Mat(1, pixel_cnt)   = x;
            Feature_Mat(2, pixel_cnt)   = y;
            Feature_Mat(3, pixel_cnt)   = img(y,x);

            Feature_Mat(4, pixel_cnt)   = abs(Ix(y,x));
            Feature_Mat(5, pixel_cnt)   = abs(Iy(y,x));

            Feature_Mat(6, pixel_cnt)   = abs(Ixx(y,x));
            Feature_Mat(7, pixel_cnt)   = abs(Iyy(y,x));

            theta = atan(abs(Iy(y,x))/abs(Ix(y,x)));
            Feature_Mat(8, pixel_cnt)   = theta;

        end
    end

    % calculate covariance matrix
    Feature_Mat_type1 = Feature_Mat;
    Feature_Mat_type1(8,:) = [];            % remove orientation (theta)
    RCM1 = cov(Feature_Mat_type1');         % case for Eq.(5)

    Feature_Mat_type2 = Feature_Mat;
    Feature_Mat_type2(3,:) = [];            % remove intensity
    RCM2 = cov(Feature_Mat_type2');         % case for Eq.(6)

    Feature_Mat_type3 = Feature_Mat;
    Feature_Mat_type3(8,:) = [];            % remove edge orientation (theta)
    Feature_Mat_type3(3,:) = [];            % remove intensity
    RCM3 = cov(Feature_Mat_type3');         % case for Eq.(8)

    RCM4 = cov(Feature_Mat');               % case for Eq.(9)

    Feature_Mat_type5 = Feature_Mat;
    Feature_Mat_type5(8,:) = [];            % remove edge orientation (theta)
    Feature_Mat_type5(1:2,:) = [];          % remove location
    RCM5 = cov(Feature_Mat_type5');         % additional case

    % project onto SPD if needed
    if spd_projection
        RCM1 = symm(spd_project(RCM1));
        RCM2 = symm(spd_project(RCM2));
        RCM3 = symm(spd_project(RCM3));
        RCM4 = symm(spd_project(RCM4));
        RCM5 = symm(spd_project(RCM5));
    end

end


function f=GA_demo(x)
f1=4*x(1).^3+4*x(1)*x(2)+2*x(2).^2-42*x(1)-14;
f2=4*x(2).^3+4*x(1)*x(2)+2*x(1).^2-26*x(1)-22;
f=f1.^2+f2.^2;