/* IO(1) */

void get_x( int _K)
{
/* data setup for symbol values 1 ... M,  f(D) = 1 */

  if( narg == 0) {

    LOADED=0;

    N = 3;	/* N data samples */
    M = 5;	/* M symbol values */
    K = 1;	/* find K best completely unmerged paths */

    states = [1:M];

    zstate = 1;

    x = rand( 1, N, "int", M);	/* input sequence */

    y = x;

    noise = 0.2 * rand( 1, N, "gauss");	/* random noise */

    z = y + noise;			/* signal plus noise */

    return;
  }

  /* narg > 0 */

  if( LOADED != 0) {
    print( "get_x: call get_x with no args first.");
    return;
  }

  M = cols(states);

  if( _K > M) {
    printf( "get_x: K > M not allowed!");
    return;
  }

  K = _K;
  combos = combinations( 1:M, K);
  perms = permutations( 1:K);
  M = rows(combos);

  zstate = 0;
}


double get_yval( int _cur, int _next)
{
/* get_yval() for f(D) = 1 */

  return states(_next);
}


double get_cost( double _zz, int _cur, int _next, int _j)
{
  double yval = get_yval( _cur, _next);

  if( yval == HUGE_VAL)
    return yval;

  return pn( _zz - yval);
}


vector get_ex( vector _index)
{
/* get_ex() for f(D) = 1 */

  return states( _index);
}


matrix get_paths( vector _index, matrix _vp)
{
  int j, c;
  matrix xex;

  c = cols(_index);
  xex = zeros( K, c);

  for( j = 1; j <= c; ++j)
    xex(:,j) = states( perms( _vp( _index(j), j+1)))';

  return xex;
}
