 /*
  * Khoros: $Id$
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id$";
#endif

 /*
  * $Log$
  */

/*
 *   Copyright, 1991, The Regents of the University of California.
 *   This software was produced under a U.S. Government contract
 *   (W-7405-ENG-36) by the Los Alamos National Laboratory, which is
 *   operated by the University of California for the U.S. Department
 *   of Energy.  The U.S. Government is licensed to use, reproduce,
 *   and distribute this software.  Neither the Government nor the
 *   University makes any warranty, express or implied, or assumes
 *   any liability responsibility for the use of this software.
 */

#include <stdio.h>

/*
 *  merge ()     Merge the statistics for cluster 2 into the statistics
 *               for cluster 1.  If one of the inputs is NULL, it is not
 *               updated.  (WILL BOMB IF means IS NULL)
 *
 *  Written by:  Patrick M. kelly
 *  Date:        8/3/91
 */

int merge ( dim, means, count, cov_upper, cov_diag, num1, num2 )

int dim;            /* Problem dimension */
float **means;      /* Mean vectors */
int *count;         /* Number of elements */
float ***cov_upper; /* Upper triangular part of covariance matrices */
float **cov_diag;   /* Diagonal part of covariance matrices */
int num1, num2;     /* The two clusters to merge */

{
     int i, j;                     /* Loop control */
     float num_1_f;                /* Number of elements cluster i */
     float num_2_f;                /* Number of elements cluster j */
     float l1, l2, l3, l4, l5;     /* Temporary */

     /*  IF NO count INFORMATION AVAILABLE, ASSUME count LARGE AND EQUAL  */

     if ( ! count ) {
          num_1_f = 1.0E12;
          num_2_f = 1.0E12;
     } else {
          num_1_f = (float) count [num1];
          num_2_f = (float) count [num2];
     }

     l1 = num_1_f - 1.0 ;
     l2 = num_2_f - 1.0 ;
     l5 = num_1_f + num_2_f;
     l3 = num_1_f * num_2_f / l5 ;
     l4 = num_1_f + num_2_f - 1.0 ;

     /*  NEW COVARIANCE MATRIX (DIAGONAL)  */

     if ( cov_diag ) {

          for ( i = 0 ; i < dim ; i ++ ) {

               cov_diag [num1][i] = l1 * cov_diag [num1][i] + 
                    l2 * cov_diag [num2][i] + 
                    l3 * (means [num1][i] - means [num2][i]) * 
                    (means [num1][j] - means [num2][j]) ;
               cov_diag [num1][i] /= l4 ;

          }

     }

     /*  NEW COVARIANCE MATRIX (UPPER TRIANGULAR)  */

     if ( cov_upper ) {

          for ( i = 0 ; i < dim ; i ++ ) {
          for ( j = i ; j < dim ; j ++ ) {

               cov_upper [num1][i][j] = l1 * cov_upper [num1][i][j] + 
                    l2 * cov_upper [num2][i][j] + 
                    l3 * (means [num1][i] - means [num2][i]) * 
                    (means [num1][j] - means [num2][j]) ;
               cov_upper [num1][i][j] /= l4 ;

          }
          }

     }

     /*  NEW MEAN VECTOR  */

     for ( i = 0 ; i < dim ; i ++ ) {
          means[num1][i]=(num_1_f*means[num1][i]+num_2_f*means [num2][i])/l5;
     }

     /*  NEW NUMBER OF ELEMENTS  */

     if ( count != NULL ) {
          count [num1] += count [num2];
     }

     return (1);
}

