Files
mlpack/fastlib/branches/fastlib-old/la/la.h
T
Ryan Curtin f6864dd435 Move fastlib-old (originally 'fastlib') to fastlib/branches/fastlib-old where it
will sit until the end of time and nobody will touch it because it's old
2010-01-31 22:31:55 +00:00

164 lines
4.4 KiB
C++

// Copyright 2007 Georgia Institute of Technology. All rights reserved.
// ABSOLUTELY NOT FOR DISTRIBUTION
/**
* @file la.h
*
* Core routines for linear algebra.
*
* See uselapack.h for more linear algebra routines.
*/
#ifndef LINEAR_H
#define LINEAR_H
#include "matrix.h"
#include "uselapack.h"
#include "math/math.h"
#include <math.h>
namespace la {
/**
* Finds the Euclidean distance squared between two vectors.
*/
inline double DistanceSqEuclidean(
index_t length, const double *va, const double *vb) {
double s = 0;
do {
double d = *va++ - *vb++;
s += d * d;
} while (--length);
return s;
}
/**
* Finds the Euclidean distance squared between two vectors.
*/
inline double DistanceSqEuclidean(const Vector& x, const Vector& y) {
DEBUG_SAME_SIZE(x.length(), y.length());
return DistanceSqEuclidean(x.length(), x.ptr(), y.ptr());
}
/**
* Finds an L_p metric distance except doesn't perform the root
* at the end.
*
* @param t_pow the power each distance calculatin is raised to
* @param length the length of the vectors
* @param va first vector
* @param vb second vector
*/
template<int t_pow>
inline double RawLMetric(
index_t length, const double *va, const double *vb) {
double s = 0;
do {
double d = *va++ - *vb++;
s += math::PowAbs<t_pow, 1>(d);
} while (--length);
return s;
}
/**
* Finds an L_p metric distance AND performs the root
* at the end.
*
* @param t_pow the power each distance calculatin is raised to
* @param length the length of the vectors
* @param va first vector
* @param vb second vector
*/
template<int t_pow>
inline double LMetric(
index_t length, const double *va, const double *vb) {
return math::Pow<1, t_pow>(RawLMetric<t_pow>(length, va, vb));
}
/** Finds the trace of the matrix.
* Trace(A) is the sum of the diagonal elements
*/
inline double Trace(Matrix &a) {
// trace has meaning only for square matrices
DEBUG_SAME_SIZE(a.n_cols(), a.n_rows());
double trace=0;
for(index_t i=0; i<a.n_cols(); i++) {
trace+=a.get(i, i);
}
return trace;
}
/** Solves the classic least square problem y=x*a
* where y is N x 1
* x is N x m
* a is m x 1
* We require that N >= m
* a should not be initialized
*/
inline success_t LeastSquareFit(Vector &y, Matrix &x, Vector *a) {
DEBUG_SAME_SIZE(y.length(), x.n_rows());
DEBUG_ASSERT(x.n_rows() >= x.n_cols());
Vector r_xy_vec;
Matrix r_xx_mat;
la::MulTransAInit(x, x, &r_xx_mat);
la::MulInit(y, x, &r_xy_vec);
success_t status = la::SolveInit(r_xx_mat, r_xy_vec, a);
if unlikely(status != SUCCESS_PASS) {
if (status==SUCCESS_FAIL) {
FATAL("Least square fit failed \n");
} else {
NONFATAL("Least square fit returned a warning \n");
}
}
return status;
}
/** Solves the classic least square problem y=x*a
* where y is N x r
* x is N x m
* a is m x r
* We require that N >= m
* a should not be initialized
*/
inline success_t LeastSquareFit(Matrix &y, Matrix &x, Matrix *a) {
DEBUG_SAME_SIZE(y.n_rows(), x.n_rows());
DEBUG_ASSERT(x.n_rows() >= x.n_cols());
Matrix r_xy_mat;
Matrix r_xx_mat;
la::MulTransAInit(x, x, &r_xx_mat);
la::MulTransAInit(x, y, &r_xy_mat);
success_t status = la::SolveInit(r_xx_mat, r_xy_mat, a);
if unlikely(status != SUCCESS_PASS) {
if (status==SUCCESS_FAIL) {
FATAL("Least square fit failed \n");
} else {
NONFATAL("Least square fit returned a warning \n");
}
}
return status;
}
/** Solves the classic least square problem y=x'*a
* where y is N x r
* x is m x N
* a is m x r
* We require that N >= m
* a should not be initialized
*/
inline success_t LeastSquareFitTrans(Matrix &y, Matrix &x, Matrix *a) {
DEBUG_SAME_SIZE(y.n_rows(), x.n_cols());
DEBUG_ASSERT(x.n_cols() >= x.n_rows());
Matrix r_xy_mat;
Matrix r_xx_mat;
la::MulTransBInit(x, x, &r_xx_mat);
la::MulInit(x, y, &r_xy_mat);
success_t status = la::SolveInit(r_xx_mat, r_xy_mat, a);
if unlikely(status != SUCCESS_PASS) {
if (status==SUCCESS_FAIL) {
FATAL("Least square fit failed \n");
} else {
NONFATAL("Least square fit returned a warning \n");
}
}
return status;
}
};
#endif