/*
  File name: parametric.h
  Created by: Ljubomir Buturovic
  Created: 08/03/2004
  Purpose: declarations for parametric classifiers.
*/

/*
  Copyright 2004 Ljubomir J. Buturovic

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation files
  (the "Software"), to deal in the Software without restriction,
  including without limitation the rights to use, copy, modify, merge,
  publish, distribute, sublicense, and/or sell copies of the Software,
  and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include "dataset.h"

/*
  The parametric quadratic classifier model. 'wmx' defines the linear
  terms, 'sigma' the quadratic ones.
 */
struct qmodel
{
  float **wmx;
  float **sigma;
};

/*
  These constants are used when calculating dataset covariance matrix
  for a linear parametric classifier. It can be calculated as an
  estimate over the entire dataset, or as a weighted sum of the
  class-conditional covariance matrix estimates. CUMULATIVE_COV
  designates the former case (cumulative covariance matrix estimate),
  WEIGHTED_COV the latter.
*/
#define CUMULATIVE_COV        1 
#define WEIGHTED_COV          2

/*
  Return parametric linear classifier trained on 'dset'. The
  classifier is a matrix c by d+1, where 'c' is number of classes and
  'd' is dimension of input vectors.

  In case of error, return NULL and set errc to the error code. Error
  codes are EINVAL for bad input arguments, malloc() error codes and
  LERR_SINGCOV for singular covariance matrix.

  Uses equations (60-62) from R. O. Duda, P. E. Hart and D. G. Stork,
  Pattern Classification, Second Edition, John Wiley & Sons, Inc.,
  2001.
*/
float **lin_learn(int mode, struct dataset *dset, int *errc);

void qmodel_free(struct qmodel *model, int c);

/*
  Return partial parametric quadratic classifier trained on
  'dset'. The partial classifier is a matrix c by d+1, where 'c' is
  number of classes and 'd' is dimension of input vectors.

  The function uses equations (66-69) from R. O. Duda, P. E. Hart and
  D. G. Stork, Pattern Classification, Second Edition, John Wiley &
  Sons, Inc., 2001. According to these equations, the quadratic
  classifier consists of a quadratic and linear parts. The quadratic
  part is trivial; it is simply -0.5 times the inverted covariance
  matrix for the corresponding class. Therefore the function does not
  return it, but instead merely computes the class-conditional
  inverted covariance matrices and stores them in dset->sigma. The
  returned array is the linear part of the classifier.

  In case of error, return NULL and set errc to the error code. Error
  codes are EINVAL for bad input arguments, malloc() error codes and
  LERR_SINGCOV for singular covariance matrix.
*/
struct qmodel *pqc_learn(struct dataset *dset, int *errc);

/*
  Save parametric quadratic classifier defined by 'qcx' in
  'fname'. 'd' is dimension of the problem, 'c' is number of classes.

  The classifier is saved in the following format: for each class, the
  linear portion of the classifier is saved first (which is a vector
  of length d+1), followed by the inverse of the class-conditional
  covariance matrix. To perform classification, use equations (66-69)
  from Duda, Hart & Stork.

  Return 0 for success, error code for failure. 
*/
int pqc_save(struct qmodel *qcx, int d, int c, char *fname);

/*
  Append parametric quadratic classifier defined by 'qcx' to 'fptr',
  in 'bagging' format. The first column is total number of models
  'nmodels, followd by model index 'mdx' and model weight 'weight'.

  Return 0 for success, error code for failure. 
*/
int pqc_write(FILE *fptr, int nmodels, struct qmodel *qcx, int d, int c, int mdx, 
	      float weight);

/*
  Load a committee of quadratic classifiers from 'fname'. The function
  returns an array of pointers to 'qmodel' structures, one structure
  per model. Each struct defines a parametric quadratic classifier.

  The function automatically recognizes two types of model files:
  single model (MODEL_SINGLE) or multiple model (MODEL_MULTI). Single
  model file contains one linear classifier, while multiple model
  contains multiple classifiers.
  
  Multiple model file has total number of models in the first column,
  followed by the model ID and model weight. The rest of information
  is the same as in single model file.

  The function sets the model type file in 'type'. For multiple model
  file, the number of models is returnes in 'nmodels', and model
  weights are returned in 'weights'.

  Each element's qmodel->wmx is a 'rows' by 'columns' matrix.

  The quadratic coefficients (qmodel->sigma) are simply the inverse
  class-conditional covariance matrices. Note that for the actual
  classification, the quadratic part has to be multiplied by -0.5.

  In case of failure, return NULL and set 'errc'. Possible errors are
  memory allocation and file access errors.
*/
struct qmodel **pqc_load_models(char *fname, int *type, int *nmodels, float **weights,
				int *rows, int *columns, int *errc);

/*
  Return predicted classification of 'vector' by parametric quadratic
  classifer stored in 'model'. It is assumed that the length of
  'vector' is ad-1.

  Return -1 in case of bad arguments or malloc() error and set
  errno. Otherwise, the result is in the [0..c-1] interval.
*/
int pqc_predict(struct qmodel *model, int c, int ad, float *vector);

/*
  Calculate quadratic classifier output for 'vector'. The classifier
  is defined by 'model'. It is assumed that the length of 'vector' is
  ad-1. The output is a vector of length c which contains values of
  discriminant function for each class.

  Return -1 in case of bad arguments or malloc() error and set errno.
*/
float *pqc_output(struct qmodel *model, int c, int ad, float *vector);


syntax highlighted by Code2HTML, v. 0.9.1