/*
   File:        empca.h
   Author:      David Cohn
   Created:     09 Aug 2002
   Description: Basic

   Implements Sam Roweis' EM procedure for performing principal
   components analysis.

   input:
   obs: input matrix, one observation per column. Assumes obs is zero-mean
   iters: number of iterations of empca to run

   output:
   evec:   left eigenvectors, once vector per column
   eval:   eigenvalues
   evec_r: right eigenvectors, one per column

   Note: empca determines how many eigenvectors to extract based on the
   dimension of evec.

   Assumes data are zero mean - eval and/or evec_r can be NULL if their 
   values are not needed.
*/

#ifndef EMPCA_H
#define EMPCA_H

#include "standard.h"
#include "ambs.h"
#include "amdym.h"

/* NOTE: assumes data are zero mean! */

void empca(dym *obs, int iters, dym *evec, dyv *eval, dym *evec_r) ;

/* 
   Make each row zero mean, returning a dyv containing the original
   mean so that future data can be transformed using the same transform.
   Useful when obs is a matrix of observations, with one observation per
   column.
*/

dyv *mk_rows_zero_mean(dym *obs) ;

/*
   Make each row unit mean, returning a dyv containing the original
   stddev so that future data can be transformed to the same scale by
   dividing by the returned vector.

   Useful when obs is a matrix of observations, with one observation per
   column.

   NOTE: this doesn't assume zero-mean data, but should probably be
   called after mk_rows_zero_mean, so that the mean vector is
   recovered.
*/

dyv *mk_rows_unit_variance(dym *obs) ;

/* Helper routines for empca */

void orth(dym *A, dym *A_orth) ;

void mk_pca(dym *A, dym *evecs, dyv *evals) ;

#endif /* EMPCA_H */
