www.pudn.com > ica_v0.04.rar > main.c


/*
  main.c

  Time-stamp: 

  This is the starting point for the Independent Component Analysis (ICA)
  program for separating mixed sources. This will be primarily used
  as an off-line tool but is a prelude to a on-line real-time version
  for unmixing EEG signals.
  
  The input is from a file and the output is optionally to a file.
  Information on how the program is performing will be given to
  standard output. This will in future optionally go to a file. The
  learning rate and number of channels is also a required input. There
  are also extra parameters to indicate how many passes to make of
  the data and how big the block size should be for data recycling.

  Programmer: Peter Stepien
              pstepien@sedal.usyd.edu.au
              CEL, School of Electrical & Information Engineering
              The University of Sydney
              SYDNEY NSW 2006 Australia

              COPYRIGHT 1997-2001
*/

/* System headers */
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/* Local headers */
#include "ica.h"

void
usage(char *progname)
{
  printf("Usage: %s [-i ] [-o ]\n", progname);
  printf("        [-it ] [-ot ]\n");
  printf("        [-c ] [-l ]\n");
  printf("        [-n ] [-b ]\n");
  printf("        [-nl ] [-cov] [-nounmix]\n");
  printf("        [-iw] [-wi ] [-w] [-wo ]\n");
  printf("        [-h]\n");
  printf("\n");
  printf("        Default values:\n");
  printf("                  = '%s'\n", DEFAULT_INPUT_FILENAME);
  printf("                 = '%s'\n", DEFAULT_OUTPUT_FILENAME);
  printf("                  = '%s'\n",
	 FILE_TYPE_MAP[DEFAULT_INPUT_TYPE]);
  printf("                 = '%s'\n",
	 FILE_TYPE_MAP[DEFAULT_OUTPUT_TYPE]);
//printf("          = %d\n", DEFAULT_NUM_CHANNELS);
  printf("               = %f\n", DEFAULT_LEARN_RATE);
  printf("            = %d\n", DEFAULT_NUM_PASSES);
  printf("                  = %d\n", DEFAULT_BLOCK_SIZE);
  printf("               = '%s'\n",
	 NONLINEAR_TYPE_MAP[DEFAULT_NONLINEAR_TYPE]);
  printf("                = '%s'\n", DEFAULT_W_INPUT_FILENAME);
  printf("               = '%s'\n", DEFAULT_W_OUTPUT_FILENAME);
  printf("\n");
  printf("        File types: ");
  util_print_file_types();
  printf("        Non-linearity types: ");
  util_print_nonlinear_types();
  printf("\n");
  printf("Version "VERSION"\n");
  printf("\n");
  exit(-1);
}

int main(n, args)
int n;
char **args;
{
  /* Parameters defining the run */

  char *input_filename = DEFAULT_INPUT_FILENAME;
  char *output_filename = DEFAULT_OUTPUT_FILENAME;
  int input_type = DEFAULT_INPUT_TYPE;
  int output_type = DEFAULT_OUTPUT_TYPE;
  int num_channels = DEFAULT_NUM_CHANNELS;
  FLOAT_TYPE learn_rate = DEFAULT_LEARN_RATE;
  int num_passes = DEFAULT_NUM_PASSES;
  int block_size = DEFAULT_BLOCK_SIZE;
  int nonlinear_type = DEFAULT_NONLINEAR_TYPE;
  int output_w = DEFAULT_OUTPUT_W;
  int input_w = DEFAULT_OUTPUT_W;
  int output_cov = DEFAULT_OUTPUT_COV;
  int output_unmix = DEFAULT_OUTPUT_UNMIX;
  char *w_input_filename = DEFAULT_W_INPUT_FILENAME;
  char *w_output_filename = DEFAULT_W_OUTPUT_FILENAME;

  /* Other variables */

  int input_file;
  int output_file;
  int w_input_file;
  int w_output_file;
  int status;
  int i;

  /*
  printf("sizeof(float)  = %d\n", sizeof(float));
  printf("sizeof(double) = %d\n", sizeof(double));
  printf("sizeof(short) = %d\n", sizeof(short));
  return (0);
*/
  
  printf("\nWelcome to the ICA program (Copyright 1997-2001)...\n\n");

#ifdef DEBUG
  printf("DEBUG: number of input parameters = %d\n",n);
  for (i=0;i= n)
      {
	usage(args[0]);
      }

      if (!strcmp(args[i], "-i"))
      {
	i++;
	input_filename = args[i];
      }
      else if (!strcmp(args[i], "-o"))
      {
	i++;
	output_filename = args[i];
      }
      else if (!strcmp(args[i], "-it"))
      {
	i++;
	input_type = util_get_file_type(args[i]);
      }
      else if (!strcmp(args[i], "-ot"))
      {
	i++;
	output_type = util_get_file_type(args[i]);
      }
      else if (!strcmp(args[i], "-c"))
      {
	i++;
	sscanf(args[i], "%d", &num_channels);
	if (input_type == EDF)
	{
	  printf("WARNING: number of channels will be read from file.\n");
	}
      }
      else if (!strcmp(args[i], "-l"))
      {
	i++;
	sscanf(args[i], "%lf", &learn_rate);
      }
      else if (!strcmp(args[i], "-n"))
      {
	i++;
	sscanf(args[i], "%d", &num_passes);
      }
      else if (!strcmp(args[i], "-b"))
      {
	i++;
	sscanf(args[i], "%d", &block_size);
      }
      else if (!strcmp(args[i], "-nl"))
      {
	i++;
	nonlinear_type = util_get_nonlinear_type(args[i]);
      }
      else if (!strcmp(args[i], "-wi"))
      {
	i++;
	w_input_filename = args[i];
      }
      else if (!strcmp(args[i], "-wo"))
      {
	i++;
	w_output_filename = args[i];
      }
      else
      {
	printf("ERROR: unknown switch '%s'\n", args[i]);
	usage(args[0]);
      }
    }
    i++;
  }

#ifdef DEBUG
  printf("DEBUG: input_filename  = '%s'\n", input_filename);
  printf("DEBUG: output_filename = '%s'\n", output_filename);
  printf("DEBUG: input_type      = '%s'\n", FILE_TYPE_MAP[input_type]);
  printf("DEBUG: output_type     = '%s'\n", FILE_TYPE_MAP[output_type]);
  printf("DEBUG: num_channels    = %d\n", num_channels);
  printf("DEBUG: learn_rate      = %lf\n", learn_rate);
  printf("DEBUG: num_passes      = %d\n", num_passes);
  printf("DEBUG: block_size      = %d\n", block_size);
  printf("DEBUG: nonlinear_type  = '%s'\n",
                                   NONLINEAR_TYPE_MAP[nonlinear_type]);
  printf("DEBUG: output_w        = %d\n", output_w);
  printf("DEBUG: output_cov      = %d\n", output_cov);
  printf("DEBUG: output_unmix    = %d\n", output_unmix);
  printf("\n");
#endif /* DEBUG */

  /* Check the parameters */

  if (num_passes < 1)
  {
    printf("ERROR: number of passes cannot be less than 1\n");
    exit(-1);
  }

  if (learn_rate <= 0.0)
  {
    printf("ERROR: the learning rate cannot be zero or less\n");
    exit(-1);
  }

  if (input_type == 0)
  {
    printf("ERROR: input file type incorrect.\n");
    printf("ERROR: choose from - ");
    util_print_file_types();
    exit(-1);
  }

  if (output_type == 0)
  {
    printf("ERROR: output file type incorrect.\n");
    printf("ERROR: choose from - ");
    util_print_file_types();
    exit(-1);
  }
  else if (output_type == EDF)
  {
    printf("ERROR: output type cannot be EDF.\n");
    exit(-1);
  }

  if ((num_channels < 2) && (input_type != EDF))
  {
    printf("ERROR: must have at least two channels\n");
    exit(-1);
  }

  if ((output_cov == TRUE) && (output_unmix == FALSE))
  {
    printf("ERROR: must output unmix to calculate covariances\n");
    exit(-1);
  }

  if (nonlinear_type == 0)
  {
    printf("ERROR: non-linearity type incorrect.\n");
    printf("ERROR: choose from - ");
    util_print_nonlinear_types();
    exit(-1);
  }

  input_file = open(input_filename, O_RDONLY);
  if (input_file == -1)
  {
    printf("ERROR: opening input file '%s'\n", input_filename);
    exit(-1);
  }

  if (input_type == EDF)
  {
    num_channels = io_reset_file_pointer(input_file, input_type);
  }

  if (input_w == TRUE)
  {
    w_input_file = open(w_input_filename, O_RDONLY);
    if (w_input_file == -1)
    {
      printf("ERROR: opening w input file '%s'\n", w_input_filename);
      exit(-1);
    }
  }
  else
  {
    w_input_file=0;
  }

  if (output_unmix == TRUE)
  {
    if (strcmp(output_filename, DEFAULT_OUTPUT_FILENAME))
    {
      output_file = open(output_filename, O_RDONLY);
      if (output_file != -1)
      {
	printf("ERROR: output file '%s' already exists\n", output_filename);
	close(input_file);
	close(output_file);
	exit(-1);
      }
    }
    
    /* Everything is all right. Open the output file for writing and
       call the ICA routine. */
    
    output_file = open(output_filename, O_WRONLY | O_CREAT, 0600);
    if (output_file == -1)
    {
      printf("ERROR: opening output file '%s' for writing\n",
	     output_filename);
      close(input_file);
      exit(-1);
    }
  }
  else
  {
    output_file = 0;
  }

  /* Open w output file if necessary */
  if (output_w == TRUE)
  {
    if (strcmp(w_output_filename, DEFAULT_W_OUTPUT_FILENAME))
    {
      output_file = open(output_filename, O_RDONLY);
      if (output_file != -1)
      {
	printf("ERROR: w output file '%s' already exists\n",
	       w_output_filename);
	close(input_file);
	close(output_file);
	exit(-1);
      }
    }

    w_output_file = open(w_output_filename, O_WRONLY | O_CREAT, 0600);
    if (w_output_file == -1)
    {
      printf("ERROR: opening w output file '%s' for writing\n",
	     output_filename);
      close(input_file);
      close(output_file);
      exit(-1);
    }
  }
  else
  {
    w_output_file = 0;
  }

  status = ica_do(input_file, output_file, input_type, output_type,
		  num_channels, learn_rate, num_passes, block_size,
		  nonlinear_type, output_w, w_output_file, output_unmix,
		  w_input_file);

  /* Close files */

  close(w_output_file);
  close(w_input_file);
  close(output_file);
  close(input_file);

  /* Let's calculate the covariance of the input and output files */

  if (output_cov == TRUE)
  {
    FLOAT_TYPE cov[num_channels][num_channels];
    FLOAT_TYPE rms_cov;

    printf("Calculating input file RMS covariance...\n");

    input_file = open(input_filename, O_RDONLY);
    if (input_file == -1)
    {
      printf("ERROR: opening input file '%s'\n", input_filename);
      exit(-1);
    }

    util_cov(input_file, input_type, num_channels, cov);
    rms_cov = util_rms_cov(cov, num_channels);

    printf("Input file RMS cov = %f\n", rms_cov);

    close(input_file);

    printf("Calculating output file RMS covariance...\n");

    input_file = open(output_filename, O_RDONLY);
    if (input_file == -1)
    {
      printf("ERROR: opening input file '%s'\n", output_filename);
      exit(-1);
    }

    util_cov(input_file, output_type, num_channels, cov);
    rms_cov = util_rms_cov(cov, num_channels);

    printf("Output file RMS cov = %f\n", rms_cov);

    close(input_file);

    printf("\n");
  }

  /* Finish up by  printing messages */

  if (status == -1)
  {
    printf("ERROR: during ICA algorithm.\n");
    return (-1);
  }

  printf("Program ended successfully.\n\n");
  return (0);
}